1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-25 23:49:17 +00:00

Beginning of: buffers and pointers.

This commit is contained in:
Chris Pressey 2017-11-24 11:30:20 +00:00
parent ff5d635307
commit 42438dd97f
5 changed files with 66 additions and 19 deletions

View File

@ -26,7 +26,7 @@ There is also one *type constructor*:
* X table (256 entries, each holding a value of type X)
This constructor can only be applied to bytes or words.
This constructor can only be applied to one type, `byte`.
Memory locations
----------------

View File

@ -58,6 +58,17 @@ class VectorType(ExecutableType):
super(VectorType, self).__init__('vector', **kwargs)
class BufferType(Type):
def __init__(self, size):
self.size = size
self.name = 'buffer[%s]' % self.size
class PointerType(Type):
def __init__(self):
self.name = 'pointer'
class Ref(object):
def is_constant(self):
"""read-only means that the program cannot change the value

View File

@ -3,7 +3,7 @@
from sixtypical.ast import Program, Defn, Routine, Block, Instr
from sixtypical.model import (
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_WORD, TYPE_WORD_TABLE,
RoutineType, VectorType, ExecutableType,
RoutineType, VectorType, ExecutableType, BufferType, PointerType,
LocationRef, ConstantRef
)
from sixtypical.scanner import Scanner
@ -32,7 +32,7 @@ class Parser(object):
def program(self):
defns = []
routines = []
while self.scanner.on('byte', 'word', 'vector'):
while self.scanner.on('byte', 'word', 'vector', 'buffer', 'pointer'):
defn = self.defn()
name = defn.name
if name in self.symbols:
@ -50,25 +50,15 @@ class Parser(object):
return Program(defns=defns, routines=routines)
def defn(self):
type = None
if self.scanner.consume('byte'):
type = TYPE_BYTE
if self.scanner.consume('table'):
type = TYPE_BYTE_TABLE
elif self.scanner.consume('word'):
type = TYPE_WORD
if self.scanner.consume('table'):
type = TYPE_WORD_TABLE
else:
self.scanner.expect('vector')
type = 'vector' # will be resolved to a Type below
type_ = self.defn_type()
self.scanner.check_type('identifier')
name = self.scanner.token
self.scanner.scan()
(inputs, outputs, trashes) = self.constraints()
if type == 'vector':
type = VectorType(inputs=inputs, outputs=outputs, trashes=trashes)
if type_ == 'vector':
type_ = VectorType(inputs=inputs, outputs=outputs, trashes=trashes)
elif inputs or outputs or trashes:
raise SyntaxError("Cannot apply constraints to non-vector type")
@ -87,10 +77,32 @@ class Parser(object):
if initial is not None and addr is not None:
raise SyntaxError("Definition cannot have both initial value and explicit address")
location = LocationRef(type, name)
location = LocationRef(type_, name)
return Defn(name=name, addr=addr, initial=initial, location=location)
def defn_type(self):
if self.scanner.consume('byte'):
if self.scanner.consume('table'):
return TYPE_BYTE_TABLE
return TYPE_BYTE
elif self.scanner.consume('word'):
if self.scanner.consume('table'):
return TYPE_WORD_TABLE
return TYPE_WORD
elif self.scanner.consume('vector'):
return 'vector' # will be resolved to a Type by caller
elif self.scanner.consume('buffer'):
self.scanner.expect('[')
self.scanner.check_type('integer literal')
size = int(self.scanner.token)
self.scanner.scan()
self.scanner.expect(']')
return BufferType(size)
else:
self.scanner.expect('pointer')
return PointerType()
def constraints(self):
inputs = set()
outputs = set()

View File

@ -29,7 +29,7 @@ class Scanner(object):
self.token = None
self.type = 'EOF'
return
if self.scan_pattern(r'\,|\@|\+|\:|\<|\>|\{|\}', 'operator'):
if self.scan_pattern(r'\,|\@|\+|\:|\<|\>|\{|\}|\[|\]', 'operator'):
return
if self.scan_pattern(r'\d+', 'integer literal'):
return

View File

@ -123,6 +123,30 @@ Repeat with not
| }
= ok
User-defined memory addresses of different types.
| byte byt
| word wor
| vector vec
| byte table tab
|
| routine main {
| }
= ok
Buffer and pointer types.
| byte byt
| word wor
| vector vec
| byte table tab
| buffer[2048] buf
| pointer ptr
|
| routine main {
| }
= ok
Explicit memory address.
| byte screen @ 1024