mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-11-29 18:49:22 +00:00
Syntax is syntax, test it there. Register built-ins as symbols.
This commit is contained in:
parent
e1cf162a5b
commit
41432b5cb3
@ -82,8 +82,14 @@ class Parser(object):
|
|||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
self.scanner = Scanner(text)
|
self.scanner = Scanner(text)
|
||||||
self.symbols = {} # token -> SymEntry
|
self.symbols = {} # token -> SymEntry
|
||||||
|
for token in ('a', 'x', 'y'):
|
||||||
|
self.symbols[token] = SymEntry(None, LocationRef(TYPE_BYTE, token))
|
||||||
|
for token in ('c', 'z', 'n', 'v'):
|
||||||
|
self.symbols[token] = SymEntry(None, LocationRef(TYPE_BIT, token))
|
||||||
|
|
||||||
def lookup(self, name):
|
def lookup(self, name):
|
||||||
|
if name not in self.symbols:
|
||||||
|
raise SyntaxError('Undefined symbol "%s"' % name)
|
||||||
return self.symbols[name].model
|
return self.symbols[name].model
|
||||||
|
|
||||||
def program(self):
|
def program(self):
|
||||||
@ -93,14 +99,14 @@ class Parser(object):
|
|||||||
defn = self.defn()
|
defn = self.defn()
|
||||||
name = defn.name
|
name = defn.name
|
||||||
if name in self.symbols:
|
if name in self.symbols:
|
||||||
raise KeyError(name)
|
raise SyntaxError(name)
|
||||||
self.symbols[name] = SymEntry(defn, LocationRef(TYPE_BYTE, name))
|
self.symbols[name] = SymEntry(defn, LocationRef(TYPE_BYTE, name))
|
||||||
defns.append(defn)
|
defns.append(defn)
|
||||||
while self.scanner.on('routine'):
|
while self.scanner.on('routine'):
|
||||||
routine = self.routine()
|
routine = self.routine()
|
||||||
name = routine.name
|
name = routine.name
|
||||||
if name in self.symbols:
|
if name in self.symbols:
|
||||||
raise KeyError(name)
|
raise SyntaxError(name)
|
||||||
self.symbols[name] = SymEntry(routine, None)
|
self.symbols[name] = SymEntry(routine, None)
|
||||||
routines.append(routine)
|
routines.append(routine)
|
||||||
self.scanner.check_type('EOF')
|
self.scanner.check_type('EOF')
|
||||||
@ -151,15 +157,7 @@ class Parser(object):
|
|||||||
return accum
|
return accum
|
||||||
|
|
||||||
def locexpr(self):
|
def locexpr(self):
|
||||||
if self.scanner.token in ('a', 'x', 'y'):
|
if self.scanner.token in ('on', 'off'):
|
||||||
loc = LocationRef(TYPE_BYTE, self.scanner.token)
|
|
||||||
self.scanner.scan()
|
|
||||||
return loc
|
|
||||||
elif self.scanner.token in ('c', 'z', 'n', 'v'):
|
|
||||||
loc = LocationRef(TYPE_BIT, self.scanner.token)
|
|
||||||
self.scanner.scan()
|
|
||||||
return loc
|
|
||||||
elif self.scanner.token in ('on', 'off'):
|
|
||||||
loc = ConstantRef(TYPE_BIT, 1 if self.scanner.token == 'on' else 0)
|
loc = ConstantRef(TYPE_BIT, 1 if self.scanner.token == 'on' else 0)
|
||||||
self.scanner.scan()
|
self.scanner.scan()
|
||||||
return loc
|
return loc
|
||||||
|
@ -45,25 +45,6 @@ Program accesses a memory location.
|
|||||||
= y: 0
|
= y: 0
|
||||||
= z: 0
|
= z: 0
|
||||||
|
|
||||||
Can't access an undeclared memory location.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st a, lives
|
|
||||||
| }
|
|
||||||
? KeyError
|
|
||||||
|
|
||||||
Can't define two memory locations with the same name.
|
|
||||||
|
|
||||||
| byte lives
|
|
||||||
| byte lives
|
|
||||||
|
|
|
||||||
| routine main {
|
|
||||||
| ld a, 0
|
|
||||||
| st a, lives
|
|
||||||
| }
|
|
||||||
? KeyError
|
|
||||||
|
|
||||||
Add honours carry.
|
Add honours carry.
|
||||||
|
|
||||||
| routine main {
|
| routine main {
|
||||||
@ -294,28 +275,6 @@ Call routine.
|
|||||||
= y: 3
|
= y: 3
|
||||||
= z: 0
|
= z: 0
|
||||||
|
|
||||||
Can't call routine that hasn;t been defined.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| ld x, 0
|
|
||||||
| ld y, 1
|
|
||||||
| call up
|
|
||||||
| call up
|
|
||||||
| }
|
|
||||||
? KeyError
|
|
||||||
|
|
||||||
Can't define two routines with the same name.
|
|
||||||
|
|
||||||
| routine main {
|
|
||||||
| inc x
|
|
||||||
| inc y
|
|
||||||
| }
|
|
||||||
| routine main {
|
|
||||||
| ld x, 0
|
|
||||||
| ld y, 1
|
|
||||||
| }
|
|
||||||
? KeyError
|
|
||||||
|
|
||||||
If.
|
If.
|
||||||
|
|
||||||
| routine main {
|
| routine main {
|
||||||
|
@ -111,3 +111,58 @@ Extern memory locations
|
|||||||
| st a, screen
|
| st a, screen
|
||||||
| }
|
| }
|
||||||
= ok
|
= ok
|
||||||
|
|
||||||
|
Can't access an undeclared memory location.
|
||||||
|
|
||||||
|
| routine main {
|
||||||
|
| ld a, 0
|
||||||
|
| st a, lives
|
||||||
|
| }
|
||||||
|
? SyntaxError
|
||||||
|
|
||||||
|
Can't define two memory locations with the same name.
|
||||||
|
|
||||||
|
| byte lives
|
||||||
|
| byte lives
|
||||||
|
|
|
||||||
|
| routine main {
|
||||||
|
| ld a, 0
|
||||||
|
| st a, lives
|
||||||
|
| }
|
||||||
|
? SyntaxError
|
||||||
|
|
||||||
|
Can't shadow the name of a register or a flag.
|
||||||
|
|
||||||
|
| byte a
|
||||||
|
|
|
||||||
|
| routine main {
|
||||||
|
| }
|
||||||
|
? SyntaxError
|
||||||
|
|
||||||
|
| byte z
|
||||||
|
|
|
||||||
|
| routine main {
|
||||||
|
| }
|
||||||
|
? SyntaxError
|
||||||
|
|
||||||
|
> Can't call routine that hasn;t been defined.
|
||||||
|
>
|
||||||
|
> | routine main {
|
||||||
|
> | ld x, 0
|
||||||
|
> | ld y, 1
|
||||||
|
> | call up
|
||||||
|
> | call up
|
||||||
|
> | }
|
||||||
|
> ? SyntaxError
|
||||||
|
|
||||||
|
Can't define two routines with the same name.
|
||||||
|
|
||||||
|
| routine main {
|
||||||
|
| inc x
|
||||||
|
| inc y
|
||||||
|
| }
|
||||||
|
| routine main {
|
||||||
|
| ld x, 0
|
||||||
|
| ld y, 1
|
||||||
|
| }
|
||||||
|
? SyntaxError
|
||||||
|
Loading…
Reference in New Issue
Block a user