Skip to content

Instantly share code, notes, and snippets.

@sstephenson
Created June 11, 2009 16:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sstephenson/128037 to your computer and use it in GitHub Desktop.
Save sstephenson/128037 to your computer and use it in GitHub Desktop.
token Op {'/' || '*' || '+' || '-'};
token Value { \d+[\.\d+]? };
token Item { <Value> || <Op> };
token Expr { [<ws> <Item> <ws>]+ };
sub do_op($lhs, $rhs, $op) {
given $op {
when '*' { $lhs * $rhs }
when '+' { $lhs + $rhs }
when '-' { $lhs - $rhs }
when '/' { $lhs / $rhs }
}
}
# Read from the command line.
my $str = @*ARGS[0];
if $str ~~ /^ <Expr> $/ {
my @stack;
for $/<Expr><Item> -> $item {
if $item<Value> {
@stack.push($item<Value>);
} else {
my $v1 = @stack.pop;
my $v0 = @stack.pop;
@stack.push(do_op($v0,$v1,$item<Op>));
}
}
say @stack[0];
} else {
say "This is not an RPN expression.";
}
# from http://daniel.carrera.bz/2009/06/rpn-calculator-in-perl-6/
Op = /[\/*+-]/
Value = /\d+[\.\d+]?/
Item = /#{Value}|#{Op}/
Expr = /(\s*#{Item}\s*)+/
def do_op(lhs, rhs, op)
case op
when "*" then lhs * rhs
when "+" then lhs + rhs
when "-" then lhs - rhs
when "/" then lhs / rhs
end
end
# Read from the command line.
str = ARGV[0]
if str =~ /^#{Expr}$/
stack = []
str.scan(Item) do |item|
if value = item[Value]
stack.push(value)
else
v1 = stack.pop.to_i
v0 = stack.pop.to_i
stack.push(do_op(v0, v1, item[Op]))
end
end
puts stack[0]
else
puts "This is not an RPN expression."
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment