diff --git a/bin/sixtypical b/bin/sixtypical index 2ade86c..2197c2b 100755 --- a/bin/sixtypical +++ b/bin/sixtypical @@ -58,6 +58,7 @@ def process_input_files(filenames, options): analyzer = Analyzer(debug=options.debug) analyzer.analyze_program(program) + compilation_roster = None if options.optimize_fallthru: from sixtypical.fallthru import FallthruAnalyzer @@ -72,8 +73,8 @@ def process_input_files(filenames, options): fa = FallthruAnalyzer(debug=options.debug) fa.analyze_program(program) - routines_list = fa.serialize() - dump(routines_list) + compilation_roster = fa.serialize() + dump(compilation_roster) if options.analyze_only: return @@ -116,7 +117,7 @@ def process_input_files(filenames, options): for byte in prelude: emitter.emit(Byte(byte)) compiler = Compiler(emitter) - compiler.compile_program(program) + compiler.compile_program(program, compilation_roster=compilation_roster) # If we are outputting a cartridge with boot and BRK address # at the end, pad to ROM size minus 4 bytes, and emit addresses. diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 113d8a2..b050af4 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -75,7 +75,7 @@ class Compiler(object): # visitor methods - def compile_program(self, program): + def compile_program(self, program, compilation_roster=None): assert isinstance(program, Program) defn_labels = [] @@ -102,10 +102,14 @@ class Compiler(object): 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': - self.compile_routine(routine) + if compilation_roster is None: + compilation_roster = [['main']] + [[routine.name] for routine in program.routines if routine.name != 'main'] + + for roster_row in compilation_roster: + for routine_name in roster_row[0:-1]: + self.compile_routine(self.routines[routine_name]) + routine_name = roster_row[-1] + self.compile_routine(self.routines[routine_name]) for location, label in self.trampolines.iteritems(): self.emitter.resolve_label(label) diff --git a/tests/SixtyPical Fallthru.md b/tests/SixtyPical Fallthru.md index 580df47..9ae5a7f 100644 --- a/tests/SixtyPical Fallthru.md +++ b/tests/SixtyPical Fallthru.md @@ -64,6 +64,9 @@ to pass these tests to be considered an implementation of SixtyPical. -> Functionality "Dump fallthru info for SixtyPical program" is implemented by -> shell command "bin/sixtypical --optimize-fallthru --dump-fallthru-info --analyze-only --traceback %(test-body-file)" + -> Functionality "Compile SixtyPical program with fallthru optimization" is implemented by + -> shell command "bin/sixtypical --prelude=c64 --optimize-fallthru --traceback %(test-body-file) >/tmp/foo && tests/appliances/bin/dcc6502-adapter Tests for functionality "Dump fallthru info for SixtyPical program" A single routine, obviously, falls through to nothing and has nothing fall @@ -222,3 +225,32 @@ because we don't necessarily know what actual routine the vector contains. = "foo" = ] = ] + + -> Tests for functionality "Compile SixtyPical program with fallthru optimization" + +Basic test for actually applying this optimization when compiling SixtyPical programs. + +Note this currently reflects the re-ordering, but does not remove the jmp/rts. + + | define foo routine trashes a, z, n + | { + | ld a, 0 + | } + | + | define bar routine trashes a, z, n + | { + | ld a, 255 + | goto foo + | } + | + | define main routine trashes a, z, n + | { + | goto foo + | } + = $080D JMP $0811 + = $0810 RTS + = $0811 LDA #$00 + = $0813 RTS + = $0814 LDA #$FF + = $0816 JMP $0811 + = $0819 RTS