Skip to content

Commit 0fb05d7

Browse files
committed
Ported to rpython
translates using pypy but does not yet work correctly
1 parent 3ba1f2d commit 0fb05d7

File tree

8 files changed

+138
-67
lines changed

8 files changed

+138
-67
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
*.pyc
2+
bfpy-c

bf.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from parser import Parser
2-
from compiler import Compiler
1+
from bfparser import Parser
2+
from bfcompiler import Compiler
33
from decompiler import Decompiler
4-
from interpreter import Interpreter
4+
from bfinterpreter import Interpreter
55

66
import sys
77
import os
@@ -13,6 +13,7 @@ def run(code, debug=False):
1313
b = c.compile()
1414

1515
if debug:
16+
print p.ast
1617
print b
1718
d = Decompiler(b)
1819
d.decompile()

compiler.py renamed to bfcompiler.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ def emit(self, acc, bytecode, arg=None):
1010
if isinstance(arg, list):
1111
acc += arg
1212
else:
13-
acc.append(chr(arg))
14-
13+
print "Error got somenthing that is not a list"
14+
# acc.append(chr(arg))
15+
1516
def encode4(self, value):
1617
return [chr(value & 0xFF),
1718
chr((value >> 8) & 0xFF),
1819
chr((value >> 16) & 0xFF),
1920
chr((value >> 24) & 0xFF)]
21+
2022
def compile_Loop(self, bytecode, ast, pos):
2123
self.pc += 5
2224
start = self.pc
@@ -32,21 +34,21 @@ def compile(self):
3234
def _compile(self, ast):
3335
pos = 0
3436
bytecode = []
35-
while(pos < len(ast)):
36-
inst = ast[pos]
37-
if inst == '>':
37+
while(pos < len(ast.children)):
38+
inst = ast.children[pos]
39+
if inst.value == '>':
3840
self.emit(bytecode, bytecodes.BF_INCR_DP)
39-
elif inst == '<':
41+
elif inst.value == '<':
4042
self.emit(bytecode, bytecodes.BF_DCR_DP)
41-
elif inst == '+':
43+
elif inst.value == '+':
4244
self.emit(bytecode, bytecodes.BF_INCR_D)
43-
elif inst == '-':
45+
elif inst.value == '-':
4446
self.emit(bytecode, bytecodes.BF_DCR_D)
45-
elif inst == '.':
47+
elif inst.value == '.':
4648
self.emit(bytecode, bytecodes.BF_ECHO)
47-
elif inst == ',':
49+
elif inst.value == ',':
4850
self.emit(bytecode, bytecodes.BF_READ)
49-
elif isinstance(inst, list):
51+
elif inst.value is None and len(inst.children) > 0:
5052
self.compile_Loop(bytecode, inst, pos)
5153
pos += 1
5254
self.pc += 1
File renamed without changes.

interpreter.py renamed to bfinterpreter.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
class Interpreter(object):
55
def __init__(self, bytecode):
6-
super(Interpreter, self).__init__()
6+
#super(Interpreter, self).__init__()
77
self.bytecode = bytecode
88

99
def decode(self, bytecode):
@@ -20,7 +20,7 @@ def read4(self, code, pc):
2020

