1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-02 03:41:28 +00:00

Compile repeat loops.

This commit is contained in:
Chris Pressey 2015-10-18 13:55:40 +01:00
parent f7eb0d48a8
commit c5998ed240
7 changed files with 72 additions and 7 deletions

View File

@ -18,3 +18,8 @@ in future versions.
---
Added ability to compile to 6502 machine code and output a `PRG` file.
0.4
---
Added `repeat` loops to the language.

View File

@ -34,8 +34,6 @@ TODO
For 0.4:
* `if not`.
* `while` loops.
* `repeat` loops.
* explicitly-addressed memory locations
For 0.5:

View File

@ -74,7 +74,8 @@ if __name__ == '__main__':
# we are outputting a .PRG, so we output the load address first
# we don't use the Emitter for this b/c not part of addr space
fh.write(Word(start_addr).serialize(0))
if not options.debug:
fh.write(Word(start_addr).serialize(0))
emitter = Emitter(start_addr)
for byte in prelude:

16
eg/loop.p60 Normal file
View File

@ -0,0 +1,16 @@
routine chrout
inputs a
trashes a
@ 65490
routine main
trashes a, y, z, n, c
{
ld y, 65
repeat {
ld a, y
call chrout
inc y
cmp y, 91
} until z
}

View File

@ -9,10 +9,11 @@ from sixtypical.emitter import Label, Byte
from sixtypical.gen6502 import (
Immediate, Absolute, Relative,
LDA, LDX, LDY, STA, STX, STY,
TAX, TAY, TXA, TYA,
CLC, SEC, ADC, SBC, ROL, ROR,
INC, INX, INY, DEC, DEX, DEY,
CMP, CPX, CPY, AND, ORA, EOR,
BCC, BNE,
BCC, BCS, BNE, BEQ,
JMP, JSR, RTS,
)
@ -70,17 +71,25 @@ class Compiler(object):
if opcode == 'ld':
if dest == REG_A:
if isinstance(src, ConstantRef):
if src == REG_X:
self.emitter.emit(TXA())
elif src == REG_Y:
self.emitter.emit(TYA())
elif isinstance(src, ConstantRef):
self.emitter.emit(LDA(Immediate(Byte(src.value))))
else:
self.emitter.emit(LDA(Absolute(self.labels[src.name])))
elif dest == REG_X:
if isinstance(src, ConstantRef):
if src == REG_A:
self.emitter.emit(TAX())
elif isinstance(src, ConstantRef):
self.emitter.emit(LDX(Immediate(Byte(src.value))))
else:
self.emitter.emit(LDX(Absolute(self.labels[src.name])))
elif dest == REG_Y:
if isinstance(src, ConstantRef):
if src == REG_A:
self.emitter.emit(TAY())
elif isinstance(src, ConstantRef):
self.emitter.emit(LDY(Immediate(Byte(src.value))))
else:
self.emitter.emit(LDY(Absolute(self.labels[src.name])))
@ -184,5 +193,15 @@ class Compiler(object):
self.emitter.resolve_label(end_label)
else:
self.emitter.resolve_label(else_label)
elif opcode == 'repeat':
cls = {
'c': BCC,
'z': BNE,
}.get(src.name)
if cls is None:
raise UnsupportedOpcodeError(instr)
top_label = self.emitter.make_label()
self.compile_block(instr.block)
self.emitter.emit(cls(Relative(top_label)))
else:
raise NotImplementedError

View File

@ -99,6 +99,18 @@ class BCC(Opcode):
}
class BCS(Opcode):
opcodes = {
Relative: 0xb0,
}
class BEQ(Opcode):
opcodes = {
Relative: 0xf0,
}
class BNE(Opcode):
opcodes = {
Relative: 0xd0,

View File

@ -144,3 +144,17 @@ Compiling `if` without `else`.
| }
| }
= 00c0a900d002a00160
Compiling `repeat`.
| routine main
| trashes a, y, z, n, c
| {
| ld y, 65
| repeat {
| ld a, y
| inc y
| cmp y, 91
| } until z
| }
= 00c0a04198c8c05bd0fa60