git @ Cat's Eye Technologies SixtyPical / b794d8d
Get serialization of relative labels correct. Chris Pressey 6 years ago
8 changed file(s) with 118 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
6363 sys.exit(1)
6464
6565 if options.compile:
66 fh = sys.stdout
6667 start_addr = 0xc000
6768 prelude = []
6869 if options.basic_prelude:
6970 start_addr = 0x0801
7071 prelude = [0x10, 0x08, 0xc9, 0x07, 0x9e, 0x32,
7172 0x30, 0x36, 0x31, 0x00, 0x00, 0x00]
73
74 # we are outputting a .PRG, so we output the load address first
75 # we don't use the Emitter for this b/c not part of addr space
76 fh.write(Word(start_addr).serialize(0))
77
7278 emitter = Emitter(start_addr)
73 # we are outputting a .PRG, so output the load address first
74 emitter.emit_header(Word(start_addr))
7579 for byte in prelude:
7680 emitter.emit(Byte(byte))
7781 compiler = Compiler(emitter)
7983 if options.debug:
8084 print repr(emitter.accum)
8185 else:
82 emitter.serialize(sys.stdout)
86 emitter.serialize(fh)
8387
8488 if options.execute:
8589 context = eval_program(program)
0 routine chrout
1 inputs a
2 trashes a
3 @ 65490
4
5 routine print
6 trashes a, z, n
7 {
8 ld a, 65
9 call chrout
10 }
11
12 routine main
13 trashes a, z, n
14 {
15 call print
16 call print
17 }
0 routine chrout
1 inputs a
2 trashes a
3 @ 65490
4
5 routine main
6 trashes a, x, y, z, n, c, v
7 {
8 ld a, 0
9 if z {
10 ld a, 89
11 call chrout
12 } else {
13 ld a, 78
14 call chrout
15 }
16
17 ld a, 1
18 if z {
19 ld a, 89
20 call chrout
21 } else {
22 ld a, 78
23 call chrout
24 }
25 }
0 routine chrout
1 inputs a
2 trashes a
3 @ 65490
4
5 routine main
6 trashes a, x, y, z, n, c, v
7 {
8 ld a, 0
9 if z {
10 ld a, 89
11 call chrout
12 ld a, 1
13 }
14
15 ld a, 65
16 call chrout
17
18 ld a, 1
19 if z {
20 ld a, 89
21 call chrout
22 ld a, 1
23 }
24 }
0 byte foo
1
2 routine chrout
3 inputs a
4 trashes a
5 @ 65490
6
7 routine print
8 inputs foo
9 trashes a, z, n
10 {
11 ld a, foo
12 call chrout
13 }
14
15 routine main
16 trashes a, y, z, n, foo
17 {
18 ld y, 65
19 st y, foo
20 call print
21 inc foo
22 call print
23 }
5656 assert self.addr is not None, "unresolved label: %s" % self.name
5757 return Word(self.addr).serialize(addr)
5858
59 def serialize_relative_to(self, addr):
60 assert self.addr is not None, "unresolved label: %s" % self.name
61 return Byte(self.addr - (addr + 2)).serialize(addr)
62
5963 def __repr__(self):
6064 addrs = ', addr=%r' % self.addr if self.addr is not None else ''
6165 return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs)
7074
7175 def emit(self, *things):
7276 for thing in things:
73 if isinstance(thing, int):
74 thing = Byte(thing)
7577 self.accum.append(thing)
7678 self.addr += thing.size()
77
78 def emit_header(self, *things):
79 """Does not advance the address counter"""
80 for thing in things:
81 if isinstance(thing, int):
82 thing = Byte(thing)
83 self.accum.append(thing)
8479
8580 def serialize(self, stream):
8681 addr = self.start_addr
5858 return 1
5959
6060 def serialize(self, addr):
61 # XXX serialize value relatively
62 return chr(0xff)
63 return self.value.serialize(addr)
61 return self.value.serialize_relative_to(addr)
6462
6563
6664 class Opcode(Emittable):
130130 | ld y, 2
131131 | }
132132 | }
133 = 00c0
133 = 00c0a900d005a0014c0bc0a00260
134
135 Compiling `if` without `else`.
136
137 | routine main
138 | trashes a, x, y, z, n, c, v
139 | {
140 | ld a, 0
141 | if z {
142 | ld y, 1
143 | }
144 | }
145 = 00c0a900d005a0014c0bc0a00260