Skip to content

Instantly share code, notes, and snippets.

@jcla1
Last active December 29, 2015 19:49
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 jcla1/7719610 to your computer and use it in GitHub Desktop.
Save jcla1/7719610 to your computer and use it in GitHub Desktop.
PSH 0
PSH 1
LOOP: SUM 2
OUT
DUP
JMP EO_CHECK
EO_CONT: OUT
POP
SSZ
PSH 20
BEQ END
POP 2
JMP LOOP
EO_CHECK: PSH 1
BEQ EO_RET
POP
PSH 0
BEQ EO_RET
POP
ADD -2
JMP EO_CHECK
EO_RET: POP
JMP EO_CONT
END: NOP
PSH 0
PSH 1
A: SUM 2
OUT
SSZ
PSH 20
BEQ END
POP 2
JMP A
END: NOP
import re
from time import sleep
from sys import argv, stderr
def runtime_error(*args):
exit()
def nop(stack, args):
return ("", stack)
def push(stack, args):
if len(args) < 1:
runtime_error()
stack.append(int(args[0]))
return ("", stack)
def pop(stack, args):
n = -int(args[0]) if len(args) > 0 else -1
return ("", stack[:n])
def jmp(stack, args):
if len(args) > 0:
return (args[0], stack)
else:
runtime_error()
def beq(stack, args):
if len(args) > 0 and stack[-1] == stack[-2]:
return (args[0], stack)
else:
return ("", stack)
def sum_stack(stack, args):
start = -int(args[0]) if len(args) > 0 else 0
stack.append(sum(stack[start:]))
return ("", stack)
def add(stack, args):
if len(args) < 1:
runtime_error()
else:
stack[-1] += int(args[0])
return ("", stack)
def duplicate(stack, args):
if len(stack) < 1: runtime_error()
stack.append(stack[-1])
return ("", stack)
def print_last_stack(stack, args):
print "==> %d" % stack[-1]
return ("", stack)
def stack_size(stack, args):
stack.append(len(stack))
return ("", stack)
funcs = {
"NOP" : nop,
"PSH" : push,
"POP" : pop,
"JMP" : jmp,
"BEQ" : beq,
"SUM" : sum_stack,
"ADD" : add,
"DUP" : duplicate,
"OUT" : print_last_stack,
"SSZ" : stack_size
}
def run(program, debug=False):
source_lines = program.split("\n")
lines = []
label_table = dict()
for line in source_lines:
line = line.strip()
if len(line) == 0:
continue
label, instr, args_blob = re.search("^(?:(\w+):\s+)?(\w+)(?:\s+(.+))?$", line).groups()
args = re.split("\s+", args_blob) if args_blob else []
if label:
label_table[label] = len(lines)
lines.append((label, instr.upper(), args))
stack = []
PP, SP = (0, -1)
LABEL, INSTR, ARGS = (0, 1, 2)
while PP < len(lines):
line = lines[PP]
f = funcs.get(line[INSTR], runtime_error)
jmp_label, stack = f(stack, line[ARGS])
if jmp_label:
# ignore unknown labels and just carry on in the program
pos = label_table.get(jmp_label, PP)
PP = pos
else:
PP += 1
if debug:
print >> stderr, "%-10s%-3s %s" % (line[LABEL] or "", line[INSTR], ", ".join(line[ARGS]))
print >> stderr, stack[-10:]
raw_input()
print stack
def main():
run(open(argv[1]).read(), argv[-1] == "d")
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment