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

Allow vectors to be decorated with inputs/outputs/trashes; test.

This commit is contained in:
Chris Pressey 2015-10-19 13:04:08 +01:00
parent a12a44eadb
commit f0b8942aa1
5 changed files with 110 additions and 14 deletions

View File

@ -33,10 +33,8 @@ TODO
For 0.6:
* `interrupt` routines.
* `goto` (tail call).
* `vector` type... with declared `inputs` `outputs` `trashes`?
* `copy` instruction... that can copy a constant to a user-def mem loc.
* declared `inputs` `outputs` `trashes` on the `vector` type.
* `goto` (tail call) a routine or a vector.
* A more involved demo for the C64 — one that sets up an interrupt.
For 0.7:
@ -48,8 +46,10 @@ For 0.7:
At some point...
* `interrupt` routines.
* add line number (or at least routine name) to error messages.
* 6502-mnemonic aliases (`sec`, `clc`)
* other handy aliases (`eq` for `z`, etc.)
* have `copy` instruction able to copy a constant to a user-def mem loc, etc.
* add absolute addressing in shl/shr, absolute-indexed for add, sub, etc.
* check and disallow recursion.

View File

@ -83,6 +83,17 @@ A location in memory may be given explicitly on a user-defined memory location.
byte table screen @ 1024
A user-defined vector memory location is decorated with READS and WRITES lists
like a routine (see below), and it may only hold addresses of routines which
are compatible. (Meaning, the routine's inputs (resp. outputs, trashes)
must be a subset of the vector's inputs (resp. outputs, trashes.))
vector actor_logic
inputs a, score
outputs x
trashes y
@ $c000
Routines
--------
@ -350,10 +361,10 @@ Grammar
-------
Program ::= {Defn} {Routine}.
Defn ::= "byte" ["table"] NewIdent ["@" WordConst].
Routine ::= "routine" NewIdent
["inputs" LocExprs] ["outputs" LocExprs] ["trashes" LocExprs]
(Block | "@" WordConst).
Defn ::= Type NewIdent [Constraints] ["@" WordConst].
Type ::= "byte" ["table"] | "vector"
Constrnt::= ["inputs" LocExprs] ["outputs" LocExprs] ["trashes" LocExprs].
Routine ::= "routine" NewIdent Constraints (Block | "@" WordConst).
LocExprs::= LocExpr {"," LocExpr}.
LocExpr ::= Register | Flag | LitByte | DefnIdent.
Register::= "a" | "x" | "y".

View File

@ -132,17 +132,20 @@ class Parser(object):
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):
raise SyntaxError("Cannot apply constraints to non-vector type")
addr = None
if self.scanner.consume('@'):
self.scanner.check_type('integer literal')
addr = int(self.scanner.token)
self.scanner.scan()
return Defn(name=name, type=type, addr=addr)
return Defn(name=name, type=type, addr=addr,
inputs=inputs, outputs=outputs, trashes=trashes)
def routine(self):
self.scanner.expect('routine')
name = self.scanner.token
self.scanner.scan()
def constraints(self):
inputs = []
outputs = []
trashes = []
@ -152,6 +155,13 @@ class Parser(object):
outputs = self.locexprs()
if self.scanner.consume('trashes'):
trashes = self.locexprs()
return (inputs, outputs, trashes)
def routine(self):
self.scanner.expect('routine')
name = self.scanner.token
self.scanner.scan()
(inputs, outputs, trashes) = self.constraints()
if self.scanner.consume('@'):
self.scanner.check_type('integer literal')
block = None

View File

@ -989,7 +989,7 @@ Can't `copy` from a memory location that isn't initialized.
| }
? UninitializedAccessError: x
Can't `st` to a memory location that doesn't appear in (outputs trashes).
Can't `copy` to a memory location that doesn't appear in (outputs trashes).
| byte lives
| routine main
@ -1036,3 +1036,62 @@ a, z, and n are trashed, and must not be declared as outputs.
| copy 0, lives
| }
? UninitializedOutputError: a
Unless of course you subsequently initialize them.
| byte lives
| routine main
| outputs lives, a, z, n
| {
| copy 0, lives
| ld a, 0
| }
= ok
You can copy the address of a routine into a vector, if that vector is declared appropriately.
| vector vec
| inputs x
| outputs x
| trashes z, n
|
| routine foo
| inputs x
| outputs x
| trashes z, n
| {
| inc x
| }
|
| routine main
| inputs foo
| outputs vec
| trashes a, z, n
| {
| copy foo, vec
| }
= ok
But not if the vector is declared inappropriately.
| vector vec
| inputs y
| outputs y
| trashes z, n
|
| routine foo
| inputs x
| outputs x
| trashes z, n
| {
| inc x
| }
|
| routine main
| inputs foo
| outputs vec
| trashes a, z, n
| {
| copy foo, vec
| }
? IllegalWriteError

View File

@ -218,6 +218,10 @@ Declaring a byte table memory location.
Declaring a vector.
| vector cinv
| inputs a
| outputs x
| trashes a, x, z, n
| @ 788
|
| routine foo {
| ld a, 0
@ -228,3 +232,15 @@ Declaring a vector.
| }
| }
= ok
Only vectors can be decorated with constraints like that.
| byte cinv
| inputs a
| outputs x
| trashes a, x, z, n
| @ 788
|
| routine main {
| }
? SyntaxError