From 1098347fa5efc757aafc22513f1af67fba759d18 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Mon, 21 Oct 2019 21:45:59 +0100 Subject: [PATCH] Routines can be declared `preserved`. --- HISTORY.md | 3 +++ src/sixtypical/callgraph.py | 4 ++-- src/sixtypical/parser.py | 4 ++++ tests/SixtyPical Callgraph.md | 39 ++++++++++++++++++++++++++++++----- tests/SixtyPical Syntax.md | 12 +++++++++++ 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index a7d1486..d5ca93c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,6 +8,9 @@ History of SixtyPical approximates the set of routines which are not called by any other routine, with an eye to omitting them from the final executable. +* A routine can be declared `preserved`, which prevents a + compiler from omitting it from the final executable, even + if it determines it is not called by any other routine. * The `dcc6502-adapter` test adapter was updated to conform to the output of the latest version of `dcc6502`. diff --git a/src/sixtypical/callgraph.py b/src/sixtypical/callgraph.py index b3a87db..bf8b39d 100644 --- a/src/sixtypical/callgraph.py +++ b/src/sixtypical/callgraph.py @@ -33,8 +33,8 @@ def construct_callgraph(program): potential_calls = node['potentially-calls'] if routine.name in potential_calls: potentially_called_by.append(name) - if getattr(routine, 'explicitly_marked_as_called', None) or routine.name == 'main': - potentially_called_by.append('*marked*') + if getattr(routine, 'preserved', None) or routine.name == 'main': + potentially_called_by.append('*preserved*') graph[routine.name]['potentially-called-by'] = potentially_called_by return graph diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index 0cf7107..64b6631 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -111,8 +111,12 @@ class Parser(object): name = self.scanner.token self.scanner.scan() self.current_routine_name = name + preserved = False + if self.scanner.consume('preserved'): + preserved = True type_, routine = self.routine(name) self.declare(name, routine, type_) + routine.preserved = preserved routines.append(routine) self.current_routine_name = None self.scanner.check_type('EOF') diff --git a/tests/SixtyPical Callgraph.md b/tests/SixtyPical Callgraph.md index aeee12b..62d5ff6 100644 --- a/tests/SixtyPical Callgraph.md +++ b/tests/SixtyPical Callgraph.md @@ -12,7 +12,7 @@ called. The `main` routine is always called. The thing that it will be called by is the system, but the callgraph analyzer will -simply consider it to be "marked as called". +simply consider it to be "marked as preserved". | define main routine | { @@ -20,7 +20,7 @@ simply consider it to be "marked as called". = { = "main": { = "potentially-called-by": [ - = "*marked*" + = "*preserved*" = ], = "potentially-calls": [] = } @@ -39,7 +39,7 @@ If a routine is called by another routine, this fact will be noted. = { = "main": { = "potentially-called-by": [ - = "*marked*" + = "*preserved*" = ], = "potentially-calls": [ = "other" @@ -68,7 +68,7 @@ the final executable. = { = "main": { = "potentially-called-by": [ - = "*marked*" + = "*preserved*" = ], = "potentially-calls": [] = }, @@ -78,6 +78,35 @@ the final executable. = } = } +If a routine is not called by another routine, but it is declared +explicitly as `preserved`, then it will not be considered unused, +and a compiler or linker will not be permitted to omit it from +the final executable. This is useful for interrupt routines and +such that really are used by some part of the system, even if not +directly by another SixtyPical routine. + + | define main routine + | { + | } + | + | define other preserved routine + | { + | } + = { + = "main": { + = "potentially-called-by": [ + = "*preserved*" + = ], + = "potentially-calls": [] + = }, + = "other": { + = "potentially-called-by": [ + = "*preserved*" + = ], + = "potentially-calls": [] + = } + = } + If two routines potentially call each other, this will be noted, even if nothing else potentially calls either of those routines. This may change in the future. @@ -98,7 +127,7 @@ This may change in the future. = { = "main": { = "potentially-called-by": [ - = "*marked*" + = "*preserved*" = ], = "potentially-calls": [] = }, diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md index f830394..f164a73 100644 --- a/tests/SixtyPical Syntax.md +++ b/tests/SixtyPical Syntax.md @@ -73,6 +73,18 @@ Extern routines | @ 65487 = ok +Preserved routine. + + | define main routine { + | ld a, $ff + | add a, $01 + | } + | define foo preserved routine { + | ld a, 0 + | add a, 1 + | } + = ok + Trash. | define main routine {