1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-04-06 17:39:38 +00:00

Vector and routine types are constructors with constraints now.

This commit is contained in:
Chris Pressey 2015-10-19 18:18:06 +01:00
parent f0b8942aa1
commit 98524e931a
5 changed files with 60 additions and 12 deletions

View File

@ -33,7 +33,8 @@ TODO
For 0.6:
* declared `inputs` `outputs` `trashes` on the `vector` type.
* declared `inputs` `outputs` `trashes` on the `vector` type...
* we need to get these 3 things onto the type, and also onto routine types
* `goto` (tail call) a routine or a vector.
* A more involved demo for the C64 — one that sets up an interrupt.

View File

@ -2,7 +2,8 @@
from sixtypical.ast import Program, Routine, Block, Instr
from sixtypical.model import (
TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
TYPE_BYTE, TYPE_BYTE_TABLE,
RoutineType, VectorType,
ConstantRef, LocationRef,
REG_A, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
)
@ -224,7 +225,7 @@ def analyze_instr(instr, context, routines):
elif opcode == 'copy':
if src.type == dest.type:
pass
elif src.type == TYPE_ROUTINE and dest.type == TYPE_VECTOR:
elif isinstance(src.type, RoutineType) and isinstance(dest.type, VectorType):
pass
else:
raise TypeMismatchError((src, dest))

View File

@ -3,7 +3,8 @@
from sixtypical.ast import Program, Routine, Block, Instr
from sixtypical.model import (
ConstantRef, LocationRef,
TYPE_BIT, TYPE_ROUTINE, TYPE_VECTOR,
TYPE_BIT,
RoutineType, VectorType,
REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
)
from sixtypical.emitter import Byte, Label, Offset
@ -242,7 +243,8 @@ class Compiler(object):
self.compile_block(instr.block)
self.emitter.emit(CLI())
elif opcode == 'copy':
if src.type in (TYPE_ROUTINE, TYPE_VECTOR) and dest.type == TYPE_VECTOR:
if isinstance(src.type, (RoutineType, VectorType)) and \
isinstance(dest.type, VectorType):
src_label = self.labels[src.name]
dest_label = self.labels[dest.name]
self.emitter.emit(LDA(Absolute(src_label)))

View File

@ -17,8 +17,43 @@ class Type(object):
TYPE_BIT = Type('bit')
TYPE_BYTE = Type('byte')
TYPE_BYTE_TABLE = Type('byte table')
TYPE_ROUTINE = Type('routine')
TYPE_VECTOR = Type('vector') # the mem loc contains an address of a routine
class InteractionConstrainedType(Type):
"""Used for routines and vectors."""
def __init__(self, name, inputs=None, outputs=None, trashes=None):
self.name = name
self.inputs = inputs or []
self.outputs = outputs or []
self.trashes = trashes or []
def __repr__(self):
return 'RoutineType(%r, inputs=%r, outputs=%r, trashes=%r)' % (
self.name, self.inputs, self.outputs, self.trashes
)
def __eq__(self, other):
return isinstance(other, RoutineType) and (
other.name == self.name and
other.inputs == self.inputs and
other.outputs == self.outputs and
other.trashes == self.trashes
)
def __hash__(self):
return hash(self.name) ^ hash(self.inputs) ^ hash(self.outputs) ^ hash(self.trashes)
class RoutineType(InteractionConstrainedType):
"""This memory location contains the code for a routine."""
def __init__(self, **kwargs):
super(RoutineType, self).__init__('routine', **kwargs)
class VectorType(InteractionConstrainedType):
"""This memory location contains the address of a routine."""
def __init__(self, **kwargs):
super(VectorType, self).__init__('vector', **kwargs)
class Ref(object):

View File

@ -4,7 +4,8 @@ import re
from sixtypical.ast import Program, Defn, Routine, Block, Instr
from sixtypical.model import (
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE,
RoutineType, VectorType,
LocationRef, ConstantRef
)
@ -115,7 +116,13 @@ class Parser(object):
name = routine.name
if name in self.symbols:
raise SyntaxError(name)
self.symbols[name] = SymEntry(routine, LocationRef(TYPE_ROUTINE, name))
ref = LocationRef(
RoutineType(inputs=routine.inputs,
outputs=routine.outputs,
trashes=routine.trashes
), name
)
self.symbols[name] = SymEntry(routine, ref)
routines.append(routine)
self.scanner.check_type('EOF')
return Program(defns=defns, routines=routines)
@ -128,13 +135,15 @@ class Parser(object):
type = TYPE_BYTE_TABLE
else:
self.scanner.expect('vector')
type = TYPE_VECTOR
type = 'vector'
self.scanner.check_type('identifier')
name = self.scanner.token
self.scanner.scan()
(inputs, outputs, trashes) = self.constraints()
if type != TYPE_VECTOR and (inputs or outputs or trashes):
if type == 'vector':
type = VectorType(inputs=inputs, outputs=outputs, trashes=trashes)
elif inputs or outputs or trashes:
raise SyntaxError("Cannot apply constraints to non-vector type")
addr = None
@ -260,7 +269,7 @@ class Parser(object):
self.scanner.scan()
if name not in self.symbols:
raise SyntaxError('Undefined routine "%s"' % name)
if self.symbols[name].model.type != TYPE_ROUTINE:
if not isinstance(self.symbols[name].model.type, RoutineType):
raise SyntaxError('Illegal call of non-routine "%s"' % name)
return Instr(opcode=opcode, name=name, dest=None, src=None)
elif self.scanner.token in ("copy",):