Re: [SPOILER] Solution for QotW #25 (RPN calculator)
Michael Carman <[email protected]> Fri, 01 Oct 2004 15:09:55 -0500
| Newsgroups | gmane.comp.lang.perl.qotw.discuss |
|---|---|
| Message-ID | <[email protected]> |
On 10/1/2004 11:12 AM, [email protected] wrote: > > I thought about using eval STRING, but decided against it. Instead, my > solution is based around a dispatch table [...] > > sub do_token { > my $t = shift; > > if (exists $op{$t}) { > my $n = $op{$t}{n}; > > unless (@stack >= $n) { > print "ERROR: Not enough elements for operation.\n"; > return; > } > > my @arg = $n ? splice(@stack, -$n) : (); > my $rv = $op{$t}{f}->(@arg); > > push @stack, $rv if defined $rv; > } > else { > push @stack, ($t =~ /^0\w/) ? oct($t) : $t; > } > } Upon further consideration, I do want an eval: eval BLOCK. Otherwise, a user entering something like "1 0 /" would kill the program. The following replacement for do_token() catches fatal errors, prints the error message, and restores the stack. sub do_token { my $t = shift; if (exists $op{$t}) { my $n = $op{$t}{n}; unless (@stack >= $n) { print "ERROR: Not enough elements for operation.\n"; return; } my @arg = $n ? splice(@stack, -$n) : (); my $rv = eval { $op{$t}{f}->(@arg) }; if ($@) { (my $err = $@) =~ s/ at .*//; print "ERROR: $err\n"; push @stack, @arg; } push @stack, $rv if defined $rv; } else { push @stack, ($t =~ /^0\w/) ? oct($t) : $t; } }