git @ Cat's Eye Technologies SixtyPical / cf679b2
Ability to --debug analysis. Make 16-bit addition test pass. Chris Pressey 3 years ago
4 changed file(s) with 35 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
5555
5656 if options.analyze:
5757 try:
58 analyzer = Analyzer()
58 analyzer = Analyzer(debug=options.debug)
5959 analyzer.analyze_program(program)
6060 except Exception as e:
6161 if options.traceback:
0 word score
1 routine main
2 inputs score
3 outputs score
4 trashes c, z, v, n
5 {
6 st off, c
7 add score, 1999
8 }
8787 raise InconsistentConstraintsError('%s in %s' % (ref.name, routine.name))
8888 self._writeable.add(ref)
8989
90 def __str__(self):
91 def locstr(loc):
92 if isinstance(loc, LocationRef):
93 return "{}:{}".format(loc.name, loc.type)
94 else:
95 return str(loc)
96
97 def locsetstr(s):
98 return '{' + ', '.join([locstr(loc) for loc in list(s)]) + '}'
99
100 return "Context(\n _touched={},\n _meaningful={},\n _writeable={}\n)".format(
101 locsetstr(self._touched), locsetstr(self._meaningful), locsetstr(self._writeable)
102 )
103
90104 def clone(self):
91105 c = Context(self.routines, self.routine, [], [], [])
92106 c._touched = set(self._touched)
156170
157171 class Analyzer(object):
158172
159 def __init__(self):
173 def __init__(self, debug=False):
160174 self.current_routine = None
161175 self.has_encountered_goto = False
162176 self.routines = {}
177 self.debug = debug
163178
164179 def assert_type(self, type, *locations):
165180 for location in locations:
183198 return
184199 type = routine.location.type
185200 context = Context(self.routines, routine, type.inputs, type.outputs, type.trashes)
201 if self.debug:
202 print "at start of routine `{}`:".format(routine.name)
203 print context
186204 self.analyze_block(routine.block, context)
205 if self.debug:
206 print "at end of routine `{}`:".format(routine.name)
207 print context
187208 if not self.has_encountered_goto:
188209 for ref in type.outputs:
189210 context.assert_meaningful(ref, exception_class=UnmeaningfulOutputError)
241262 self.assert_type(TYPE_WORD, src, dest)
242263 context.assert_meaningful(src, dest, FLAG_C)
243264 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
265 context.set_touched(REG_A)
244266 context.set_unmeaningful(REG_A)
245267 elif opcode == 'sub':
246268 self.assert_type(TYPE_BYTE, src, dest)
398398 | }
399399 ? UnmeaningfulOutputError: a in main
400400
401 Not sure why this doesn't also raise an error? `a` is trashed...
401 To be sure, `add`ing a word constant to a word memory location trashes `a`.
402402
403403 | word score
404404 | routine main
409409 | st off, c
410410 | add score, 1999
411411 | }
412 ? UnmeaningfulOutputError: a in main
412 ? ForbiddenWriteError: a in main
413413
414414 ### sub ###
415415