forked from whaleygeek/MyLittleComputer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
symtab.py
100 lines (65 loc) · 2.34 KB
/
symtab.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# symtab.py 23/04/2015 D.J.Whale
#
# A symbol table to keep track of labels and their values and usage addresses
import instruction
defines = {} # label->addr
fixups = {} # addr->labelref
def trace(msg):
print(str(msg))
def is_defined(label):
return label in defines
def define(label, addr):
"""Define a new label"""
#trace("define:" + str(label) + "=" + str(addr))
if defines.has_key(label):
raise ValueError("Label already defined:" + label + "=" + str(defines[label]))
defines[label] = addr
def use(label, refaddr):
"""Use (refer to) a label"""
if not defines.has_key(label):
#trace("use:" + str(label) + " at:" + str(refaddr))
fixlater(refaddr, label)
addrref = None
else:
addrref = defines[label]
#trace("use:" + str(label) + " at:" + str(refaddr) + " fixup:" + str(addrref))
# already known, so get it's value
return addrref
def get(label):
"""Get the value associated with a label"""
if not defines.has_key(label):
raise ValueError("Unknown label:" + str(label))
return defines[label]
def fixlater(refaddr, label):
"""Defer the fixup of a reference to a label at this address, til later"""
fixups[refaddr] = label
def fixup(memory):
"""Fixup all addresses"""
# Find all usages that did not previously have a define
for refaddr in fixups:
label = fixups[refaddr]
realaddr = defines[label]
#trace("fixup refaddr:" + str(refaddr) + " for label:" + label + " to:" + str(realaddr))
instr1 = memory[refaddr]
instr2 = instruction.setOperand(instr1, realaddr)
#instr1_str = instruction.toString(instr1)
#instr2_str = instruction.toString(instr2)
#trace("fixup: old:" + str(instr1_str) + " new:" + str(instr2_str))
memory[refaddr] = instr2
def dumpLabels(f=None):
"""Dump the whole symbol table to stdout"""
if f==None:
import sys
f = sys.stdout
f.write("LABELS:\n")
for label in defines:
f.write(" " + label + ":" + str(defines[label]) + "\n")
def dumpFixups(f=None):
"""Dump all fixups in the symbol table to stdout"""
if f==None:
import sys
f = sys.stdout
f.write("FIXUPS:\n")
for refaddr in fixups:
f.write(" " + str(refaddr) + ":" + fixups[refaddr] + "\n")
# END