1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-22 17:32:01 +00:00

Do not assume every label refers to a word-sized chunk of memory.

This commit is contained in:
Chris Pressey 2017-12-11 10:42:42 +00:00
parent 404f8c72a3
commit bef1aba8ce
3 changed files with 35 additions and 10 deletions

View File

@ -3,7 +3,7 @@
from sixtypical.ast import Program, Routine, Block, Instr
from sixtypical.model import (
ConstantRef, LocationRef, IndexedRef, IndirectRef, AddressRef,
TYPE_BIT, TYPE_BYTE, TYPE_WORD, TYPE_WORD_TABLE, BufferType, PointerType, RoutineType, VectorType,
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_WORD, TYPE_WORD_TABLE, BufferType, PointerType, RoutineType, VectorType,
REG_A, REG_X, REG_Y, FLAG_C
)
from sixtypical.emitter import Byte, Label, Offset, LowAddressByte, HighAddressByte
@ -35,10 +35,22 @@ class Compiler(object):
assert isinstance(program, Program)
for defn in program.defns:
label = Label(defn.name)
if defn.addr is not None:
label.set_addr(defn.addr)
self.labels[defn.name] = label
# compute length of memory pointed to. this is awful.
length = None
type_ = defn.location.type
if type_ == TYPE_BYTE:
length = 1
elif type_ == TYPE_WORD or isinstance(type_, (PointerType, VectorType)):
length = 2
elif type_ == TYPE_BYTE_TABLE:
length = 256
elif type_ == TYPE_WORD_TABLE:
length = 512
elif isinstance(type_, BufferType):
length = type_.size
if length is None:
raise NotImplementedError("Need size for type {}".format(type_))
self.labels[defn.name] = Label(defn.name, addr=defn.addr, length=length)
for routine in program.routines:
self.routines[routine.name] = routine
@ -60,8 +72,10 @@ class Compiler(object):
for defn in program.defns:
if defn.initial is not None:
label = self.labels[defn.name]
initial_data = Byte(defn.initial) # TODO: support other types than Byte
label.set_length(initial_data.size())
self.emitter.resolve_label(label)
self.emitter.emit(Byte(defn.initial))
self.emitter.emit(initial_data)
# uninitialized, "BSS" data
for defn in program.defns:

View File

@ -1,3 +1,8 @@
"""Binary machine code emitter. Used in SixtyPical to emit 6502 machine code,
but not specific to SixtyPical, or 6502. Not even necessarily machine code -
though some parts are written around the assumptions of 8-bit architectures."""
class Emittable(object):
def size(self):
raise NotImplementedError
@ -54,13 +59,17 @@ class Table(Emittable):
class Label(Emittable):
def __init__(self, name, addr=None):
def __init__(self, name, addr=None, length=None):
self.name = name
self.addr = addr
self.length = length
def set_addr(self, addr):
self.addr = addr
def set_length(self, length):
self.length = length
def size(self):
return 2
@ -77,8 +86,9 @@ class Label(Emittable):
return Byte(self.addr + offset).serialize()
def __repr__(self):
addrs = ', addr=%r' % self.addr if self.addr is not None else ''
return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs)
addr_s = ', addr=%r' % self.addr if self.addr is not None else ''
length_s = ', length=%r' % self.length if self.length is not None else ''
return "%s(%r%s%s)" % (self.__class__.__name__, self.name, addr_s, length_s)
class Offset(Emittable):
@ -165,4 +175,4 @@ class Emitter(object):
"""Set the given label to be at the current address and
advance the address for the next label, but don't emit anything."""
self.resolve_label(label)
self.addr += label.size()
self.addr += label.length

View File

@ -1,5 +1,6 @@
"""Data/storage model for SixtyPical."""
class Type(object):
def __init__(self, name):
self.name = name