1
0
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:
Chris Pressey 2015-10-18 19:41:26 +01:00
parent ab1b5990e7
commit c98e446583
5 changed files with 57 additions and 10 deletions

View File

@ -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.

View File

@ -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]
.

View File

@ -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):

View File

@ -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)

View File

@ -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