-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvm.py
67 lines (59 loc) · 1.68 KB
/
vm.py
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
from opcodes import *
globals().update(OPCODES.__members__)
def run(code):
vm = VirtualMachine()
i = 0 # index in code
while True:
op = code[i]
if op == PUSH:
i += 1
vm.stack.append(code[i])
elif op == ADD:
b = vm.stack.pop()
a = vm.stack.pop()
vm.stack.append(a+b)
elif op == SUB:
b = vm.stack.pop()
a = vm.stack.pop()
vm.stack.append(a-b)
elif op == AND:
b = vm.stack.pop()
a = vm.stack.pop()
vm.stack.append(a & b)
elif op == PRINT:
print(vm.stack.pop(), end='')
elif op == OUTCHAR:
print(chr(vm.stack.pop()), end='')
elif op == LT:
b = vm.stack.pop()
a = vm.stack.pop()
vm.stack.append(int(a < b))
elif op == JMP:
i = code[i+1]-1
elif op == JZ:
i += 1
addr = code[i]
if vm.stack.pop() == 0:
i = addr-1
elif op == GSTORE:
i += 1
addr = code[i]
vm.globals[addr] = vm.stack.pop()
elif op == GLOAD:
i += 1
addr = code[i]
vm.stack.append(vm.globals[addr])
elif op == HALT:
return
else:
raise Exception(f"Invalid opcode: {op}")
i += 1
class VirtualMachine:
def __init__(self):
# Stack implemented as list
# append() - add to stack
# pop() - remove from stack
self.stack = []
# Globals implemented as dictionary
# Keys will be addresses in memory (integer)
self.globals = {}