152
« on: June 16, 2008, 02:34:55 AM »
This is my first-ever Perl program. I even forewent the "HELLO WHIRLED" nonsense and skipped right onto the good stuff.
I wrote this while my laptop was churning through Lunicks updates:
#!/usr/bin/perl
# I'm loves my switch()
use Switch;
# variabledeclarationsectionstuff
my $prog; # program storage thingie
my $ip = -1; # instruction pointer
my $ramptr = 0; # memory pointer
my $ram; # the actual memory storage
my $maxram = 9999; # 10k oughta be enough for anyone...
my $maxint = (2**8)-1; # set the highest number per memory position (normally (2^8)-2 -- 8-bit precision)
my $loopip; # where do each of the loops start
my $loopptr = -1; # how deeply nested are we?
my $nestlvl = 0; # used to traverse loops for '['
my $proglen; # holds program length
# open file
open my $bffile, $ARGV[0] or die "Could not open $ARGV[0]: $!";
# read file to memory
$prog .= <$bffile> until eof($bffile);
$proglen = length($prog);
# initialize the memory
$ram[$ramptr] = 0 until ($ramptr++ == $max_ram);
# close file
close $prog;
# start interpremacating
while($ip++ < $proglen) {
switch(substr($prog,$ip,1)) {
case '+' { if(++$ram[$ramptr] > $maxint) { $ram[$ramptr] = 0; } }
case '-' { if(--$ram[$ramptr] < 0) { $ram[$ramptr] = $maxint; } }
case '>' { if(++$ramptr > $maxram) { $ramptr = 0; } }
case '<' { if(--$ramptr < 0) { $ramptr = $maxram; } }
case '.' { if($ram[$ramptr] == 10) { print "\n" } else { print sprintf("%c",$ram[$ramptr]); } } #make sure this gets printed as a character
case ',' { print "Input not yet implemented!\n"; }
case '[' { unless($ram[$ramptr] == 0) { $loopip[++$loopptr] = $ip; }
else { $nestlvl++; until($nestlvl == 0) {
switch(substr($prog,++$ip,1)) {
case '[' { $nestlvl++; }
case ']' { $nestlvl--; } } } } }
case ']' { unless($ram[$ramptr] == 0) { $ip = $loopip[$loopptr]; } else { $loopptr--; } }
}
}
# be nice and print a trailing newline
print "\n";
I looked around for approximately three minutes and didn't find any good way of pulling input from the console without requiring the user to hit enter, so I just left it out. Most brainfuck programs are just people showing off anyway, so it probably doesn't matter all that much.
It's very quick and dirty. Like I said, first Perl program and done while my system installed updates (WRITTEN COMPLETELY IN A CLI ENVIRONMENT USING nano GASP OH NO). It's exceedingly slow -- the three quines that I threw at it took between five and ten seconds to run on my laptop (Pentium M 1.73GHz) while my C# interpreter dealt with them very quickly. My best guess would be that my method for pulling characters out of strings is highly inefficient (probably not helped by the fact that you don't declare variable types in Perl), but I was on a time budget with this so I kept research to a minimum and just stuck with methods that I was familiar with.
I have to say, I LOVE the post-statement evaluations that Perl has, not to mention the fun "OR DIE" clause.
I also find it amusing that the meat of the interpreter is small enough to fit inside of the "new message" textbox. Yay, brainfuck!