# g_interpreter.pl # # Example input: 10 5 / 8 + . # explanation: divide 10 by 5, add 8, then print the result # output: 10 # # g_interpreter v0.1 # Interpreter for the G language # Actually just a really simple RPN calculator # Copyright (C) 2009 G-Brain # http://www.g-brain.net # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA02110-1301, USA. $file = $ARGV[0]; die "Usage: perl g_interpreter.pl " if ($file eq ""); open PROGRAM, $file or die "Could not open file: $file"; my ($token, $buf); my @stack = (); while ((read PROGRAM, $buf, 1) != 0) { if (g_is_whitespace($buf)) { g_eval($token); $token = ""; } else { $token .= $buf; } } sub g_is_whitespace($) { $c = shift; return ($c eq ' ' || ord($c) == 10) } sub g_is_print($) { return shift eq '.'; } sub g_is_function($) { $f = shift; return grep $_ eq $f, ('+','-','*','/') } sub g_eval($) { $token = shift; if (g_is_print($token)) { print pop(@stack)."\n"; } elsif (g_is_function($token)) { ($two,$one) = (pop(@stack), pop(@stack)); if ($token eq '+') { $new = $one+$two } elsif ($token eq '-') { $new = $one-$two } elsif ($token eq '*') { $new = $one*$two } elsif ($token eq '/') { $new = $one/$two } push @stack, $new; } else { push @stack, $token; } }