1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-29 18:49:22 +00:00

Implement compiling if, but we need relative addressing first.

This commit is contained in:
Chris Pressey 2015-10-17 16:34:02 +01:00
parent 479b484313
commit b6bb64528f
3 changed files with 67 additions and 10 deletions

View File

@ -7,12 +7,13 @@ from sixtypical.model import (
) )
from sixtypical.emitter import Label, Byte from sixtypical.emitter import Label, Byte
from sixtypical.gen6502 import ( from sixtypical.gen6502 import (
Immediate, Absolute, Immediate, Absolute, Relative,
LDA, LDX, LDY, STA, STX, STY, LDA, LDX, LDY, STA, STX, STY,
CLC, SEC, ADC, SBC, ROL, ROR, CLC, SEC, ADC, SBC, ROL, ROR,
RTS, JSR,
INC, INX, INY, DEC, DEX, DEY, INC, INX, INY, DEC, DEX, DEY,
CMP, CPX, CPY, AND, ORA, EOR, CMP, CPX, CPY, AND, ORA, EOR,
BCC, BNE,
JMP, JSR, RTS,
) )
@ -58,10 +59,8 @@ class Compiler(object):
def compile_block(self, block): def compile_block(self, block):
assert isinstance(block, Block) assert isinstance(block, Block)
label = self.emitter.make_label()
for instr in block.instrs: for instr in block.instrs:
self.compile_instr(instr) self.compile_instr(instr)
return label
def compile_instr(self, instr): def compile_instr(self, instr):
assert isinstance(instr, Instr) assert isinstance(instr, Instr)
@ -168,6 +167,22 @@ class Compiler(object):
label = self.labels[instr.name] label = self.labels[instr.name]
self.emitter.emit(JSR(Absolute(label))) self.emitter.emit(JSR(Absolute(label)))
elif opcode == 'if': elif opcode == 'if':
raise NotImplementedError cls = {
'c': BCC,
'z': BNE,
}.get(src.name)
if cls is None:
raise UnsupportedOpcodeError(instr)
else_label = Label('else_label')
self.emitter.emit(cls(Relative(else_label)))
self.compile_block(instr.block1)
if instr.block2:
end_label = Label('end_label')
self.emitter.emit(JMP(Absolute(end_label)))
self.emitter.resolve_label(else_label)
self.compile_block(instr.block2)
self.emitter.resolve_label(end_label)
else:
self.emitter.resolve_label(else_label)
else: else:
raise NotImplementedError raise NotImplementedError

View File

@ -8,6 +8,9 @@ class AddressingMode(object):
"""Size of the operand for the mode (not including the opcode)""" """Size of the operand for the mode (not including the opcode)"""
raise NotImplementedError raise NotImplementedError
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.value)
class Implied(AddressingMode): class Implied(AddressingMode):
def size(self): def size(self):
@ -31,9 +34,6 @@ class Immediate(AddressingMode):
def serialize(self): def serialize(self):
return self.value.serialize() return self.value.serialize()
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.value)
class Absolute(AddressingMode): class Absolute(AddressingMode):
def __init__(self, value): def __init__(self, value):
@ -46,8 +46,18 @@ class Absolute(AddressingMode):
def serialize(self): def serialize(self):
return self.value.serialize() return self.value.serialize()
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.value) class Relative(AddressingMode):
def __init__(self, value):
assert isinstance(value, (Byte, Label))
self.value = value
def size(self):
return 1
def serialize(self):
# HA
return chr(0xff)
class Opcode(Emittable): class Opcode(Emittable):
@ -81,6 +91,18 @@ class AND(Opcode):
} }
class BCC(Opcode):
opcodes = {
Relative: 0x90,
}
class BNE(Opcode):
opcodes = {
Relative: 0xd0,
}
class CLC(Opcode): class CLC(Opcode):
opcodes = { opcodes = {
Implied: 0x18 Implied: 0x18
@ -151,6 +173,12 @@ class INY(Opcode):
} }
class JMP(Opcode):
opcodes = {
Absolute: 0x4c,
}
class JSR(Opcode): class JSR(Opcode):
opcodes = { opcodes = {
Absolute: 0x20, Absolute: 0x20,

View File

@ -118,3 +118,17 @@ Some instructions.
| shr a | shr a
| } | }
= 00c0a900a200a0008d46c08e46c08c46c0381869016d46c0e901ed46c0ee46c0e8c8ce46c0ca8829ff2d46c009ff0d46c049ff4d46c0c901cd46c0e001ec46c0c001cc46c02a6a60 = 00c0a900a200a0008d46c08e46c08c46c0381869016d46c0e901ed46c0ee46c0e8c8ce46c0ca8829ff2d46c009ff0d46c049ff4d46c0c901cd46c0e001ec46c0c001cc46c02a6a60
Compiling `if`.
| routine main
| trashes a, x, y, z, n, c, v
| {
| ld a, 0
| if z {
| ld y, 1
| } else {
| ld y, 2
| }
| }
= 00c0