User:Marinus/REVERSE interpreter

REVERSE interpreter. Straight from the backup.


 * 1) !/usr/bin/perl


 * 1) REVERSE interpreter, by Marinus Oosters


 * 1) This implements the REVERSE programming language, as described at
 * 2) http://www.geocities.com/brianscsmith/reverse.html

$#ARGV and die("reverse.pl: usage: reverse.pl program.\n");

@program = ; %vvars = ; %wvars = ; %xvars = ;

$ptr = 0; $x = 1;

open(pgm,$ARGV[0]) or die("reverse.pl: error: can't open ".$ARGV[0].".\n"); @lines = ;

$pstr = join(' ',@lines); $pstr =~ s/(\+|-|\/|\^|%|\*|=)-/\1_/; @ptemp = split(' ',$pstr);

foreach (@ptemp) { $_ ne '' and @program = (@program,$_); }

while($ptr>-1 and$ptr<=$#program) { $cmd = $program[$ptr]; # check for commands without a left variable if ($cmd=~/^reverse$/i) {if($x==1){$x=-1;}else{$x=1;}} elsif ($cmd=~/^reverse/i) { $val = 0; for (substr($cmd,7,1)) { /\>/ && do { for (substr($cmd,8,1)) { /v/i && do { $val = ($vvars{substr($cmd,9)}<0); last;}; /w/i && do { $val = ($wvars{substr($cmd,9)}<0); last;}; /x/i && do { $val = ($xvars{substr($cmd,9)}<0); last;}; die("$cmd : variable expected.\n"); }				last; };			/\0); last;}; /w/i && do { $val = ($wvars{substr($cmd,9)}>0); last;}; /x/i && do { $val = ($xvars{substr($cmd,9)}>0); last;}; die("$cmd : variable expected.\n"); }				last; };			/\=/ && do { for (substr($cmd,8,1)) { /v/i && do { $val = ($vvars{substr($cmd,9)}==0); last;}; /w/i && do { $val = ($wvars{substr($cmd,9)}==0); last;}; /x/i && do { $val = ($xvars{substr($cmd,9)}==0); last;}; die("$cmd : variable expected.\n"); }				last; };			/\!/ && do { for (substr($cmd,8,1)) { /\>/ && do { for (substr($cmd,9,1)) { /v/i && do {$val=!($vvars{substr($cmd,10 )}<0);last;}; /w/i && do {$val=!($wvars{substr($cmd,10 )}<0);last;}; /x/i && do {$val=!($xvars{substr($cmd,10 )}<0);last;}; die("$cmd : variable expected.\n"); }						last; };					/\0);last;}; /w/i && do {$val=!($wvars{substr($cmd,10 )}>0);last;}; /x/i && do {$val=!($xvars{substr($cmd,10 )}>0);last;}; die("$cmd : variable expected.\n"); }						last; };					/\=/ && do { for (substr($cmd,9,1)) { /v/i && do {$val=!($vvars{substr($cmd,10 )}==0);last;}; /w/i && do {$val=!($wvars{substr($cmd,10 )}==0);last;}; /x/i && do {$val=!($xvars{substr($cmd,10 )}==0);last;}; die ("$cmd : variable expected.\n"); }						last; };					die ("$cmd : <, >, or = expected after !.\n"); }				last; };			die("$cmd : nothing, <, >, = or ! expected after REVERSE.\n"); }		if($val){if($x==1){$x=-1;}else{$x=1;}} }		elsif (substr($cmd,0,3)=~/get/i) { for (substr($cmd,3,1)) { /v/i && do { $c = ; chomp($c); $vvars{substr($cmd,4)} = int($c); last; };			/w/i && do { $c = ; $wvars{substr($cmd,4)} = $c; last; }; /x/i && do {$xvars{substr($cmd,4)} = ord(getc) % 128; last; }; die ("$cmd : variable expected.\n"); }	} elsif (substr($cmd,0,3)=~/put/i) { for (substr($cmd,3,1)) { /v/i && do { print ' '.$vvars{substr($cmd,4)}; last; }; /w/i && do { print ' '.$wvars{substr($cmd,4)}; last; }; /x/i && do { print chr($xvars{substr($cmd,4)}); last; }; print substr($cmd,4);last; }	} elsif ($cmd=~/^skip$/i) { $ptr += $x; }	# modifiers else { @values = split(/[\+|\-|\*|\/|\^|\%|\=]/, $cmd); @ops = ; foreach (split("",$cmd)) { if (/[\+|\-|\*|\/|\^|\%|\=]/) { @ops = (@ops, $_); }		}

($#values - $#ops == 1) or die("$cmd : syntax error\n");

# all but the last value will be modified, so except for the last one, # all of them must be variables.

for ($c=0;$c<$#values;$c++) { (substr($values[$c],0,1)=~/[v|w|x]/i) or die("$cmd : variable expected.\n"); }		# execute the commands

for ($c=$#ops;$c>=0;$c--) {

# first get the value that won't change my $val=0; for (substr($values[$c+1],0,1)) { /v/i && do {$val = $vvars{substr($values[$c+1],1)}; last;}; /w/i && do {$val = $wvars{substr($values[$c+1],1)}; last;}; /x/i && do {$val = $xvars{substr($values[$c+1],1)}; last;}; /[0-9]/ && do {$val = $values[$c+1];last;}; /\_/ && do {$val = -(substr($values[$c+1],1));last;}; die("$cmd : syntax error\n"); }				# execute

for (substr($values[$c],0,1)) { /v/i && do { for ($ops[$c]) { /\+/ && do {$vvars{substr($values[$c],1)}+=$val;last;}; /\-/ && do {$vvars{substr($values[$c],1)}-=$val;last;}; /\*/ && do {$vvars{substr($values[$c],1)}*=$val;last;}; /\// && do {$vvars{substr($values[$c],1)}/=$val;last;}; /\^/ && do {$vvars{substr($values[$c],1)}**=$val;last;}; /\%/ && do {$vvars{substr($values[$c],1)}%=$val;last;}; /\=/ && do {$vvars{substr($values[$c],1)}=$val;last;}; last; }					$vvars{substr($values[$c],1)}=int($vvars{substr($values[$c],1)}); last; };				/w/i && do { for ($ops[$c]) { /\+/ && do {$wvars{substr($values[$c],1)}+=$val;last;}; /\-/ && do {$wvars{substr($values[$c],1)}-=$val;last;}; /\*/ && do {$wvars{substr($values[$c],1)}*=$val;last;}; /\// && do {$wvars{substr($values[$c],1)}/=$val;last;}; /\^/ && do {$wvars{substr($values[$c],1)}**=$val;last;}; /\%/ && do {$wvars{substr($values[$c],1)}%=$val;last;}; /\=/ && do {$wvars{substr($values[$c],1)}=$val;last;}; last; }					last; };				/x/i && do { for ($ops[$c]) { /\+/ && do {$xvars{substr($values[$c],1)}+=$val;last;}; /\-/ && do {$xvars{substr($values[$c],1)}-=$val;last;}; /\*/ && do {$xvars{substr($values[$c],1)}*=$val;last;}; /\// && do {$xvars{substr($values[$c],1)}/=$val;last;}; /\^/ && do {$xvars{substr($values[$c],1)}**=$val;last;}; /\%/ && do {$xvars{substr($values[$c],1)}%=$val;last;}; /\=/ && do {$xvars{substr($values[$c],1)}=$val;last;}; last; }					$xvars{substr($values[$c],1)}=int($xvars{substr($values[$c],1)}); $xvars{substr($values[$c],1)} %= 128; last; };				last; }		}	}	$ptr += $x; }