git @ Cat's Eye Technologies SixtyPical / 7a024f3
Compile static storage location access. Chris Pressey 5 years ago
2 changed file(s) with 35 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
2727 class Compiler(object):
2828 def __init__(self, emitter):
2929 self.emitter = emitter
30 self.routines = {}
31 self.labels = {}
32 self.trampolines = {} # Location -> Label
30 self.routines = {} # routine.name -> Routine
31 self.routine_statics = {} # routine.name -> { static.name -> Label }
32 self.labels = {} # global.name -> Label ("global" includes routines)
33 self.trampolines = {} # Location -> Label
3334 self.current_routine = None
3435
3536 # helper methods
5859 return length
5960
6061 def get_label(self, name):
61 if self.current_routine and hasattr(self.current_routine, 'statics'):
62 for static in self.current_routine.statics:
63 if static.location.name == name:
64 raise NotImplementedError("static " + name)
62 if self.current_routine:
63 static_label = self.routine_statics.get(self.current_routine.name, {}).get(name)
64 if static_label:
65 return static_label
6566 return self.labels[name]
6667
6768 # visitor methods
6970 def compile_program(self, program):
7071 assert isinstance(program, Program)
7172
73 defn_labels = []
74
7275 for defn in program.defns:
7376 length = self.compute_length_of_defn(defn)
74 self.labels[defn.name] = Label(defn.name, addr=defn.addr, length=length)
77 label = Label(defn.name, addr=defn.addr, length=length)
78 self.labels[defn.name] = label
79 defn_labels.append((defn, label))
7580
7681 for routine in program.routines:
7782 self.routines[routine.name] = routine
8085 label.set_addr(routine.addr)
8186 self.labels[routine.name] = label
8287
88 if hasattr(routine, 'statics'):
89 static_labels = {}
90 for defn in routine.statics:
91 length = self.compute_length_of_defn(defn)
92 label = Label(defn.name, addr=defn.addr, length=length)
93 static_labels[defn.name] = label
94 defn_labels.append((defn, label))
95 self.routine_statics[routine.name] = static_labels
96
8397 self.compile_routine(self.routines['main'])
8498 for routine in program.routines:
8599 if routine.name != 'main':
91105 self.emitter.emit(RTS())
92106
93107 # initialized data
94 for defn in program.defns:
108 for defn, label in defn_labels:
95109 if defn.initial is not None:
96 label = self.get_label(defn.name)
97110 initial_data = None
98111 type_ = defn.location.type
99112 if type_ == TYPE_BYTE:
109122 self.emitter.emit(initial_data)
110123
111124 # uninitialized, "BSS" data
112 for defn in program.defns:
125 for defn, label in defn_labels:
113126 if defn.initial is None and defn.addr is None:
114 label = self.get_label(defn.name)
115127 self.emitter.resolve_bss_label(label)
116
117128
118129 def compile_routine(self, routine):
119130 self.current_routine = routine
955955 | inputs x
956956 | outputs x
957957 | trashes z, n
958 | static byte t : 7
958 | static byte t : 255
959959 | {
960960 | st x, t
961961 | inc t
964964 |
965965 | define main routine
966966 | trashes a, x, z, n
967 | static byte t : 77
967 | static byte t : 7
968968 | {
969969 | ld x, t
970970 | call foo
971971 | }
972 = ???
972 = $080D LDX $081F
973 = $0810 JSR $0814
974 = $0813 RTS
975 = $0814 STX $081E
976 = $0817 INC $081E
977 = $081A LDX $081E
978 = $081D RTS
979 = $081E .byte $FF
980 = $081F .byte $07