Skip to content

Instantly share code, notes, and snippets.

@yoh2
Created December 12, 2013 14:13
Show Gist options
  • Select an option

  • Save yoh2/7928540 to your computer and use it in GitHub Desktop.

Select an option

Save yoh2/7928540 to your computer and use it in GitHub Desktop.
何となく書いてしまったBrainf*ck実装。
#!/usr/bin/perl -w
# usage: bf.pl [source (default: stdin)]
sub run_bf
{
my @prog = @_;
my $ip = 0;
my $dp = 0;
my @data = (0) x 30000;
my %inst = (
'>' => sub { $dp++ },
'<' => sub { $dp-- },
'+' => sub { $data[$dp] = ($data[$dp] + 1) & 0xff },
'-' => sub { $data[$dp] = ($data[$dp] - 1) & 0xff },
'.' => sub { print (chr $data[$dp]) },
# input -- reads 0xff on EOF.
',' => sub { $c = getc; $data[$dp] = $c? ord $c: 0xff },
'[' => sub { $ip = $_[0] unless $data[$dp] },
']' => sub { $ip = $_[0] },
);
while($ip <= $#prog)
{
my ($opcode, $operand) = @{$prog[$ip++]};
&{$inst{$opcode}}($operand);
}
}
sub load_bf
{
my ($file) = @_;
open $fh, "<$file" or die "failed to open '$file'.";
my @prog = ();
my @loop_stack = ();
while(defined (my $c = getc $fh))
{
if($c =~ /[-+<>.,[]/)
{
push @prog, [$c];
if($c eq '[')
{
push @loop_stack, $#prog;
}
}
elsif($c eq ']')
{
my $begin = pop @loop_stack;
push @prog, [$c, $begin];
$prog[$begin]->[1] = $#prog + 1;
}
}
return @prog;
}
# main
&run_bf(&load_bf(@ARGV, '/dev/stdin'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment