Advertisement
glezmen

Brainfuck compiler by glezmen

Jul 25th, 2012
358
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 2.00 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. #   Brainfuck compiler by Norbert Bokor (glezmen@gmail.com)
  3.  
  4. use strict;
  5. use bigint;
  6. use Term::ReadKey;
  7.  
  8. die "Unknown parameter!\n" if ($#ARGV == 1 && $ARGV[1] ne "dbg");
  9. die "Usage: bfcompile.pl  <brainfuck code> [dbg]\n" if ($#ARGV < 0 || $#ARGV > 1);
  10.  
  11. my $SIZE = 30_000;
  12. my $INFLIMIT = 1e5;
  13. my $debug = 1 if ($#ARGV > 0);
  14. my @mem   = map {0} (1 .. $SIZE);
  15. my $jto   = my $cmds = my $ptr = my $stack = my $top = my $write = my $inf = 0;
  16. my $code = $ARGV[0];
  17. $code = join('',<F>) if (open F, "<$ARGV[0]");
  18.  
  19. sub check($)
  20. {
  21.     foreach (split('',shift))
  22.     {
  23.         ++$stack if (/\[/);
  24.         --$stack if (/\]/);
  25.         last if ($stack < 0);
  26.     }
  27.     die "ERROR: unmatched bracket!" if ($stack != 0);
  28. }
  29.  
  30. sub run($)
  31. {
  32.     open my $tty , '<', '/dev/tty';
  33.     my @s = split('',shift);
  34.     for ( my $i = 0; $i <= $#s ;)
  35.     {
  36.         $top = $ptr if ($ptr > $top);
  37.         $_ = $s[$i];
  38.         if ($stack > 0)
  39.         {
  40.             ++$stack if (/\[/);
  41.             --$stack if (/\]/);
  42.             if ($stack >= 0)
  43.             {
  44.                 ++$i;
  45.                 next;
  46.             }
  47.         }
  48.         elsif ($stack < 0)
  49.         {
  50.             ++$stack if (/\[/);
  51.             --$stack if (/\]/);
  52.             if ($stack < 0)
  53.             {
  54.                 --$i;
  55.                 next;
  56.             }
  57.             else
  58.             {
  59.                 die "ERROR: infinite loop? :S $inf loops jumping to pos $i" if ($i == $jto && $write == 0 && ++$inf > $INFLIMIT);
  60.                 $jto = $i;
  61.                 $write = 0;
  62.             }
  63.         }
  64.         print "\nPTR: $ptr\tVAL: $mem[$ptr]\tTOP: $top\tPOS: $i\tTOTAL: $#s\tCMD: $_\tcommands: $cmds\n" if (defined $debug);
  65.         ++$cmds if (/[-+,.<>\[\]]/);
  66.         die "ERROR: pointer overrun!" if (/>/ && ++$ptr >= $SIZE);
  67.         die "ERROR: pointer underrun!" if (/</ && --$ptr < 0);
  68.         ReadMode "raw";
  69.         $mem[$ptr] = ++$mem[$ptr] % 256 if (/\+/);
  70.         $mem[$ptr] = ($mem[$ptr] + 255) % 256 if (/-/);
  71.         print chr $mem[$ptr] if (/\./);
  72.         $mem[$ptr] = ord(ReadKey(0, $tty)) if (/,/);
  73.         ReadMode "normal";
  74.         ++$write if (/[-+,<>]/);
  75.         $stack = 1 if ($mem[$ptr] == 0 && /\[/);
  76.         if (/\]/)
  77.         {
  78.             $stack = -1;
  79.             --$i;
  80.         }
  81.         else
  82.         {
  83.             ++$i;
  84.         }
  85.     }
  86.     print "\ncommands executed: $cmds\n";
  87. }
  88.  
  89. check($code);
  90. run($code);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement