Subject: | loops with line breaks in them don't function correctly |
When a loop has a line break in between the open [ and the close ], then
the code filter doesn't represent this properly in the generated perl
code.
Attached is a patch that detects whether there is a loop open at the
start and end of a chunk of code and doesn't put in the "do {" and "P;
}" chunks respectively.
You can test this with the attached program loop.pl. Before the
patch will generate code such as below, and run endlessly. After the
patch will generate the 2nd chunk of code below, and exit promptly as
expected.
Without patch:
do { $Acme::Brainfuck::m[$Acme::Brainfuck::p] +=
1;while($Acme::Brainfuck::m[$Acme::Brainfuck::p])
{$Acme::Brainfuck::m[$Acme::Brainfuck::p]; };
do { $Acme::Brainfuck::m[$Acme::Brainfuck::p] -= 1;};
$Acme::Brainfuck::m[$Acme::Brainfuck::p]; };
After patch:
do { $Acme::Brainfuck::m[$Acme::Brainfuck::p] +=
1;while($Acme::Brainfuck::m[$Acme::Brainfuck::p]){
$Acme::Brainfuck::m[$Acme::Brainfuck::p] -= 1;};
$Acme::Brainfuck::m[$Acme::Brainfuck::p]; };
Cheers,
Hugh
Subject: | loopcount.patch |
--- /usr/share/perl5/Acme/Brainfuck.pm 2012-12-09 14:51:08.266221294 +1300
+++ /usr/local/share/perl/5.10.1/Acme/Brainfuck.pm 2012-12-09 14:55:50.733812703 +1300
@@ -100,14 +100,20 @@
FILTER_ONLY code => sub
{
my $ret = $_;
+ my $loopcount = 0;
while ($ret =~ /\s ([\Q$ops\E]+) \s/gsx)
{
my $code = $1;
my $len = length($1);
my $at = pos($ret) - ($len + 1);
- $code =~ s/^/do { /g;
- $code =~ s/$/P; }; /g;
+ if ($loopcount == 0) {
+ $code =~ s/^/do { /g;
+ }
+ $loopcount = $loopcount + ($code =~ tr/\[//) - ($code =~ tr/\]//);
+ if ($loopcount == 0) {
+ $code =~ s/$/P; }; /g;
+ }
$code =~ s/(\++)/"P += ".length($1).";" /eg;
$code =~ s/(\-+)/"P -= ".length($1).";" /eg;
$code =~ s/(<+)/"\$Acme::Brainfuck::p -= ".length($1).";" /eg;
Subject: | loop.pl |
use Acme::Brainfuck qw/debug/;
+[
-]