Skip to content

Instantly share code, notes, and snippets.

@FMNSSun
Last active November 4, 2015 15:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FMNSSun/3cc9c08e69a98eb0ae01 to your computer and use it in GitHub Desktop.
Save FMNSSun/3cc9c08e69a98eb0ae01 to your computer and use it in GitHub Desktop.
Beam interpreter in Pyhton
#!/usr/bin/python
import sys
if(len(sys.argv) < 5):
print 'Usage: ./beam.py path <debug> <debugpoints> <memsize>'
print ' debug: on or off'
print ' debugpoints: ;-seperated list of coordinates (e.g. 0,9;0,2)'
print ' (use -1,-1 for none)'
print ' memsize: how many memory cells'
sys.exit(-3)
debug = False
cycles = 0
bps = sys.argv[3].split(';')
bps = map(lambda a: a.split(','),bps)
bps = map(lambda ds: (int(ds[0]),int(ds[1])),bps)
memsize = int(sys.argv[4])
if(sys.argv[2] == 'on'):
debug = True
elif(sys.argv[2] == 'off'):
debug = False
else:
print 'Unknown option: ' + sys.argv[2]
sys.exit(-2)
fpath = sys.argv[1]
fhandle = open(fpath, 'r')
fcontents = fhandle.read()
lines = fcontents.splitlines()
chars = map(list,lines)
x = 0
y = 0
h = len(lines)
xd = 1
yd = 0
beam = 0
store = 0
memory = [0] * memsize
while True:
cycles += 1
if y < 0 or y >= h:
sys.stderr.write("y out of bounds: " + str(x) + "," + str(y) + "\n")
sys.exit(-1)
w = len(lines[y])
if x < 0 or x >= w:
sys.stderr.write("x out of bounds: " + str(x) + "," + str(y) + "\n")
sys.exit(-2)
if((x,y) in bps):
print
print '== DEBUGPOINT =='
print 'Beam := %d, Store := %d' % (beam, store)
print 'Cycles := %d' % (cycles)
print 'C := %s' % (lines[y][x])
print ' ** MEMORY **'
print memory
c = lines[y][x]
if(debug): print '%d,%d: %s ; %d,%d' % (x,y,c,beam,store)
if(c == 'H'):
break
elif(c == '>'):
xd = 1; yd = 0
elif(c == '<'):
xd = -1; yd = 0
elif(c == '^'):
yd = -1; xd = 0
elif(c == 'v'):
yd = 1; xd = 0
elif(c == '+'):
beam += 1
if(beam >= 256): beam = 0
elif(c == '-'):
beam -= 1
if(beam < 0): beam = 255
elif(c == '@'):
sys.stdout.write(chr(beam))
elif(c == ':'):
sys.stdout.write(str(beam))
elif(c == '/'):
if(xd == -1):
yd = 1; xd = 0;
elif(yd == -1):
xd = 1; yd = 0;
elif(xd == 1):
yd = -1; xd = 0;
elif(yd == 1):
xd = -1; yd = 0;
elif(c == '\\'):
if(xd == 1):
yd = 1; xd = 0;
elif(yd == -1):
xd = -1; yd = 0;
elif(yd == 1):
xd = 1; yd = 0;
elif(xd == -1):
yd = -1; xd = 0
elif(c == '!'):
if(beam != 0):
xd *= -1
yd *= -1
elif(c == '?'):
if(beam == 0):
xd *= -1
yd *= -1
elif(c == '|'):
if(yd == 0):
xd *= -1; yd = 0
elif(c == '_'):
if(xd == 0):
yd *= -1; xd = 0
elif(c == 'S'):
store = beam
elif(c == 'L'):
beam = store
beam %= 256
elif(c == 's'):
memory[beam] = store % 256
elif(c == 'g'):
store = memory[beam]
elif(c == 'P'):
memory[store] = beam
elif(c == 'p'):
beam = memory[store]
elif(c == 'u'):
if(beam != store):
yd = -1; xd = 0;
elif(c == 'n'):
if(beam != store):
yd = 1; xd = 0;
elif(c == '`'):
store -= 1
if(store < 0): store = 255
elif(c == '\''):
store += 1
elif(c == ')'):
if(store != 0): xd = -1; yd = 0;
elif(c == '('):
if(store != 0): xd = 1; yd = 0;
elif(c == 'r'):
s = sys.stdin.read(1)
if(len(s) != 0):
beam = ord(s)
else:
beam = 0
x += xd
y += yd
print ""
print ""
print "Took %d cycles." % (cycles)
@MickyTails
Copy link

Hi, with the store decrementer the value is set to 255 if less than 0, but there is no reciprocal rule on the incrementer.

@FMNSSun
Copy link
Author

FMNSSun commented Nov 4, 2015

The store is an arbitrarily large positive integer as by the Beam specification.

@FMNSSun
Copy link
Author

FMNSSun commented Nov 4, 2015

However, line

if(beam < 0): beam = 256

should be beam = 255. I'll fix it.

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment