amahabal's Journal
http://use.perl.org/~amahabal/journal/
amahabal's use Perl Journal
en-us
use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners.
2012-02-08T23:32:46+00:00
pudge
pudge@perl.org
Technology
hourly
1
1970-01-01T00:00+00:00
amahabal's Journal
http://use.perl.org/images/topics/useperl.gif
http://use.perl.org/~amahabal/journal/
-
RPN Take 4
http://use.perl.org/~amahabal/journal/38583?from=rss
<a href="http://blog.afoolishmanifesto.com/archives/341"> fREW++ </a> and <a href="http://use.perl.org/~pmichaud/journal/38580"> pmichaud++ </a> have, between them, three versions of the RPN calculator. Here is a fourth, clener in some ways.
You can use it as follows:<blockquote><div><p> <tt>> <nobr> <wbr></nobr>./perl6 rpn.pl '4 5 9 sqrt + *'<br>32<br>><nobr> <wbr></nobr>./perl6 rpn.pl '4 5 9 sqrt rotate3 + *'<br>35</tt></p></div> </blockquote><p>And here is the code:</p><blockquote><div><p> <tt>my %op_dispatch_table = {<br> '+' => { $^a + $^b },<br> '-' => { $^a - $^b },<br> '*' => { $^a * $^b },<br> '/' => { $^a / $^b },<br> 'sqrt' => { $^a.sqrt },<br> 'say' => { $^a.say; $^a},<br> 'rotate3' => { ($^b, $^c, $^a) },<br> };<br> <br>sub evaluate (%odt, $expr) {<br> my @stack;<br> my @tokens = $expr.split(/\s+/);<br> for @tokens {<br> when<nobr> <wbr></nobr>/^\d+$/ { @stack.push($_); }<br> when ?%odt{$_} { my $f = %odt{$_};<br> my @top_terms = gather {<br> for 1..$f.arity { take @stack.pop}<br> };<br> @top_terms = reverse(@top_terms);<br> my @to_push = $f.(|@top_terms);<br> @stack.push(@to_push);<br> }<br> default { die "Unrecognized token '$_'; aborting"; }<br> }<br> @stack.pop;<br>}<br> <br>say "Result: { evaluate(%op_dispatch_table, @*ARGS[0]) }";</tt></p></div> </blockquote><p>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.</p>
amahabal
2009-03-03T18:52:07+00:00
journal