diff --git a/HISTORY.md b/HISTORY.md index 47f5298..2ed6a2d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -4,23 +4,26 @@ History of SixtyPical 0.21 ---- +* A source file can be included in another source file + by means of the `include` directive. +* 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 reference implementation constructs a callgraph and determines the set of routines which are not reachable (directly or indirectly) from `main`, 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. * Added `--prune-unreachable-routines` option, which causes the compiler to in fact omit routines determined to be unreachable as described above. +* Added `--include-path` option, which configures the list + of directories that are searched when a source file is + included with the `include` directive. * Code generation now performs modest peephole optimization at the end of each routine. This results in better code generation for constructs in tail position, notably tail optimization of `calls`, but also for `goto`s and `if` blocks at the end of a routine. -* The `dcc6502-adapter` test adapter was updated to conform - to the output of the latest version of `dcc6502`. 0.20 ---- diff --git a/TODO.md b/TODO.md index 127c031..c1c39c0 100644 --- a/TODO.md +++ b/TODO.md @@ -31,14 +31,6 @@ For goodness sake, let the programmer say `'A'` instead of `65`. Not all computers think `'A'` should be `65`. Allow the character set to be mapped. Probably copy what Ophis does. -### "Include" directives - -Search a searchlist of include paths. And use them to make libraries of routines. - -One such library routine might be an `interrupt routine` type for various architectures. -Since "the supervisor" has stored values on the stack, we should be able to trash them -with impunity, in such a routine. - ### Pointers into non-byte tables Right now you cannot get a pointer into a non-byte (for instance, word or vector) table. diff --git a/bin/sixtypical b/bin/sixtypical index 2a3f20d..b1420b4 100755 --- a/bin/sixtypical +++ b/bin/sixtypical @@ -26,11 +26,12 @@ from sixtypical.compiler import Compiler def process_input_files(filenames, options): symtab = SymbolTable() + include_path = options.include_path.split(':') programs = [] for filename in options.filenames: - program = load_program(filename, symtab) + program = load_program(filename, symtab, include_path) if options.debug: print(symtab) programs.append(program) @@ -137,6 +138,12 @@ if __name__ == '__main__': "Default: raw." ) + argparser.add_argument( + "--include-path", "-I", type=str, metavar='PATH', default='.', + help="A colon-separated list of directories in which to look for " + "files which are included during `include` directives." + ) + argparser.add_argument( "--analyze-only", action="store_true", diff --git a/eg/README.md b/eg/README.md index eb4be82..615a8aa 100644 --- a/eg/README.md +++ b/eg/README.md @@ -3,11 +3,18 @@ in subdirectories by machine architecture. ### rudiments -In the [rudiments](rudiments/) directory are programs which are not for -any particular machine, but meant to demonstrate the features of SixtyPical. -Some are meant to fail and produce an error message. Others can run on -any architecture where there is a routine at 65490 which outputs the value -of the accumulator as an ASCII character. +In the [rudiments](rudiments/) directory are programs which are +meant to demonstrate the elementary features of SixtyPical, and +to serve as manual integration test cases. + +These sources are portable across architectures. They include +architecture-dependent libraries to produce output. Libraries +for such are provided in the `include` directory in the root +directory of the repository; make it is on the compiler's include +search path. + +Some others of these sources are meant to fail and produce an error +message when compiled. ### c64 diff --git a/eg/rudiments/add.60p b/eg/rudiments/add.60p index 3c5a631..5174627 100644 --- a/eg/rudiments/add.60p +++ b/eg/rudiments/add.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print YY +include "chrout.60p" + word score define main routine diff --git a/eg/rudiments/buffer.60p b/eg/rudiments/buffer.60p index 18eb6d8..d5c3023 100644 --- a/eg/rudiments/buffer.60p +++ b/eg/rudiments/buffer.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print Y +include "chrout.60p" + byte table[2048] buf pointer ptr @ 254 byte foo diff --git a/eg/rudiments/call.60p b/eg/rudiments/call.60p index eed32f3..a407204 100644 --- a/eg/rudiments/call.60p +++ b/eg/rudiments/call.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print AA +include "chrout.60p" + define print routine trashes a, z, n { diff --git a/eg/rudiments/cmp-byte.60p b/eg/rudiments/cmp-byte.60p index 21e1f7b..1d488f1 100644 --- a/eg/rudiments/cmp-byte.60p +++ b/eg/rudiments/cmp-byte.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print ENGGL +include "chrout.60p" + byte b define main routine diff --git a/eg/rudiments/cmp-litword.60p b/eg/rudiments/cmp-litword.60p index 5cf9793..66366b6 100644 --- a/eg/rudiments/cmp-litword.60p +++ b/eg/rudiments/cmp-litword.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print ENGGL +include "chrout.60p" + word w1 define main routine diff --git a/eg/rudiments/cmp-word.60p b/eg/rudiments/cmp-word.60p index 853c08e..e5ff73c 100644 --- a/eg/rudiments/cmp-word.60p +++ b/eg/rudiments/cmp-word.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print ENGGL +include "chrout.60p" + word w1 word w2 diff --git a/eg/rudiments/conditional.60p b/eg/rudiments/conditional.60p index 66c0ea8..cbb4c53 100644 --- a/eg/rudiments/conditional.60p +++ b/eg/rudiments/conditional.60p @@ -1,7 +1,7 @@ -// Demonstrates vector tables. -// Include `support/${PLATFORM}.60p` before this source // Should print YN +include "chrout.60p" + define main routine trashes a, x, y, z, n, c, v { diff --git a/eg/rudiments/conditional2.60p b/eg/rudiments/conditional2.60p index 0def82c..6709b61 100644 --- a/eg/rudiments/conditional2.60p +++ b/eg/rudiments/conditional2.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print YA +include "chrout.60p" + define main routine trashes a, x, y, z, n, c, v { diff --git a/eg/rudiments/example.60p b/eg/rudiments/example.60p index a374c6e..e6f0031 100644 --- a/eg/rudiments/example.60p +++ b/eg/rudiments/example.60p @@ -1,6 +1,8 @@ -// Include `support/${PLATFORM}.60p` and `support/stdlib.60p` before this source // Should print 01 +include "chrout.60p" +include "prbyte.60p" + byte lives define main routine diff --git a/eg/rudiments/goto.60p b/eg/rudiments/goto.60p index 1c8d9a9..1e57945 100644 --- a/eg/rudiments/goto.60p +++ b/eg/rudiments/goto.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print AB +include "chrout.60p" + define bar routine trashes a, z, n { ld a, 66 call chrout diff --git a/eg/rudiments/loop.60p b/eg/rudiments/loop.60p index 6ccb445..b4c57fc 100644 --- a/eg/rudiments/loop.60p +++ b/eg/rudiments/loop.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print ABCDEFGHIJKLMNOPQRSTUVWXYZ +include "chrout.60p" + define main routine trashes a, y, z, n, c { diff --git a/eg/rudiments/memloc.60p b/eg/rudiments/memloc.60p index cb8bd5b..2baf8a8 100644 --- a/eg/rudiments/memloc.60p +++ b/eg/rudiments/memloc.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print AB +include "chrout.60p" + byte foo define print routine diff --git a/eg/rudiments/nested-for.60p b/eg/rudiments/nested-for.60p index 833f09d..c735d90 100644 --- a/eg/rudiments/nested-for.60p +++ b/eg/rudiments/nested-for.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print H (being ASCII 72 = 8 * 9) +include "chrout.60p" + // Increase y by 7, circuitously // define foo routine diff --git a/eg/rudiments/print.60p b/eg/rudiments/print.60p index 7589930..78ac6bb 100644 --- a/eg/rudiments/print.60p +++ b/eg/rudiments/print.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print A +include "chrout.60p" + define main routine inputs a trashes a, z, n diff --git a/eg/rudiments/vector-table.60p b/eg/rudiments/vector-table.60p index 0bead91..7b8e9b0 100644 --- a/eg/rudiments/vector-table.60p +++ b/eg/rudiments/vector-table.60p @@ -1,7 +1,9 @@ -// Demonstrates vector tables. -// Include `support/${PLATFORM}.60p` before this source // Should print AABAB +// Demonstrates vector tables. + +include "chrout.60p" + vector routine trashes a, z, n print diff --git a/eg/rudiments/vector.60p b/eg/rudiments/vector.60p index b4b018c..7f0b38a 100644 --- a/eg/rudiments/vector.60p +++ b/eg/rudiments/vector.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print AB +include "chrout.60p" + vector routine trashes a, z, n print diff --git a/eg/rudiments/word-table.60p b/eg/rudiments/word-table.60p index 54babbc..9372700 100644 --- a/eg/rudiments/word-table.60p +++ b/eg/rudiments/word-table.60p @@ -1,6 +1,7 @@ -// Include `support/${PLATFORM}.60p` before this source // Should print YY +include "chrout.60p" + word one word table[256] many diff --git a/eg/rudiments/support/c64.60p b/include/c64/chrout.60p similarity index 100% rename from eg/rudiments/support/c64.60p rename to include/c64/chrout.60p diff --git a/eg/rudiments/support/stdlib.60p b/include/stdlib/prbyte.60p similarity index 100% rename from eg/rudiments/support/stdlib.60p rename to include/stdlib/prbyte.60p diff --git a/eg/rudiments/support/vic20.60p b/include/vic20/chrout.60p similarity index 100% rename from eg/rudiments/support/vic20.60p rename to include/vic20/chrout.60p diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index ce03244..cc35c2d 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -21,8 +21,9 @@ class ForwardReference(object): class Parser(object): - def __init__(self, symtab, text, filename): + def __init__(self, symtab, text, filename, include_path): self.symtab = symtab + self.include_path = include_path self.scanner = Scanner(text, filename) self.current_routine_name = None @@ -100,7 +101,7 @@ class Parser(object): while self.scanner.consume('include'): filename = self.scanner.token self.scanner.scan() - program = load_program(filename, self.symtab) + program = load_program(filename, self.symtab, self.include_path) includes.append(program) while self.scanner.on('typedef', 'const'): if self.scanner.on('typedef'): @@ -479,9 +480,14 @@ class Parser(object): # - - - - -def load_program(filename, symtab): +def load_program(filename, symtab, include_path): + import os + for include_dir in include_path: + if os.path.exists(os.path.join(include_dir, filename)): + filename = os.path.join(include_dir, filename) + break text = open(filename).read() - parser = Parser(symtab, text, filename) + parser = Parser(symtab, text, filename, include_path) program = parser.program() return program