Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

amahabal (8575)

amahabal
  (email not shown publicly)

Journal of amahabal (8575)

Tuesday March 03, 2009
01:52 PM

RPN Take 4

fREW++ and pmichaud++ have, between them, three versions of the RPN calculator. Here is a fourth, clener in some ways. You can use it as follows:

./perl6 rpn.pl '4 5 9 sqrt + *'
32
> ./perl6 rpn.pl '4 5 9 sqrt rotate3 + *'
35

And here is the code:

my %op_dispatch_table = {
        '+'    => { $^a + $^b },
        '-'    => { $^a - $^b },
        '*'    => { $^a * $^b },
        '/'    => { $^a / $^b },
        'sqrt' => { $^a.sqrt },
        'say'  => { $^a.say; $^a},
        'rotate3' => { ($^b, $^c, $^a) },
    };

sub evaluate (%odt, $expr) {
  my @stack;
  my @tokens = $expr.split(/\s+/);
  for @tokens {
      when /^\d+$/     { @stack.push($_); }
      when ?%odt{$_} { my $f = %odt{$_};
                       my @top_terms = gather {
                         for 1..$f.arity { take @stack.pop}
                       };
                       @top_terms = reverse(@top_terms);
                       my @to_push = $f.(|@top_terms);
                       @stack.push(@to_push);
                     }
      default        { die "Unrecognized token '$_'; aborting"; }
   }
   @stack.pop;
}

say "Result: { evaluate(%op_dispatch_table, @*ARGS[0]) }";

I'd like to do even better: when an operator is unrecognized (say "double"), but there is a subroutine of that name in scope we should use that. I will try that next.