View difference between Paste ID: inEYgyN9 and vCWL5YD9
SHOW: | | - or go back to the newest paste.
1
#!/usr/bin/perl -w
2-
#brainfuck.pl
2+
3
4
A brainfuck interpreter.
5
6
    USAGE:
7-
	USAGE:
7+
8
Non-Interactive: Run script with brainfuck program file as command line option.
9
10
Input buffer:
11
  Uses an input buffer so that you can enter an entire line of text at a time
12-
	Uses an input buffer so that you can enter an entire line of text at a time
12+
13
NOTE: Since you use "enter" to submit a line, there's no way to enter newlines.
14
15
Use valid code:
16
  This doesn't check the brainfuck code for validity. It assumes all open
17-
	This doesn't check the brainfuck code for validity. It assumes all open
17+
18
19
Comment removal:
20
  In the preparation phase, it removes all non-bf characters from the code, so
21-
	In the preparation phase, it removes all non-bf characters from the code,
21+
extra formatting and comments have no impact on speed.
22-
so extra formatting and comments have no impact on speed.
22+
NOTE: Valid bf characters are only the canonical eight: +-<>[],.
23-
	NOTE: Valid bf characters are only the canonical eight: +-<>[],.
23+
24
25
Language implementation details:
26
  Cell values are 0 to 255 with wrapping.
27-
	Cell values are 0 to 255 with wrapping.
27+
  It uses 30000 memory cells with wrapping, as in the original implementation.
28-
	It uses 30000 memory cells with wrapping, as in the original implementation.
28+
29
=end comment
30-
=cut comment
30+
=cut
31
use strict;
32
33
# Number of memory cells
34
my $MEMSIZE = 30_000;
35
36
# Read in program, remove comments, turn into array of characters
37
print STDERR "Enter brainfuck code, then an EOF character to signal the end.\n"
38-
print "Enter brainfuck code, then an EOF character to signal the end.\n" .
38+
  . "Usually this is Ctrl+D.\n";
39-
	"Usually this is Ctrl+D.\n";
39+
40
while (<>) {
41
  s/[^+\-<>.,\[\]]//g;
42-
	s/[^+\-<>.,\[\]]//g;
42+
  my @line = split('', $_);
43-
	my @line = split('', $_);
43+
  push(@program, @line);
44-
	push(@program, @line);
44+
45
print STDERR "\n=====Program Output=====\n";
46-
print "\n=====Program Output=====\n";
46+
47
# MAIN PARSING AND EXECUTION LOOP
48
49
my $ptr = 0;
50
my @mem = ();
51
my @bufferin = ();
52
for (my $counter = 0; $counter < @program; $counter++) {
53
  
54-
	
54+
  if ($program[$counter] eq '+') {
55-
	if ($program[$counter] eq '+') {
55+
    $mem[$ptr] = ++$mem[$ptr] % 256;
56-
		$mem[$ptr] = ++$mem[$ptr] % 256;
56+
    
57-
		
57+
  } elsif ($program[$counter] eq '-') {
58-
	} elsif ($program[$counter] eq '-') {
58+
    $mem[$ptr] = --$mem[$ptr] % 256;
59-
		$mem[$ptr] = --$mem[$ptr] % 256;
59+
    
60-
		
60+
  } elsif ($program[$counter] eq '>') {
61-
	} elsif ($program[$counter] eq '>') {
61+
    $ptr = ++$ptr % $MEMSIZE;
62-
		$ptr = ++$ptr % $MEMSIZE;
62+
    
63-
		
63+
  } elsif ($program[$counter] eq '<') {
64-
	} elsif ($program[$counter] eq '<') {
64+
    $ptr = --$ptr % $MEMSIZE;
65-
		$ptr = --$ptr % $MEMSIZE;
65+
    
66-
		
66+
  } elsif ($program[$counter] eq '.') {
67-
	} elsif ($program[$counter] eq '.') {
67+
    if ($mem[$ptr]) {
68-
		if ($mem[$ptr]) {
68+
      print chr($mem[$ptr]);
69-
			print chr($mem[$ptr]);
69+
    }
70-
		}
70+
    
71-
		
71+
  } elsif ($program[$counter] eq ',') {
72-
	} elsif ($program[$counter] eq ',') {
72+
    unless(@bufferin) {          # fill input buffer
73-
		unless(@bufferin) {					# fill input buffer
73+
      print "\n";
74-
			print "\n";
74+
      chomp(my $in = <STDIN>);
75-
			chomp(my $in = <STDIN>);
75+
      push(@bufferin, split('', $in));
76-
			push(@bufferin, split('', $in));
76+
    }
77-
		}
77+
    $mem[$ptr] = ord(shift @bufferin);
78-
		$mem[$ptr] = ord(shift @bufferin);
78+
    
79-
		
79+
  } elsif ($program[$counter] eq '[') {
80-
	} elsif ($program[$counter] eq '[') {
80+
    unless ($mem[$ptr]) {
81-
		unless ($mem[$ptr]) {
81+
      my $nested = 1;
82-
			my $nested = 1;
82+
      until ($nested < 1) {
83-
			until ($nested < 1) {
83+
        $counter++;
84-
				$counter++;
84+
        if ($program[$counter] eq '[') {
85-
				if ($program[$counter] eq '[') {
85+
          $nested++;
86-
					$nested++;
86+
        } elsif ($program[$counter] eq ']') {
87-
				} elsif ($program[$counter] eq ']') {
87+
          $nested--;
88-
					$nested--;
88+
        }
89-
				}
89+
      }
90-
			}
90+
    }
91-
		}
91+
    
92-
		
92+
  } elsif ($program[$counter] eq ']') {
93-
	} elsif ($program[$counter] eq ']') {
93+
    if ($mem[$ptr]) {
94-
		if ($mem[$ptr]) {
94+
      my $nested = 1;
95-
			my $nested = 1;
95+
      until ($nested < 1) {
96-
			until ($nested < 1) {
96+
        $counter--;
97-
				$counter--;
97+
        if ($program[$counter] eq ']') {
98-
				if ($program[$counter] eq ']') {
98+
          $nested++;
99-
					$nested++;
99+
        } elsif ($program[$counter] eq '[') {
100-
				} elsif ($program[$counter] eq '[') {
100+
          $nested--;
101-
					$nested--;
101+
        }
102-
				}
102+
      }
103-
			}
103+
    }
104-
		}
104+
  }
105-
		
105+