Skip to content

Instantly share code, notes, and snippets.

@orlp
Last active August 29, 2015 14:18
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 orlp/91e0654f5366e1918844 to your computer and use it in GitHub Desktop.
Save orlp/91e0654f5366e1918844 to your computer and use it in GitHub Desktop.
import sys
if len(sys.argv) < 3:
print("Usage: {} [-d] <file> <n>".format(sys.argv[0]))
sys.exit()
debug = False
if sys.argv[1] == "-d":
sys.argv.pop(1)
debug = True
source_lines = []
tags = {}
# Preprocessing.
orig_lines = [line.strip() for line in open(sys.argv[1])]
for linenr, line in enumerate(orig_lines):
if "#" in line:
line = line[:line.index("#")]
if ":" in line:
tag, line = line.split(":")
tags[tag.strip()] = len(source_lines)
line = line.strip()
if line: source_lines.append((linenr + 1, line))
# Compile to VM bytecode
INCX = 0
INCY = 1
HALT = 2
PRINTX = 3
JMP = 4
DJZX = 5
DJZY = 6
bytecode = []
debug_lines = {}
for linenr, line in source_lines:
debug_lines[len(bytecode)] = orig_lines[linenr - 1]
args = line.split()
if line == "INCX": bytecode.append(INCX)
elif line == "INCY": bytecode.append(INCY)
elif line == "HALT": bytecode.append(HALT)
elif line == "PRINTX": bytecode.append(PRINTX)
elif len(args) == 2 and args[0] in {"JMP", "DJZX", "DJZY"}:
if args[1] not in tags:
print("Unknown jump location {} on line {}:\n{}".format(args[1], linenr, line))
sys.exit(1)
bytecode.append((4 + ["JMP", "DJZX", "DJZY"].index(args[0])) | tags[args[1]] << 4)
else:
print("Unknown instruction on line {}:\n{}".format(linenr, line))
sys.exit(1)
# Execute
X = int(sys.argv[2])
Y = 0
isp = 0
while True:
if isp > len(bytecode):
print("Execution fell off end of program.")
sys.exit(1)
if debug:
print(X, Y, debug_lines[isp])
arg0 = bytecode[isp] & 0xf
arg1 = bytecode[isp] >> 4
isp += 1
if arg0 == 0: X += 1
elif arg0 == 1: Y += 1
elif arg0 == 2: break
elif arg0 == 3: print(X)
elif arg0 == 4: isp = arg1
elif arg0 == 5:
if X == 0: isp = arg1
else: X -= 1
elif arg0 == 6:
if Y == 0: isp = arg1
else: Y -= 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment