-
Notifications
You must be signed in to change notification settings - Fork 1
/
bf.pasm
137 lines (117 loc) · 2.05 KB
/
bf.pasm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# $Id$
# A Brainfuck interpreter
# By Leon Brocard <acme@astray.com>
#
# See http://www.catseye.mb.ca/esoteric/bf/
# for more information on this silly language
.loadlib 'io_ops'
get_params '0', P5 # P5 = @ARGV
# Get the brainfuck source file into S0
set S0, P5[1]
if S0, SOURCE
usage:
set S0, P5[0]
print "usage: ./parrot "
print S0
print " file.bf\n"
end
# Read the file into S1
SOURCE:
null I3
ne S0, "-O", no_o
set I3, 1 # optimize switch
set S0, P5[2]
no_o:
open P1, S0, 'r'
defined I0, P1
unless I0, usage
SOURCE_LOOP:
readline S2, P1
concat S1, S2
if S2, SOURCE_LOOP
close P1
length I30, S1
# Initialise
set I0, 0 # Our program counter
new P0, 'ResizableIntegerArray' # Our memory
set I1, 0 # Our pointer
getstdin P30
# The main interpreter loop
INTERP:
substr S0, S1, I0, 1
ne S0, "+", NOTPLUS
set I2, P0[I1]
inc I2
band I2, 0xff
set P0[I1], I2
branch NEXT
NOTPLUS:
ne S0, "-", NOTMINUS
set I2, P0[I1]
dec I2
band I2, 0xff
set P0[I1], I2
branch NEXT
NOTMINUS:
ne S0, ">", NOTGT
inc I1
branch NEXT
NOTGT:
ne S0, "<", NOTLT
dec I1
branch NEXT
NOTLT:
ne S0, "[", NOTOPEN
set I2, P0[I1]
if I2, NEXT
set I2, 0 # "depth"
OPEN_LOOP:
inc I0
substr S2, S1, I0, 1
ne S2, "[", OPEN_NOTOPEN
inc I2
branch OPEN_LOOP
OPEN_NOTOPEN:
ne S2, "]", OPEN_LOOP
eq I2, 0, NEXT
dec I2
branch OPEN_LOOP
NOTOPEN:
ne S0, "]", NOTCLOSE
unless I3, no_opt
set I2, P0[I1]
unless I2, NEXT
no_opt:
set I2, 0 # "height"
CLOSE_LOOP:
dec I0
substr S2, S1, I0, 1
ne S2, "]", CLOSE_NOTCLOSE
inc I2
branch CLOSE_LOOP
CLOSE_NOTCLOSE:
ne S2, "[", CLOSE_LOOP
eq I2, 0, INTERP
dec I2
branch CLOSE_LOOP
NOTCLOSE:
ne S0, ".", NOTDOT
set I2, P0[I1]
chr S31, I2
print S31
branch NEXT
NOTDOT:
ne S0, ",", NEXT
read S31, P30, 1
if S31, no_eof
null I2 # some return -1, some don't change data
branch eof
no_eof:
ord I2, S31
eof:
set P0[I1], I2
branch NEXT
NEXT:
inc I0
lt I0, I30, INTERP
end