git @ Cat's Eye Technologies SixtyPical / b829836
Ability to parse static definitions and look them up. Chris Pressey 3 years ago
2 changed file(s) with 91 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
1717 class Parser(object):
1818 def __init__(self, text):
1919 self.scanner = Scanner(text)
20 self.symbols = {} # token -> SymEntry
21 self.typedefs = {} # token -> Type AST
20 self.symbols = {} # token -> SymEntry
21 self.current_statics = {} # token -> SymEntry
22 self.typedefs = {} # token -> Type AST
2223 for token in ('a', 'x', 'y'):
2324 self.symbols[token] = SymEntry(None, LocationRef(TYPE_BYTE, token))
2425 for token in ('c', 'z', 'n', 'v'):
2627 self.backpatch_instrs = []
2728
2829 def lookup(self, name):
30 if name in self.current_statics:
31 return self.current_statics[name].model
2932 if name not in self.symbols:
3033 raise SyntaxError('Undefined symbol "%s"' % name)
3134 return self.symbols[name].model
208211 type_ = self.defn_type()
209212 if not isinstance(type_, RoutineType):
210213 raise SyntaxError("Can only define a routine, not %r" % type_)
214 statics = []
211215 if self.scanner.consume('@'):
212216 self.scanner.check_type('integer literal')
213217 block = None
214218 addr = int(self.scanner.token)
215219 self.scanner.scan()
216220 else:
221 statics = self.statics()
222
223 self.current_statics = {}
224 for defn in statics:
225 name = defn.name
226 if name in self.symbols or name in self.current_statics:
227 raise SyntaxError('Symbol "%s" already declared' % name)
228 self.current_statics[name] = SymEntry(defn, defn.location)
217229 block = self.block()
230 self.current_statics = {}
231
218232 addr = None
219233 location = LocationRef(type_, name)
220234 return Routine(
221235 name=name, block=block, addr=addr,
222 location=location
236 location=location, statics=statics
223237 )
224238
225239 def labels(self):
282296 index = self.locexpr()
283297 loc = IndexedRef(loc, index)
284298 return loc
299
300 def statics(self):
301 defns = []
302 while self.scanner.consume('static'):
303 defn = self.defn()
304 if defn.initial is None:
305 raise SyntaxError("Static definition {} must have initial value".format(defn))
306 defns.append(defn)
307 return defns
285308
286309 def block(self):
287310 instrs = []
528528 | ld a, 0
529529 | }
530530 ? SyntaxError
531
532 Memory locations can be defined static to a routine.
533
534 | define foo routine
535 | inputs x
536 | outputs x
537 | trashes z, n
538 | static byte t : 0
539 | {
540 | st x, t
541 | inc t
542 | ld x, t
543 | }
544 |
545 | define main routine
546 | trashes a, x, z, n
547 | static byte t : 0
548 | {
549 | ld x, t
550 | call foo
551 | }
552 = ok
553
554 Static memory locations must always be given an initial value.
555
556 | define main routine
557 | inputs x
558 | outputs x
559 | trashes z, n
560 | static byte t
561 | {
562 | st x, t
563 | inc t
564 | ld x, t
565 | }
566 ? SyntaxError
567
568 Name of a static cannot shadow an existing global or static.
569
570 | byte t
571 |
572 | define main routine
573 | inputs x
574 | outputs x
575 | trashes z, n
576 | static byte t
577 | {
578 | st x, t
579 | inc t
580 | ld x, t
581 | }
582 ? SyntaxError
583
584 | define main routine
585 | inputs x
586 | outputs x
587 | trashes z, n
588 | static byte t
589 | static byte t
590 | {
591 | st x, t
592 | inc t
593 | ld x, t
594 | }
595 ? SyntaxError