git @ Cat's Eye Technologies SixtyPical / bef1aba
Do not assume every label refers to a word-sized chunk of memory. Chris Pressey 4 years ago
3 changed file(s) with 35 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
22 from sixtypical.ast import Program, Routine, Block, Instr
33 from sixtypical.model import (
44 ConstantRef, LocationRef, IndexedRef, IndirectRef, AddressRef,
5 TYPE_BIT, TYPE_BYTE, TYPE_WORD, TYPE_WORD_TABLE, BufferType, PointerType, RoutineType, VectorType,
5 TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_WORD, TYPE_WORD_TABLE, BufferType, PointerType, RoutineType, VectorType,
66 REG_A, REG_X, REG_Y, FLAG_C
77 )
88 from sixtypical.emitter import Byte, Label, Offset, LowAddressByte, HighAddressByte
3434 assert isinstance(program, Program)
3535
3636 for defn in program.defns:
37 label = Label(defn.name)
38 if defn.addr is not None:
39 label.set_addr(defn.addr)
40 self.labels[defn.name] = label
37 # compute length of memory pointed to. this is awful.
38 length = None
39 type_ = defn.location.type
40 if type_ == TYPE_BYTE:
41 length = 1
42 elif type_ == TYPE_WORD or isinstance(type_, (PointerType, VectorType)):
43 length = 2
44 elif type_ == TYPE_BYTE_TABLE:
45 length = 256
46 elif type_ == TYPE_WORD_TABLE:
47 length = 512
48 elif isinstance(type_, BufferType):
49 length = type_.size
50 if length is None:
51 raise NotImplementedError("Need size for type {}".format(type_))
52 self.labels[defn.name] = Label(defn.name, addr=defn.addr, length=length)
4153
4254 for routine in program.routines:
4355 self.routines[routine.name] = routine
5971 for defn in program.defns:
6072 if defn.initial is not None:
6173 label = self.labels[defn.name]
74 initial_data = Byte(defn.initial) # TODO: support other types than Byte
75 label.set_length(initial_data.size())
6276 self.emitter.resolve_label(label)
63 self.emitter.emit(Byte(defn.initial))
77 self.emitter.emit(initial_data)
6478
6579 # uninitialized, "BSS" data
6680 for defn in program.defns:
0 """Binary machine code emitter. Used in SixtyPical to emit 6502 machine code,
1 but not specific to SixtyPical, or 6502. Not even necessarily machine code -
2 though some parts are written around the assumptions of 8-bit architectures."""
3
4
05 class Emittable(object):
16 def size(self):
27 raise NotImplementedError
5358
5459
5560 class Label(Emittable):
56 def __init__(self, name, addr=None):
61 def __init__(self, name, addr=None, length=None):
5762 self.name = name
5863 self.addr = addr
64 self.length = length
5965
6066 def set_addr(self, addr):
6167 self.addr = addr
68
69 def set_length(self, length):
70 self.length = length
6271
6372 def size(self):
6473 return 2
7685 return Byte(self.addr + offset).serialize()
7786
7887 def __repr__(self):
79 addrs = ', addr=%r' % self.addr if self.addr is not None else ''
80 return "%s(%r%s)" % (self.__class__.__name__, self.name, addrs)
88 addr_s = ', addr=%r' % self.addr if self.addr is not None else ''
89 length_s = ', length=%r' % self.length if self.length is not None else ''
90 return "%s(%r%s%s)" % (self.__class__.__name__, self.name, addr_s, length_s)
8191
8292
8393 class Offset(Emittable):
164174 """Set the given label to be at the current address and
165175 advance the address for the next label, but don't emit anything."""
166176 self.resolve_label(label)
167 self.addr += label.size()
177 self.addr += label.length
00 """Data/storage model for SixtyPical."""
1
12
23 class Type(object):
34 def __init__(self, name):