git @ Cat's Eye Technologies SixtyPical / 643a48a
Compiler object, labels, compile 'call'... It prints 'A'! Chris Pressey 6 years ago
7 changed file(s) with 116 addition(s) and 88 deletion(s). Raw diff Collapse all Expand all
3232
3333 For 0.3:
3434
35 * extern routines.
3635 * generate 6502 code for all SixtyPical instructions.
37 * a little demo that actually compiles and does something on a C64 emulator.
3836
3937 For 0.4:
4038
2020 from sixtypical.evaluator import eval_program
2121 from sixtypical.analyzer import analyze_program
2222 from sixtypical.emitter import Emitter, Byte, Word
23 from sixtypical.compiler import compile_program
23 from sixtypical.compiler import Compiler
2424
2525
2626 if __name__ == '__main__':
7474 emitter.emit(Word(start_addr))
7575 for byte in header:
7676 emitter.emit(Byte(byte))
77 compile_program(program, emitter)
77 compiler = Compiler(emitter)
78 compiler.compile_program(program)
7879 if options.debug:
7980 print repr(emitter.accum)
8081 else:
0 routine chrout
1 inputs a
2 trashes a
3 @ 65490
4
5 routine main
6 inputs a
7 trashes a, z, n
8 {
9 ld a, 65
10 call chrout
11 }
44 ConstantRef, LocationRef,
55 REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
66 )
7 from sixtypical.emitter import Byte
7 from sixtypical.emitter import Label, Byte
88 from sixtypical.gen6502 import (
99 Immediate, Absolute,
10 LDA, LDX, LDY, STA, STX, STY, CLC, SEC, ADC, RTS
10 LDA, LDX, LDY, STA, STX, STY, CLC, SEC, ADC, RTS, JSR
1111 )
1212
1313
1515 pass
1616
1717
18 def compile_program(program, emitter):
19 assert isinstance(program, Program)
20 routines = {r.name: r for r in program.routines}
21 for routine in program.routines:
22 compile_routine(routine, emitter, routines)
18 class Compiler(object):
19 def __init__(self, emitter):
20 self.emitter = emitter
21 self.routines = {}
22 self.labels = {}
2323
24 def compile_program(self, program):
25 assert isinstance(program, Program)
26 for routine in program.routines:
27 self.routines[routine.name] = routine
28 label = Label(routine.name)
29 if routine.addr is not None:
30 label.set_addr(routine.addr)
31 self.labels[routine.name] = label
32 for routine in program.routines:
33 self.compile_routine(routine)
2434
25 def compile_routine(routine, emitter, routines):
26 assert isinstance(routine, Routine)
27 label = emitter.make_label(routine.name)
28 if routine.block:
29 compile_block(routine.block, emitter, routines)
30 emitter.emit(RTS())
31 return label
35 def compile_routine(self, routine):
36 assert isinstance(routine, Routine)
37 if routine.block:
38 self.compile_block(routine.block)
39 self.emitter.emit(RTS())
3240
41 def compile_block(self, block):
42 assert isinstance(block, Block)
43 label = self.emitter.make_label()
44 for instr in block.instrs:
45 self.compile_instr(instr)
46 return label
3347
34 def compile_block(block, emitter, routines):
35 assert isinstance(block, Block)
36 label = emitter.make_label()
37 for instr in block.instrs:
38 compile_instr(instr, emitter, routines)
39 return label
40
41
42 def compile_instr(instr, emitter, routines):
43 assert isinstance(instr, Instr)
44 opcode = instr.opcode
45 dest = instr.dest
46 src = instr.src
47
48 if opcode == 'ld':
49 if dest == REG_A:
50 if isinstance(src, ConstantRef):
51 emitter.emit(LDA(Immediate(Byte(src.value))))
48 def compile_instr(self, instr):
49 assert isinstance(instr, Instr)
50 opcode = instr.opcode
51 dest = instr.dest
52 src = instr.src
53
54 if opcode == 'ld':
55 if dest == REG_A:
56 if isinstance(src, ConstantRef):
57 self.emitter.emit(LDA(Immediate(Byte(src.value))))
58 else:
59 self.emitter.emit(LDA(Absolute(src.label)))
60 elif dest == REG_X:
61 pass
62 elif dest == REG_Y:
63 pass
5264 else:
53 emitter.emit(LDA(Absolute(src.label)))
54 elif dest == REG_X:
55 pass
56 elif dest == REG_Y:
57 pass
65 raise UnsupportedOpcodeError(instr)
66 elif opcode == 'st':
67 if dest == FLAG_C and src == ConstantRef(0):
68 self.emitter.emit(CLC())
69 elif dest == FLAG_C and src == ConstantRef(1):
70 self.emitter.emit(SEC())
71 elif src == REG_A:
72 self.emitter.emit(STA(Absolute(dest.label)))
73 elif src == REG_X:
74 self.emitter.emit(STX(Absolute(dest.label)))
75 elif src == REG_Y:
76 self.emitter.emit(STY(Absolute(dest.label)))
77 else:
78 raise UnsupportedOpcodeError(instr)
79 elif opcode == 'add':
80 if dest == REG_A:
81 if isinstance(src, ConstantRef):
82 self.emitter.emit(ADC(Immediate(Byte(src.value))))
83 else:
84 self.emitter.emit(ADC(Absolute(src.label)))
85 else:
86 raise UnsupportedOpcodeError(instr)
87 elif opcode == 'sub':
88 raise NotImplementedError
89 elif opcode == 'inc':
90 raise NotImplementedError
91 elif opcode == 'dec':
92 raise NotImplementedError
93 elif opcode == 'cmp':
94 raise NotImplementedError
95 elif opcode == 'and':
96 raise NotImplementedError
97 elif opcode == 'or':
98 raise NotImplementedError
99 elif opcode == 'xor':
100 raise NotImplementedError
101 elif opcode == 'shl':
102 raise NotImplementedError
103 elif opcode == 'shr':
104 raise NotImplementedError
105 elif opcode == 'call':
106 label = self.labels[instr.name]
107 self.emitter.emit(JSR(Absolute(label)))
108 elif opcode == 'if':
109 raise NotImplementedError
58110 else:
59 raise UnsupportedOpcodeError(instr)
60 elif opcode == 'st':
61 if dest == FLAG_C and src == ConstantRef(0):
62 emitter.emit(CLC())
63 elif dest == FLAG_C and src == ConstantRef(1):
64 emitter.emit(SEC())
65 elif src == REG_A:
66 emitter.emit(STA(Absolute(dest.label)))
67 elif src == REG_X:
68 emitter.emit(STX(Absolute(dest.label)))
69 elif src == REG_Y:
70 emitter.emit(STY(Absolute(dest.label)))
71 else:
72 raise UnsupportedOpcodeError(instr)
73 elif opcode == 'add':
74 if dest == REG_A:
75 if isinstance(src, ConstantRef):
76 emitter.emit(ADC(Immediate(Byte(src.value))))
77 else:
78 emitter.emit(ADC(Absolute(src.label)))
79 else:
80 raise UnsupportedOpcodeError(instr)
81 elif opcode == 'sub':
82 raise NotImplementedError
83 elif opcode == 'inc':
84 raise NotImplementedError
85 elif opcode == 'dec':
86 raise NotImplementedError
87 elif opcode == 'cmp':
88 raise NotImplementedError
89 elif opcode == 'and':
90 raise NotImplementedError
91 elif opcode == 'or':
92 raise NotImplementedError
93 elif opcode == 'xor':
94 raise NotImplementedError
95 elif opcode == 'shl':
96 raise NotImplementedError
97 elif opcode == 'shr':
98 raise NotImplementedError
99 elif opcode == 'call':
100 raise NotImplementedError(instr.name)
101 elif opcode == 'if':
102 raise NotImplementedError
103 else:
104 raise NotImplementedError
111 raise NotImplementedError
5757 assert self.addr is not None, "unresolved label: %s" % self.name
5858 return Word(self.addr).serialize()
5959
60 def __repr__(self):
61 addrs = ', addr=%r' % self.addr if self.addr is not None else ''
62 return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs)
63
6064
6165 class Emitter(object):
6266 def __init__(self, addr):
122122 }
123123
124124
125 class JSR(Opcode):
126 opcodes = {
127 Absolute: 0x20,
128 }
129
130
125131 class LDA(Opcode):
126132 opcodes = {
127133 Immediate: 0xa9,
4343 | ld a, 65
4444 | call chrout
4545 | }
46 = 00c018690460
46 = 00c0a94120d2ff60