-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathisa_cpu.py
More file actions
86 lines (67 loc) · 2.01 KB
/
isa_cpu.py
File metadata and controls
86 lines (67 loc) · 2.01 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
class ISACPU:
def __init__(self, index):
self.index = index
self.reset()
def reset(self):
self.reg = {"R0": None, "R1": False, "R3": False, "R4": False}
self.labels = {}
self.pc = 0
self.executed = set()
self.skipped = set()
self.branch_taken = set()
def mark_exec(self, i):
self.executed.add(i)
def mark_skip(self, i):
self.skipped.add(i)
def build_labels(self, program):
for i, instr in enumerate(program):
if instr.startswith("LABEL"):
_, name = instr.split()
self.labels[name] = i
def step(self, program):
if self.pc >= len(program):
return False
instr = program[self.pc]
parts = instr.split()
op = parts[0]
self.mark_exec(self.pc)
# LABEL
if op == "LABEL":
self.pc += 1
return True
# LOAD
elif op == "LOAD":
_, r, val = parts
self.reg[r] = val
# INDEX
elif op == "IN_INDEX":
self.reg["R1"] = self.reg["R0"] in self.index
# BLACKLIST
elif op == "BLACKLIST":
self.reg["R3"] = self.reg["R0"] in {"the", "and"}
# NOT
elif op == "NOT":
_, r, src = parts
self.reg[r] = not self.reg[src]
# AND
elif op == "AND":
self.reg["R4"] = self.reg["R1"] and self.reg["R3"]
# BRANCH
elif op == "JMPZ":
_, r, label = parts
if not self.reg[r]:
self.branch_taken.add(self.pc)
self.pc = self.labels[label]
return True
self.pc += 1
return True
# -------------------------
# CONTROL FUNCTIONS
# -------------------------
def rewind(self):
if not self.history:
return False
self.pc, self.reg = self.history.pop()
return True
def is_done(self, program):
return self.pc >= len(program)