mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-01-10 02:29:23 +00:00
Implement indirect JSRs with trampolines in theory; doesn't work.
This commit is contained in:
parent
b20945898e
commit
0b2b5d904e
@ -14,6 +14,7 @@ sys.path.insert(0, join(dirname(realpath(sys.argv[0])), '..', 'src'))
|
||||
|
||||
import codecs
|
||||
from optparse import OptionParser
|
||||
from pprint import pprint
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
@ -84,7 +85,7 @@ if __name__ == '__main__':
|
||||
compiler = Compiler(emitter)
|
||||
compiler.compile_program(program)
|
||||
if options.debug:
|
||||
print repr(emitter.accum)
|
||||
pprint(emitter.accum)
|
||||
else:
|
||||
emitter.serialize(fh)
|
||||
|
||||
|
@ -1,10 +1,31 @@
|
||||
vector foo outputs x trashes z, n
|
||||
vector print
|
||||
trashes a, z, n
|
||||
|
||||
routine bar outputs x trashes z, n {
|
||||
ld x, 200
|
||||
routine chrout
|
||||
inputs a
|
||||
trashes a
|
||||
@ 65490
|
||||
|
||||
routine printa
|
||||
trashes a, z, n
|
||||
{
|
||||
ld a, 65
|
||||
call chrout
|
||||
}
|
||||
|
||||
routine main inputs bar outputs x, foo trashes a, z, n {
|
||||
copy bar, foo
|
||||
call foo
|
||||
routine printb
|
||||
trashes a, z, n
|
||||
{
|
||||
ld a, 66
|
||||
call chrout
|
||||
}
|
||||
|
||||
routine main
|
||||
inputs printa, printb
|
||||
trashes print, a, z, n
|
||||
{
|
||||
copy printa, print
|
||||
call print
|
||||
copy printb, print
|
||||
call print
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ class Compiler(object):
|
||||
self.emitter = emitter
|
||||
self.routines = {}
|
||||
self.labels = {}
|
||||
self.trampolines = {} # Location -> Label
|
||||
|
||||
def compile_program(self, program):
|
||||
assert isinstance(program, Program)
|
||||
@ -52,11 +53,16 @@ class Compiler(object):
|
||||
if routine.name != 'main':
|
||||
self.compile_routine(routine)
|
||||
|
||||
for location, label in self.trampolines.iteritems():
|
||||
self.emitter.resolve_label(label)
|
||||
self.emitter.emit(JMP(Indirect(self.labels[location.name])))
|
||||
|
||||
for defn in program.defns:
|
||||
if defn.addr is None:
|
||||
label = self.labels[defn.name]
|
||||
self.emitter.resolve_bss_label(label)
|
||||
|
||||
|
||||
def compile_routine(self, routine):
|
||||
assert isinstance(routine, Routine)
|
||||
if routine.block:
|
||||
@ -198,9 +204,10 @@ class Compiler(object):
|
||||
if isinstance(location.type, RoutineType):
|
||||
self.emitter.emit(JSR(Absolute(label)))
|
||||
elif isinstance(location.type, VectorType):
|
||||
# XXX NOT QUITE RIGHT, IS IT?
|
||||
# We need to simulate an indirect JSR!
|
||||
self.emitter.emit(JMP(Indirect(label)))
|
||||
trampoline = self.trampolines.setdefault(
|
||||
location, Label(location.name + '_trampoline')
|
||||
)
|
||||
self.emitter.emit(JSR(Absolute(trampoline)))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
elif opcode == 'goto':
|
||||
|
Loading…
x
Reference in New Issue
Block a user