# 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 <program.g>" 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;
}
}