mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-11-25 23:49:17 +00:00
Make ld parse to a IndexedRef or IndirectRef (latter still todo.)
This commit is contained in:
parent
f87c07e52a
commit
34daad0e56
@ -1,7 +1,7 @@
|
||||
SixtyPical
|
||||
==========
|
||||
|
||||
_Version 0.11. Work-in-progress, everything is subject to change._
|
||||
_Version 0.12. Work-in-progress, everything is subject to change._
|
||||
|
||||
SixtyPical is a very low-level programming language, similar to 6502 assembly,
|
||||
with static analysis through abstract interpretation.
|
||||
|
@ -127,6 +127,9 @@ class Context(object):
|
||||
if kwargs.get('message'):
|
||||
message += ' (%s)' % kwargs['message']
|
||||
raise exception_class(message)
|
||||
elif isinstance(ref, IndexedRef):
|
||||
self.assert_meaningful(ref.ref, **kwargs)
|
||||
self.assert_meaningful(ref.index, **kwargs)
|
||||
else:
|
||||
raise NotImplementedError(ref)
|
||||
|
||||
@ -236,14 +239,16 @@ class Analyzer(object):
|
||||
src = instr.src
|
||||
|
||||
if opcode == 'ld':
|
||||
if instr.index:
|
||||
if TableType.is_a_table_type(src.type, TYPE_BYTE) and dest.type == TYPE_BYTE:
|
||||
if isinstance(src, IndexedRef):
|
||||
if TableType.is_a_table_type(src.ref.type, TYPE_BYTE) and dest.type == TYPE_BYTE:
|
||||
pass
|
||||
else:
|
||||
raise TypeMismatchError('%s and %s in %s' %
|
||||
(src.name, dest.name, self.current_routine.name)
|
||||
(src.ref.name, dest.name, self.current_routine.name)
|
||||
)
|
||||
context.assert_meaningful(instr.index)
|
||||
context.assert_meaningful(src.index)
|
||||
elif isinstance(src, IndirectRef):
|
||||
raise NotImplementedError
|
||||
elif src.type != dest.type:
|
||||
raise TypeMismatchError('%s and %s in %s' %
|
||||
(src.name, dest.name, self.current_routine.name)
|
||||
@ -352,6 +357,9 @@ class Analyzer(object):
|
||||
context.assert_meaningful(src)
|
||||
|
||||
elif opcode == 'copy':
|
||||
if dest == REG_A:
|
||||
raise ForbiddenWriteError("{} cannot be used as destination for copy".format(dest))
|
||||
|
||||
# 1. check that their types are compatible
|
||||
|
||||
if isinstance(src, AddressRef) and isinstance(dest, LocationRef):
|
||||
|
@ -131,9 +131,9 @@ class Compiler(object):
|
||||
self.emitter.emit(TYA())
|
||||
elif isinstance(src, ConstantRef):
|
||||
self.emitter.emit(LDA(Immediate(Byte(src.value))))
|
||||
elif instr.index == REG_X:
|
||||
elif isinstance(src, IndexedRef) and src.index == REG_X:
|
||||
self.emitter.emit(LDA(AbsoluteX(self.labels[src.name])))
|
||||
elif instr.index == REG_Y:
|
||||
elif isinstance(src, IndexedRef) and src.index == REG_Y:
|
||||
self.emitter.emit(LDA(AbsoluteY(self.labels[src.name])))
|
||||
else:
|
||||
self.emitter.emit(LDA(Absolute(self.labels[src.name])))
|
||||
@ -142,7 +142,7 @@ class Compiler(object):
|
||||
self.emitter.emit(TAX())
|
||||
elif isinstance(src, ConstantRef):
|
||||
self.emitter.emit(LDX(Immediate(Byte(src.value))))
|
||||
elif instr.index == REG_Y:
|
||||
elif isinstance(src, IndexedRef) and src.index == REG_Y:
|
||||
self.emitter.emit(LDX(AbsoluteY(self.labels[src.name])))
|
||||
else:
|
||||
self.emitter.emit(LDX(Absolute(self.labels[src.name])))
|
||||
@ -151,7 +151,7 @@ class Compiler(object):
|
||||
self.emitter.emit(TAY())
|
||||
elif isinstance(src, ConstantRef):
|
||||
self.emitter.emit(LDY(Immediate(Byte(src.value))))
|
||||
elif instr.index == REG_X:
|
||||
elif isinstance(src, IndexedRef) and src.index == REG_X:
|
||||
self.emitter.emit(LDY(AbsoluteX(self.labels[src.name])))
|
||||
else:
|
||||
self.emitter.emit(LDY(Absolute(self.labels[src.name])))
|
||||
|
@ -202,7 +202,8 @@ class IndexedRef(Ref):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return '{}+{}'.format(self.ref.name, self.index.name)
|
||||
return self.ref.name
|
||||
#return '{}+{}'.format(self.ref.name, self.index.name)
|
||||
|
||||
def is_constant(self):
|
||||
return False
|
||||
|
@ -316,7 +316,15 @@ class Parser(object):
|
||||
self.scanner.expect('forever')
|
||||
return Instr(opcode='repeat', dest=None, src=src,
|
||||
block=block, inverted=inverted)
|
||||
elif self.scanner.token in ("ld", "add", "sub", "cmp", "and", "or", "xor"):
|
||||
elif self.scanner.token in ("ld",):
|
||||
# the same as add, sub, cmp etc below, except supports an indlocexpr for the src
|
||||
opcode = self.scanner.token
|
||||
self.scanner.scan()
|
||||
dest = self.locexpr()
|
||||
self.scanner.expect(',')
|
||||
src = self.indlocexpr()
|
||||
return Instr(opcode=opcode, dest=dest, src=src, index=None)
|
||||
elif self.scanner.token in ("add", "sub", "cmp", "and", "or", "xor"):
|
||||
opcode = self.scanner.token
|
||||
self.scanner.scan()
|
||||
dest = self.locexpr()
|
||||
|
@ -1462,6 +1462,21 @@ Can `copy` from a `byte` to a `byte`.
|
||||
| }
|
||||
= ok
|
||||
|
||||
The understanding is that, because `copy` trashes `a`, `a` cannot be used
|
||||
as the destination of a `copy`.
|
||||
|
||||
| byte source : 0
|
||||
| byte dest
|
||||
|
|
||||
| routine main
|
||||
| inputs source
|
||||
| outputs dest
|
||||
| trashes a, z, n
|
||||
| {
|
||||
| copy source, a
|
||||
| }
|
||||
? ForbiddenWriteError
|
||||
|
||||
Can `copy` from a `word` to a `word`.
|
||||
|
||||
| word source : 0
|
||||
@ -1504,9 +1519,7 @@ Can't `copy` from a `word` to a `byte`.
|
||||
| }
|
||||
? TypeMismatchError
|
||||
|
||||
### copy[] ###
|
||||
|
||||
Buffers and pointers.
|
||||
### Buffers and pointers ###
|
||||
|
||||
Note that `^buf` is a constant value, so it by itself does not require `buf` to be
|
||||
listed in any input/output sets.
|
||||
@ -1588,6 +1601,24 @@ Read through a pointer.
|
||||
| }
|
||||
= ok
|
||||
|
||||
Read through a pointer to the `a` register. Note that
|
||||
this is done with `ld`, not `copy`.
|
||||
|
||||
| buffer[2048] buf
|
||||
| pointer ptr
|
||||
| byte foo
|
||||
|
|
||||
| routine main
|
||||
| inputs buf
|
||||
| outputs foo
|
||||
| trashes a, y, z, n, ptr
|
||||
| {
|
||||
| ld y, 0
|
||||
| copy ^buf, ptr
|
||||
| ld a, [ptr] + y
|
||||
| }
|
||||
= ok
|
||||
|
||||
### routines ###
|
||||
|
||||
Routines are constants. You need not, and in fact cannot, specify a constant
|
||||
|
@ -846,7 +846,7 @@ Read through a pointer, into a byte storage location, or the `a` register.
|
||||
| ld y, 0
|
||||
| copy ^buf, ptr
|
||||
| copy [ptr] + y, foo
|
||||
| copy [ptr] + y, a
|
||||
| ld a, [ptr] + y
|
||||
| }
|
||||
= $080D LDY #$00
|
||||
= $080F LDA #$1F
|
||||
|
Loading…
Reference in New Issue
Block a user