1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-01 12:41:30 +00:00

Analyze copy, but... we now need more sophisticated context. :/

This commit is contained in:
Chris Pressey 2015-10-18 20:16:14 +01:00
parent c98e446583
commit 8b30a232fa
5 changed files with 110 additions and 6 deletions

View File

@ -334,8 +334,8 @@ To simulate a "while" loop, use an `if` internal to the block, like
copy <src-memory-location>, <dest-memory-location>
Reads from src and writes to dest. Differs from `st` in that is able to
copy more general types of data (for example, vectors,) and it sets the
`z` and `n` flags and trashes the `a` register.
copy more general types of data (for example, vectors,) and it trashes the
`z` and `n` flags and the `a` register.
* It is illegal if dest is read-only.
* It is illegal if dest does not occur in the WRITES lists of the current
@ -343,8 +343,8 @@ copy more general types of data (for example, vectors,) and it sets the
* It is illegal if src is not of same type as dest.
* It is illegal if src is uninitialized.
After execution, dest is considered initialized, as are `z` and `n`, while
`a` is considered uninitialized.
After execution, dest is considered initialized, and `z` and `n`, and
`a` are considered uninitialized.
Grammar
-------

View File

@ -2,8 +2,9 @@
from sixtypical.ast import Program, Routine, Block, Instr
from sixtypical.model import (
TYPE_BYTE, TYPE_BYTE_TABLE,
ConstantRef, LocationRef, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
ConstantRef, LocationRef,
REG_A, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
)
@ -214,5 +215,16 @@ def analyze_instr(instr, context, routines):
analyze_block(instr.block, context, routines)
# NB I *think* that's enough... but it might not be?
elif opcode == 'copy':
if src.type == dest.type:
pass
elif src.type == TYPE_ROUTINE and dest.type == TYPE_VECTOR:
pass
else:
raise TypeMismatchError((src, dest))
context.assert_initialized(src)
context.assert_writeable(dest)
context.set_initialized(dest)
context.set_uninitialized(REG_A, FLAG_Z, FLAG_N)
else:
raise NotImplementedError(opcode)

View File

@ -154,5 +154,11 @@ def eval_instr(instr, context, routines):
eval_block(instr.block, context, routines)
while context.get(src) == 0:
eval_block(instr.block, context, routines)
elif opcode == 'copy':
context.set(dest, context.get(src))
# these are trashed; so could be anything really
context.set(REG_A, 0)
context.set(FLAG_Z, 0)
context.set(FLAG_N, 0)
else:
raise NotImplementedError

View File

@ -965,3 +965,74 @@ initialized at the start.
| } until z
| }
? UninitializedAccessError: y
### copy ###
Can't `copy` from a memory location that isn't initialized.
| byte lives
| routine main
| inputs x
| outputs lives
| trashes a, z, n
| {
| copy x, lives
| }
= ok
| byte lives
| routine main
| outputs lives
| trashes x, a, z, n
| {
| copy x, lives
| }
? UninitializedAccessError: x
Can't `st` to a memory location that doesn't appear in (outputs trashes).
| byte lives
| routine main
| trashes lives, a, z, n
| {
| copy 0, lives
| }
= ok
| byte lives
| routine main
| outputs lives
| trashes a, z, n
| {
| copy 0, lives
| }
= ok
| byte lives
| routine main
| inputs lives
| trashes a, z, n
| {
| copy 0, lives
| }
? IllegalWriteError: lives
a, z, and n are trashed, and must be declared as such
| byte lives
| routine main
| outputs lives
| {
| copy 0, lives
| }
? IllegalWriteError: a
a, z, and n are trashed, and must not be declared as outputs.
| byte lives
| routine main
| outputs lives, a, z, n
| {
| copy 0, lives
| }
? UninitializedOutputError: a

View File

@ -385,3 +385,18 @@ Repeat loop.
= x: 10
= y: 25
= z: 1
Copy instruction. Note that the state of a, z, and n are not defined
after copy executes.
| routine main {
| ld x, 5
| copy x, y
| }
= a: 0
= c: 0
= n: 0
= v: 0
= x: 5
= y: 5
= z: 0