1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-02 03:41:28 +00:00

Compile static storage location access.

This commit is contained in:
Chris Pressey 2018-02-09 16:13:09 +00:00
parent 52fb1dc6b9
commit 7a024f3062
2 changed files with 35 additions and 16 deletions

View File

@ -28,9 +28,10 @@ class UnsupportedOpcodeError(KeyError):
class Compiler(object):
def __init__(self, emitter):
self.emitter = emitter
self.routines = {}
self.labels = {}
self.trampolines = {} # Location -> Label
self.routines = {} # routine.name -> Routine
self.routine_statics = {} # routine.name -> { static.name -> Label }
self.labels = {} # global.name -> Label ("global" includes routines)
self.trampolines = {} # Location -> Label
self.current_routine = None
# helper methods
@ -59,10 +60,10 @@ class Compiler(object):
return length
def get_label(self, name):
if self.current_routine and hasattr(self.current_routine, 'statics'):
for static in self.current_routine.statics:
if static.location.name == name:
raise NotImplementedError("static " + name)
if self.current_routine:
static_label = self.routine_statics.get(self.current_routine.name, {}).get(name)
if static_label:
return static_label
return self.labels[name]
# visitor methods
@ -70,9 +71,13 @@ class Compiler(object):
def compile_program(self, program):
assert isinstance(program, Program)
defn_labels = []
for defn in program.defns:
length = self.compute_length_of_defn(defn)
self.labels[defn.name] = Label(defn.name, addr=defn.addr, length=length)
label = Label(defn.name, addr=defn.addr, length=length)
self.labels[defn.name] = label
defn_labels.append((defn, label))
for routine in program.routines:
self.routines[routine.name] = routine
@ -81,6 +86,15 @@ class Compiler(object):
label.set_addr(routine.addr)
self.labels[routine.name] = label
if hasattr(routine, 'statics'):
static_labels = {}
for defn in routine.statics:
length = self.compute_length_of_defn(defn)
label = Label(defn.name, addr=defn.addr, length=length)
static_labels[defn.name] = label
defn_labels.append((defn, label))
self.routine_statics[routine.name] = static_labels
self.compile_routine(self.routines['main'])
for routine in program.routines:
if routine.name != 'main':
@ -92,9 +106,8 @@ class Compiler(object):
self.emitter.emit(RTS())
# initialized data
for defn in program.defns:
for defn, label in defn_labels:
if defn.initial is not None:
label = self.get_label(defn.name)
initial_data = None
type_ = defn.location.type
if type_ == TYPE_BYTE:
@ -110,12 +123,10 @@ class Compiler(object):
self.emitter.emit(initial_data)
# uninitialized, "BSS" data
for defn in program.defns:
for defn, label in defn_labels:
if defn.initial is None and defn.addr is None:
label = self.get_label(defn.name)
self.emitter.resolve_bss_label(label)
def compile_routine(self, routine):
self.current_routine = routine
assert isinstance(routine, Routine)

View File

@ -956,7 +956,7 @@ just the same as initialized global storage locations are.
| inputs x
| outputs x
| trashes z, n
| static byte t : 7
| static byte t : 255
| {
| st x, t
| inc t
@ -965,9 +965,17 @@ just the same as initialized global storage locations are.
|
| define main routine
| trashes a, x, z, n
| static byte t : 77
| static byte t : 7
| {
| ld x, t
| call foo
| }
= ???
= $080D LDX $081F
= $0810 JSR $0814
= $0813 RTS
= $0814 STX $081E
= $0817 INC $081E
= $081A LDX $081E
= $081D RTS
= $081E .byte $FF
= $081F .byte $07