git @ Cat's Eye Technologies SixtyPical / d408e74
Establish an `include` directory and `--include-path` option. Chris Pressey 2 years ago
28 changed file(s) with 113 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
33 0.21
44 ----
55
6 * A source file can be included in another source file
7 by means of the `include` directive.
8 * A routine can be declared `preserved`, which prevents a
9 compiler from omitting it from the final executable, even
10 if it determines it is not called by any other routine.
611 * The reference implementation constructs a callgraph and
712 determines the set of routines which are not reachable
813 (directly or indirectly) from `main`, with an eye to
914 omitting them from the final executable.
10 * A routine can be declared `preserved`, which prevents a
11 compiler from omitting it from the final executable, even
12 if it determines it is not called by any other routine.
1315 * Added `--prune-unreachable-routines` option, which causes
1416 the compiler to in fact omit routines determined to be
1517 unreachable as described above.
18 * Added `--include-path` option, which configures the list
19 of directories that are searched when a source file is
20 included with the `include` directive.
1621 * Code generation now performs modest peephole optimization
1722 at the end of each routine. This results in better code
1823 generation for constructs in tail position, notably
1924 tail optimization of `calls`, but also for `goto`s and
2025 `if` blocks at the end of a routine.
21 * The `dcc6502-adapter` test adapter was updated to conform
22 to the output of the latest version of `dcc6502`.
2326
2427 0.20
2528 ----
2929
3030 Not all computers think `'A'` should be `65`. Allow the character set to be
3131 mapped. Probably copy what Ophis does.
32
33 ### "Include" directives
34
35 Search a searchlist of include paths. And use them to make libraries of routines.
36
37 One such library routine might be an `interrupt routine` type for various architectures.
38 Since "the supervisor" has stored values on the stack, we should be able to trash them
39 with impunity, in such a routine.
4032
4133 ### Pointers into non-byte tables
4234
2525
2626 def process_input_files(filenames, options):
2727 symtab = SymbolTable()
28 include_path = options.include_path.split(':')
2829
2930 programs = []
3031
3132 for filename in options.filenames:
32 program = load_program(filename, symtab)
33 program = load_program(filename, symtab, include_path)
3334 if options.debug:
3435 print(symtab)
3536 programs.append(program)
137138 )
138139
139140 argparser.add_argument(
141 "--include-path", "-I", type=str, metavar='PATH', default='.',
142 help="A colon-separated list of directories in which to look for "
143 "files which are included during `include` directives."
144 )
145
146 argparser.add_argument(
140147 "--analyze-only",
141148 action="store_true",
142149 help="Only parse and analyze the program; do not compile it."
22
33 ### rudiments
44
5 In the [rudiments](rudiments/) directory are programs which are not for
6 any particular machine, but meant to demonstrate the features of SixtyPical.
7 Some are meant to fail and produce an error message. Others can run on
8 any architecture where there is a routine at 65490 which outputs the value
9 of the accumulator as an ASCII character.
5 In the [rudiments](rudiments/) directory are programs which are
6 meant to demonstrate the elementary features of SixtyPical, and
7 to serve as manual integration test cases.
8
9 These sources are portable across architectures. They include
10 architecture-dependent libraries to produce output. Libraries
11 for such are provided in the `include` directory in the root
12 directory of the repository; make it is on the compiler's include
13 search path.
14
15 Some others of these sources are meant to fail and produce an error
16 message when compiled.
1017
1118 ### c64
1219
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print YY
1
2 include "chrout.60p"
23
34 word score
45
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print Y
1
2 include "chrout.60p"
23
34 byte table[2048] buf
45 pointer ptr @ 254
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print AA
1
2 include "chrout.60p"
23
34 define print routine
45 trashes a, z, n
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print ENGGL
1
2 include "chrout.60p"
23
34 byte b
45
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print ENGGL
1
2 include "chrout.60p"
23
34 word w1
45
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print ENGGL
1
2 include "chrout.60p"
23
34 word w1
45 word w2
0 // Demonstrates vector tables.
1 // Include `support/${PLATFORM}.60p` before this source
20 // Should print YN
1
2 include "chrout.60p"
33
44 define main routine
55 trashes a, x, y, z, n, c, v
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print YA
1
2 include "chrout.60p"
23
34 define main routine
45 trashes a, x, y, z, n, c, v
0 // Include `support/${PLATFORM}.60p` and `support/stdlib.60p` before this source
10 // Should print 01
1
2 include "chrout.60p"
3 include "prbyte.60p"
24
35 byte lives
46
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print AB
1
2 include "chrout.60p"
23
34 define bar routine trashes a, z, n {
45 ld a, 66
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
2 include "chrout.60p"
23
34 define main routine
45 trashes a, y, z, n, c
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print AB
1
2 include "chrout.60p"
23
34 byte foo
45
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print H (being ASCII 72 = 8 * 9)
1
2 include "chrout.60p"
23
34 // Increase y by 7, circuitously
45 //
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print A
1
2 include "chrout.60p"
23
34 define main routine
45 inputs a
+0
-6
eg/rudiments/support/c64.60p less more
0 // Implementation of `chrout` for the Commodore 64 platform.
1
2 define chrout routine
3 inputs a
4 trashes a
5 @ 65490
+0
-26
eg/rudiments/support/stdlib.60p less more
0 byte table[16] hexchars : "0123456789ABCDEF"
1
2 define prbyte routine
3 inputs a, hexchars
4 trashes a, z, n, c, v
5 {
6 save x {
7 save a {
8 st off, c
9 shr a
10 shr a
11 shr a
12 shr a
13 and a, 15
14 ld x, a
15 ld a, hexchars + x
16 call chrout
17 }
18 save a {
19 and a, 15
20 ld x, a
21 ld a, hexchars + x
22 call chrout
23 }
24 }
25 }
+0
-6
eg/rudiments/support/vic20.60p less more
0 // Implementation of `chrout` for the Commodore VIC-20 platform.
1
2 define chrout routine
3 inputs a
4 trashes a
5 @ 65490
0 // Should print AABAB
1
02 // Demonstrates vector tables.
1 // Include `support/${PLATFORM}.60p` before this source
2 // Should print AABAB
3
4 include "chrout.60p"
35
46 vector routine
57 trashes a, z, n
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print AB
1
2 include "chrout.60p"
23
34 vector routine
45 trashes a, z, n
0 // Include `support/${PLATFORM}.60p` before this source
10 // Should print YY
1
2 include "chrout.60p"
23
34 word one
45 word table[256] many
0 // Implementation of `chrout` for the Commodore 64 platform.
1
2 define chrout routine
3 inputs a
4 trashes a
5 @ 65490
0 byte table[16] hexchars : "0123456789ABCDEF"
1
2 define prbyte routine
3 inputs a, hexchars
4 trashes a, z, n, c, v
5 {
6 save x {
7 save a {
8 st off, c
9 shr a
10 shr a
11 shr a
12 shr a
13 and a, 15
14 ld x, a
15 ld a, hexchars + x
16 call chrout
17 }
18 save a {
19 and a, 15
20 ld x, a
21 ld a, hexchars + x
22 call chrout
23 }
24 }
25 }
0 // Implementation of `chrout` for the Commodore VIC-20 platform.
1
2 define chrout routine
3 inputs a
4 trashes a
5 @ 65490
2020
2121
2222 class Parser(object):
23 def __init__(self, symtab, text, filename):
23 def __init__(self, symtab, text, filename, include_path):
2424 self.symtab = symtab
25 self.include_path = include_path
2526 self.scanner = Scanner(text, filename)
2627 self.current_routine_name = None
2728
99100 while self.scanner.consume('include'):
100101 filename = self.scanner.token
101102 self.scanner.scan()
102 program = load_program(filename, self.symtab)
103 program = load_program(filename, self.symtab, self.include_path)
103104 includes.append(program)
104105 while self.scanner.on('typedef', 'const'):
105106 if self.scanner.on('typedef'):
478479 # - - - -
479480
480481
481 def load_program(filename, symtab):
482 def load_program(filename, symtab, include_path):
483 import os
484 for include_dir in include_path:
485 if os.path.exists(os.path.join(include_dir, filename)):
486 filename = os.path.join(include_dir, filename)
487 break
482488 text = open(filename).read()
483 parser = Parser(symtab, text, filename)
489 parser = Parser(symtab, text, filename, include_path)
484490 program = parser.program()
485491 return program
486492