mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-11-25 23:49:17 +00:00
Spec and syntax for vectors and copy instruction.
This commit is contained in:
parent
ab1b5990e7
commit
c98e446583
@ -51,3 +51,4 @@ At some point...
|
||||
* 6502-mnemonic aliases (`sec`, `clc`)
|
||||
* other handy aliases (`eq` for `z`, etc.)
|
||||
* add absolute addressing in shl/shr, absolute-indexed for add, sub, etc.
|
||||
* check and disallow recursion.
|
||||
|
@ -1,7 +1,7 @@
|
||||
SixtyPical
|
||||
==========
|
||||
|
||||
This document describes the SixtyPical programming language version 0.5,
|
||||
This document describes the SixtyPical programming language version 0.6-PRE,
|
||||
both its execution aspect and its static analysis aspect (even though
|
||||
these are, technically speaking, separate concepts.)
|
||||
|
||||
@ -14,11 +14,13 @@ the language.
|
||||
Types
|
||||
-----
|
||||
|
||||
There are three TYPES in SixtyPical:
|
||||
There are five TYPES in SixtyPical:
|
||||
|
||||
* bit (2 possible values)
|
||||
* byte (256 possible values)
|
||||
* byte table (256 entries, each holding a byte)
|
||||
* routine (code stored somewhere in memory, read-only)
|
||||
* vector (address of a routine)
|
||||
|
||||
Memory locations
|
||||
----------------
|
||||
@ -72,13 +74,14 @@ and two-hundred and fifty-six byte constants,
|
||||
### User-defined ###
|
||||
|
||||
There may be any number of user-defined memory locations. They are defined
|
||||
by giving the type, which must be `byte`, and the name.
|
||||
by giving the type, which must be `byte`, `byte table`, or `vector`, and the
|
||||
name.
|
||||
|
||||
byte pos
|
||||
|
||||
A location in memory may be given explicitly on a user-defined memory location.
|
||||
|
||||
byte screen @ 1024
|
||||
byte table screen @ 1024
|
||||
|
||||
Routines
|
||||
--------
|
||||
@ -326,6 +329,23 @@ To simulate a "while" loop, use an `if` internal to the block, like
|
||||
|
||||
"until" is optional, but if omitted, must be replaced with "forever".
|
||||
|
||||
### copy ###
|
||||
|
||||
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.
|
||||
|
||||
* It is illegal if dest is read-only.
|
||||
* It is illegal if dest does not occur in the WRITES lists of the current
|
||||
routine.
|
||||
* 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.
|
||||
|
||||
Grammar
|
||||
-------
|
||||
|
||||
@ -356,4 +376,5 @@ Grammar
|
||||
| "call" RoutineIdent
|
||||
| "if" ["not"] LocExpr Block ["else" Block]
|
||||
| "repeat" Block ("until" ["not"] LocExpr | "forever")
|
||||
| "copy" LocExpr "," LocExpr ["+" LocExpr]
|
||||
.
|
||||
|
@ -17,6 +17,8 @@ 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 Ref(object):
|
||||
|
@ -4,7 +4,7 @@ import re
|
||||
|
||||
from sixtypical.ast import Program, Defn, Routine, Block, Instr
|
||||
from sixtypical.model import (
|
||||
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE,
|
||||
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
|
||||
LocationRef, ConstantRef
|
||||
)
|
||||
|
||||
@ -103,7 +103,7 @@ class Parser(object):
|
||||
def program(self):
|
||||
defns = []
|
||||
routines = []
|
||||
while self.scanner.on('byte'):
|
||||
while self.scanner.on('byte') or self.scanner.on('vector'):
|
||||
defn = self.defn()
|
||||
name = defn.name
|
||||
if name in self.symbols:
|
||||
@ -115,16 +115,20 @@ class Parser(object):
|
||||
name = routine.name
|
||||
if name in self.symbols:
|
||||
raise SyntaxError(name)
|
||||
self.symbols[name] = SymEntry(routine, None)
|
||||
self.symbols[name] = SymEntry(routine, LocationRef(TYPE_ROUTINE, name))
|
||||
routines.append(routine)
|
||||
self.scanner.check_type('EOF')
|
||||
return Program(defns=defns, routines=routines)
|
||||
|
||||
def defn(self):
|
||||
type = TYPE_BYTE
|
||||
self.scanner.expect('byte')
|
||||
if self.scanner.consume('table'):
|
||||
type = TYPE_BYTE_TABLE
|
||||
if self.scanner.consume('byte'):
|
||||
type = TYPE_BYTE
|
||||
if self.scanner.consume('table'):
|
||||
type = TYPE_BYTE_TABLE
|
||||
else:
|
||||
self.scanner.expect('vector')
|
||||
type = TYPE_VECTOR
|
||||
self.scanner.check_type('identifier')
|
||||
name = self.scanner.token
|
||||
self.scanner.scan()
|
||||
@ -246,5 +250,12 @@ class Parser(object):
|
||||
self.scanner.scan()
|
||||
# TODO: check that is has been defined
|
||||
return Instr(opcode=opcode, name=name, dest=None, src=None)
|
||||
elif self.scanner.token in ("copy",):
|
||||
opcode = self.scanner.token
|
||||
self.scanner.scan()
|
||||
src = self.locexpr()
|
||||
self.scanner.expect(',')
|
||||
dest = self.locexpr()
|
||||
return Instr(opcode=opcode, dest=dest, src=src)
|
||||
else:
|
||||
raise ValueError('bad opcode "%s"' % self.scanner.token)
|
||||
|
@ -196,3 +196,15 @@ Declaring a byte table memory location.
|
||||
| st a, tab + y
|
||||
| }
|
||||
= ok
|
||||
|
||||
Declaring a vector.
|
||||
|
||||
| vector cinv
|
||||
|
|
||||
| routine foo {
|
||||
| ld a, 0
|
||||
| }
|
||||
| routine main {
|
||||
| copy foo, cinv
|
||||
| }
|
||||
= ok
|
||||
|
Loading…
Reference in New Issue
Block a user