git @ Cat's Eye Technologies SixtyPical / ed1ed3e
Always analyze before compiling. Chris Pressey 3 years ago
6 changed file(s) with 116 addition(s) and 81 deletion(s). Raw diff Collapse all Expand all
8484 ### And at some point...
8585
8686 * Check that the buffer being read or written to through pointer, appears in approporiate inputs or outputs set.
87 * always analyze before executing or compiling, unless told not to
8887 * `interrupt` routines -- to indicate that "the supervisor" has stored values on the stack, so we can trash them.
8988 * error messages that include the line number of the source code
9089 * add absolute addressing in shl/shr, absolute-indexed for add, sub, etc.
2626 if __name__ == '__main__':
2727 optparser = OptionParser(__doc__.strip())
2828
29 optparser.add_option("--analyze",
29 optparser.add_option("--analyze-only",
3030 action="store_true",
31 help="")
31 help="Only parse and analyze the program; do not compile it.")
3232 optparser.add_option("--basic-prelude",
3333 action="store_true",
34 help="")
35 optparser.add_option("--compile",
36 action="store_true",
37 help="")
34 help="Insert a Commodore BASIC 2.0 snippet before the program "
35 "so that it can be LOADed and RUN on Commodore platforms.")
3836 optparser.add_option("--debug",
3937 action="store_true",
40 help="")
38 help="Display debugging information when analyzing and compiling.")
39 optparser.add_option("--parse-only",
40 action="store_true",
41 help="Only parse the program; do not analyze or compile it.")
4142 optparser.add_option("--traceback",
4243 action="store_true",
43 help="")
44 help="When an error occurs, display a full Python traceback.")
4445
4546 (options, args) = optparser.parse_args(sys.argv[1:])
4647
4748 for filename in args:
4849 text = open(filename).read()
49 parser = Parser(text)
50 program = parser.program()
5150
52 if options.analyze:
53 try:
54 analyzer = Analyzer(debug=options.debug)
55 analyzer.analyze_program(program)
56 except Exception as e:
57 if options.traceback:
58 raise
59 else:
60 traceback.print_exception(e.__class__, e, None)
61 sys.exit(1)
51 try:
52 parser = Parser(text)
53 program = parser.program()
54 except Exception as e:
55 if options.traceback:
56 raise
57 else:
58 traceback.print_exception(e.__class__, e, None)
59 sys.exit(1)
6260
63 if options.compile:
64 fh = sys.stdout
65 start_addr = 0xc000
66 prelude = []
67 if options.basic_prelude:
68 start_addr = 0x0801
69 prelude = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32,
70 0x30, 0x36, 0x31, 0x00, 0x00, 0x00]
61 if options.parse_only:
62 sys.exit(0)
7163
72 # we are outputting a .PRG, so we output the load address first
73 # we don't use the Emitter for this b/c not part of addr space
74 if not options.debug:
75 fh.write(Word(start_addr).serialize(0))
64 try:
65 analyzer = Analyzer(debug=options.debug)
66 analyzer.analyze_program(program)
67 except Exception as e:
68 if options.traceback:
69 raise
70 else:
71 traceback.print_exception(e.__class__, e, None)
72 sys.exit(1)
7673
77 emitter = Emitter(start_addr)
78 for byte in prelude:
79 emitter.emit(Byte(byte))
80 compiler = Compiler(emitter)
81 compiler.compile_program(program)
82 if options.debug:
83 pprint(emitter.accum)
84 else:
85 emitter.serialize(fh)
74 if options.analyze_only:
75 sys.exit(0)
76
77 fh = sys.stdout
78 start_addr = 0xc000
79 prelude = []
80 if options.basic_prelude:
81 start_addr = 0x0801
82 prelude = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32,
83 0x30, 0x36, 0x31, 0x00, 0x00, 0x00]
84
85 # we are outputting a .PRG, so we output the load address first
86 # we don't use the Emitter for this b/c not part of addr space
87 if not options.debug:
88 fh.write(Word(start_addr).serialize(0))
89
90 emitter = Emitter(start_addr)
91 for byte in prelude:
92 emitter.emit(Byte(byte))
93 compiler = Compiler(emitter)
94 compiler.compile_program(program)
95 if options.debug:
96 pprint(emitter.accum)
97 else:
98 emitter.serialize(fh)
257257 raise TypeMismatchError((src, dest))
258258 context.assert_meaningful(instr.index)
259259 elif src.type != dest.type:
260 raise TypeMismatchError('%s and %s in %s' %
261 (src.name, dest.name, self.current_routine.name)
260 raise TypeMismatchError('%r and %r in %s' %
261 (src, dest, self.current_routine.name)
262262 )
263263 context.assert_meaningful(src)
264264 context.set_written(dest)
66 [Falderal]: http://catseye.tc/node/Falderal
77
88 -> Functionality "Analyze SixtyPical program" is implemented by
9 -> shell command "bin/sixtypical --analyze --traceback %(test-body-file) && echo ok"
9 -> shell command "bin/sixtypical --analyze-only --traceback %(test-body-file) && echo ok"
1010
1111 -> Tests for functionality "Analyze SixtyPical program"
1212
235235 | ld a, 0
236236 | st a, foo
237237 | }
238 ? TypeMismatchError: a and foo in main
238 ? TypeMismatchError
239239
240240 ### tables ###
241241
66 [Falderal]: http://catseye.tc/node/Falderal
77
88 -> Functionality "Compile SixtyPical program" is implemented by
9 -> shell command "bin/sixtypical --basic-prelude --compile %(test-body-file) | tests/appliances/bin/dcc6502-adapter"
9 -> shell command "bin/sixtypical --basic-prelude --traceback %(test-body-file) >/tmp/foo && tests/appliances/bin/dcc6502-adapter </tmp/foo"
1010
1111 -> Tests for functionality "Compile SixtyPical program"
1212
276276 | trashes a, x, y, z, n, c, v
277277 | {
278278 | ld a, 0
279 | ld y, 0
279280 | if z {
280281 | ld y, 1
281282 | }
282283 | }
283284 = $080D LDA #$00
284 = $080F BNE $0813
285 = $0811 LDY #$01
286 = $0813 RTS
285 = $080F LDY #$00
286 = $0811 BNE $0815
287 = $0813 LDY #$01
288 = $0815 RTS
287289
288290 Compiling `repeat`.
289291
494496
495497 Copy routine to vector, inside an `interrupts off` block.
496498
497 | vector routine bar
499 | vector routine
500 | inputs x
501 | outputs x
502 | trashes z, n
503 | bar
498504 |
499505 | routine foo
500506 | inputs x
505511 | }
506512 |
507513 | routine main
508 | inputs foo
509514 | outputs bar
510515 | trashes a, n, z
511516 | {
567572
568573 Indirect call.
569574
570 | vector routine outputs x trashes z, n foo
571 |
572 | routine bar outputs x trashes z, n {
575 | vector routine
576 | outputs x
577 | trashes z, n
578 | foo
579 |
580 | routine bar
581 | outputs x
582 | trashes z, n
583 | {
573584 | ld x, 200
574585 | }
575586 |
576 | routine main inputs bar outputs x, foo trashes a, z, n {
587 | routine main
588 | outputs x, foo
589 | trashes a, z, n
590 | {
577591 | copy bar, foo
578592 | call foo
579593 | }
589603
590604 goto.
591605
592 | routine bar outputs x trashes z, n {
606 | routine bar
607 | inputs y
608 | outputs x, y
609 | trashes z, n
610 | {
593611 | ld x, 200
594612 | }
595613 |
596 | routine main outputs x trashes a, z, n {
614 | routine main
615 | outputs x, y
616 | trashes a, z, n
617 | {
597618 | ld y, 200
598619 | goto bar
599620 | }
840861 | routine main
841862 | inputs buf
842863 | outputs y, foo, delta
843 | trashes a, z, n, ptr
864 | trashes a, c, v, z, n, ptr
844865 | {
845866 | copy 619, delta
846867 | ld y, 0
868 | st off, c
847869 | copy ^buf, ptr
848870 | add ptr, delta
849871 | add ptr, word 1
850872 | copy [ptr] + y, foo
851873 | }
852874 = $080D LDA #$6B
853 = $080F STA $1042
875 = $080F STA $1043
854876 = $0812 LDA #$02
855 = $0814 STA $1043
877 = $0814 STA $1044
856878 = $0817 LDY #$00
857 = $0819 LDA #$41
858 = $081B STA $FE
859 = $081D LDA #$08
860 = $081F STA $FF
861 = $0821 LDA $FE
862 = $0823 ADC $1042
863 = $0826 STA $FE
864 = $0828 LDA $FF
865 = $082A ADC $1043
866 = $082D STA $FF
867 = $082F LDA $FE
868 = $0831 ADC #$01
869 = $0833 STA $FE
870 = $0835 LDA $FF
871 = $0837 ADC #$00
872 = $0839 STA $FF
873 = $083B LDA ($FE),Y
874 = $083D STA $1041
875 = $0840 RTS
879 = $0819 CLC
880 = $081A LDA #$42
881 = $081C STA $FE
882 = $081E LDA #$08
883 = $0820 STA $FF
884 = $0822 LDA $FE
885 = $0824 ADC $1043
886 = $0827 STA $FE
887 = $0829 LDA $FF
888 = $082B ADC $1044
889 = $082E STA $FF
890 = $0830 LDA $FE
891 = $0832 ADC #$01
892 = $0834 STA $FE
893 = $0836 LDA $FF
894 = $0838 ADC #$00
895 = $083A STA $FF
896 = $083C LDA ($FE),Y
897 = $083E STA $1042
898 = $0841 RTS
876899
877900 ### Trash
878901
99 [Falderal]: http://catseye.tc/node/Falderal
1010
1111 -> Functionality "Check syntax of SixtyPical program" is implemented by
12 -> shell command "bin/sixtypical %(test-body-file) && echo ok"
12 -> shell command "bin/sixtypical --parse-only --traceback %(test-body-file) && echo ok"
1313
1414 -> Tests for functionality "Check syntax of SixtyPical program"
1515