2121
def run(self):
2222
pc = 0
23-
memory = {0:0}
23+
memory = [0 for x in xrange(300)]
2424
dp = 0
2525
while(pc < len(self.bytecode)):
2626
inst = self.decode(self.bytecode[pc])
@@ -30,35 +30,31 @@ def run(self):
3030
elif inst == bytecodes.BF_DCR_DP:
3131
dp -= 1
3232
elif inst == bytecodes.BF_INCR_D:
33-
if dp not in memory:
34-
memory[dp] = 0
33+
3534
memory[dp] += 1
3635
elif inst == bytecodes.BF_DCR_D:
37-
if dp not in memory:
38-
memory[dp] = 0
36+
3937
memory[dp] -= 1
4038
elif inst == bytecodes.BF_ECHO:
41-
if dp not in memory:
42-
memory[dp] = 0
39+
4340
if memory[dp] < 256:
4441
print chr(memory[dp])
4542
else:
4643
print memory[dp]
4744
elif inst == bytecodes.BF_READ:
48-
inp = sys.stdin.read(1)
49-
memory[dp] = ord(inp)
45+
# inp = sys.stdin.read(1)
46+
# memory[dp] = ord(inp)
47+
pass
5048
elif inst == bytecodes.BF_JUMP_IF_ZERO:
51-
if dp not in memory:
52-
memory[dp] = 0
49+
5350
if memory[dp] == 0:
5451
arg = self.read4(self.bytecode, 4)
5552
pc = arg
5653
else:
5754
# skip argument
5855
pc += 4
5956
elif inst == bytecodes.BF_JUMP_UNLESS_ZERO:
60-
if dp not in memory:
61-
memory[dp] = 0
57+
6258
if memory[dp] != 0:
6359
arg = self.read4(self.bytecode, pc)
6460
pc = arg

bfparser.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
class AstNode(object):
2+
def __init__(self, value = None):
3+
self.value = value
4+
self.children = []
5+
6+
def __repr__(self):
7+
s = ''
8+
if len(self.children) > 0:
9+
s = repr(self.children)
10+
if self.value is not None:
11+
s = self.value + s
12+
return s
13+
14+
def __eq__(self, other):
15+
return (self.__class__ is other.__class__ and
16+
self.__dict__ == other.__dict__)
17+
18+
def __ne__(self, other):
19+
return not self == other
20+
21+
class Parser(object):
22+
def __init__(self, code):
23+
self.code = code
24+
self.ast = AstNode()
25+
self.nest = 0
26+
27+
def parseLoop(self):
28+
self.nest -= 1
29+
t = []
30+
c = self.ast.children.pop()
31+
while(c.value != '['):
32+
t.insert(0, c)
33+
c = self.ast.children.pop()
34+
self.ast.children = t
35+
36+
def parse(self):
37+
self.pos = 0
38+
self._parse(self.ast)
39+
def _parse(self, node):
40+
while(self.pos < len(self.code)):
41+
inst = self.code[self.pos]
42+
if inst == '>':
43+
node.children.append(AstNode('>'))
44+
elif inst == '<':
45+
node.children.append(AstNode('<'))
46+
elif inst == '+':
47+
node.children.append(AstNode('+'))
48+
elif inst == '-':
49+
node.children.append(AstNode('-'))
50+
elif inst == '.':
51+
node.children.append(AstNode('.'))
52+
elif inst == ',':
53+
node.children.append(AstNode(','))
54+
elif inst == '[':
55+
self.pos += 1
56+
n = AstNode()
57+
self._parse(n)
58+
node.children.append(n)
59+
elif inst == ']':
60+
self.pos += 1
61+
return
62+
self.pos += 1
63+
64+
assert self.nest == 0, self.nest

bfpy.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import os
2+
from pypy.rlib.streamio import open_file_as_stream
3+
4+
from bfparser import Parser
5+
from bfcompiler import Compiler
6+
from bfinterpreter import Interpreter
7+
from bfdecompiler import Decompiler
8+
9+
def run(code, debug=False):
10+
p = Parser(code)
11+
p.parse()
12+
c = Compiler(p.ast)
13+
b = c.compile()
14+
15+
if debug:
16+
print p.ast
17+
print b
18+
d = Decompiler(b)
19+
d.decompile()
20+
21+
i = Interpreter(b)
22+
i.run()
23+
print
24+
25+
def entry_point(args):
26+
if len(args) == 1:
27+
print "Missing input"
28+
return 1
29+
else:
30+
inp = args[1]
31+
if os.path.exists(inp):
32+
f = open_file_as_stream(args[1])
33+
code = f.readall()
34+
f.close()
35+
else:
36+
code = inp
37+
if len(args) >= 3 and args[2] == "-debug":
38+
debug = True
39+
else:
40+
debug = False
41+
42+
run(code, debug)
43+
return 0
44+
45+
def target(driver, args):
46+
return entry_point, None

parser.py

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)