Skip to content

Instantly share code, notes, and snippets.

@uasi
Created November 26, 2010 18:13
Show Gist options
  • Save uasi/717036 to your computer and use it in GitHub Desktop.
Save uasi/717036 to your computer and use it in GitHub Desktop.
use v6;
class Brainfuck {
has $!buf;
has $!ptr;
submethod BUILD(:$buf-size = 1024) {
$!buf = Buf.new(0 xx $buf-size);
$!ptr = 0;
}
multi method unfuck($self where :!defined: $code) {
self.new.unfuck($code);
}
multi method unfuck($code) {
my @chars = $code.comb(/ <[ + . , < > ]> | '-' | '[' | ']' /);
my $at = 0;
while @chars[$at] -> $char {
given $char {
when '>' { $!ptr++ }
when '<' { $!ptr-- }
when '+' { self!incl($!buf[$!ptr]) }
when '-' { self!decl($!buf[$!ptr]) }
when '.' { print $!buf[$!ptr].chr }
when ',' { $!buf[$!ptr] = $*STDIN.getc }
when '[' { $at = self!find-closing-bracket(@chars, $at) - 1 if $!buf[$!ptr] == 0 }
when ']' { $at = self!find-opening-bracket(@chars, $at) - 1 if $!buf[$!ptr] != 0 }
default { die "Unknown instruction '$_'" }
}
$at++;
}
}
method !incl($byte is rw) {
$byte = $byte < 255 ?? $byte + 1 !! 0;
}
method !decl($byte is rw) {
$byte = $byte > 0 ?? $byte - 1 !! 255;
}
method !find-closing-bracket(@chars, $pos is copy) {
my $unmatch = 1;
while $unmatch {
my $char = @chars[++$pos];
given $char {
when '[' { $unmatch++ }
when ']' { $unmatch-- }
when :!defined { die 'Matching closing bracket not found' }
}
}
$pos;
}
method !find-opening-bracket(@chars, $pos is copy) {
my $unmatch = 1;
while $unmatch {
my $char = @chars[--$pos];
given $char {
when '[' { $unmatch-- }
when ']' { $unmatch++ }
when :!defined { die 'Matching opening bracket not found' }
}
}
$pos;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment