First cut at building fallthru map. Needs tests.
Chris Pressey
4 years ago
56 | 56 |
|
57 | 57 |
analyzer = Analyzer(debug=options.debug)
|
58 | 58 |
analyzer.analyze_program(program)
|
|
59 |
|
|
60 |
if options.dump_fallthru_map:
|
|
61 |
import json
|
|
62 |
sys.stdout.write(json.dumps(program.fallthru_map, indent=4, sort_keys=True))
|
|
63 |
sys.stdout.write("\n")
|
59 | 64 |
|
60 | 65 |
if options.analyze_only:
|
61 | 66 |
return
|
|
120 | 125 |
'filenames', metavar='FILENAME', type=str, nargs='+',
|
121 | 126 |
help="The SixtyPical source files to compile."
|
122 | 127 |
)
|
123 | |
argparser.add_argument(
|
124 | |
"--analyze-only",
|
125 | |
action="store_true",
|
126 | |
help="Only parse and analyze the program; do not compile it."
|
127 | |
)
|
|
128 |
|
128 | 129 |
argparser.add_argument(
|
129 | 130 |
"--origin", type=str, default='0xc000',
|
130 | 131 |
help="Location in memory where the `main` routine will be "
|
|
142 | 143 |
"Also sets the origin and format. "
|
143 | 144 |
"Options are: c64, vic20, atari2600."
|
144 | 145 |
)
|
|
146 |
|
145 | 147 |
argparser.add_argument(
|
146 | |
"--debug",
|
|
148 |
"--analyze-only",
|
147 | 149 |
action="store_true",
|
148 | |
help="Display debugging information when analyzing and compiling."
|
|
150 |
help="Only parse and analyze the program; do not compile it."
|
|
151 |
)
|
|
152 |
argparser.add_argument(
|
|
153 |
"--dump-fallthru-map",
|
|
154 |
action="store_true",
|
|
155 |
help="Dump the fallthru map to stdout after analyzing the program."
|
149 | 156 |
)
|
150 | 157 |
argparser.add_argument(
|
151 | 158 |
"--parse-only",
|
152 | 159 |
action="store_true",
|
153 | 160 |
help="Only parse the program; do not analyze or compile it."
|
|
161 |
)
|
|
162 |
argparser.add_argument(
|
|
163 |
"--debug",
|
|
164 |
action="store_true",
|
|
165 |
help="Display debugging information when analyzing and compiling."
|
154 | 166 |
)
|
155 | 167 |
argparser.add_argument(
|
156 | 168 |
"--traceback",
|
309 | 309 |
def analyze_program(self, program):
|
310 | 310 |
assert isinstance(program, Program)
|
311 | 311 |
self.routines = {r.location: r for r in program.routines}
|
|
312 |
fallthru_map = {}
|
312 | 313 |
for routine in program.routines:
|
313 | |
self.analyze_routine(routine)
|
|
314 |
context = self.analyze_routine(routine)
|
|
315 |
if context:
|
|
316 |
for encountered_goto in context.encountered_gotos():
|
|
317 |
fallthru_map.setdefault(encountered_goto.name, set()).add(routine.name)
|
|
318 |
program.fallthru_map = dict([(k, list(v)) for k, v in fallthru_map.iteritems()])
|
314 | 319 |
|
315 | 320 |
def analyze_routine(self, routine):
|
316 | 321 |
assert isinstance(routine, Routine)
|
|
352 | 357 |
if ref not in type_.outputs and ref not in type_.trashes and not routine_has_static(routine, ref):
|
353 | 358 |
raise ForbiddenWriteError(routine, ref.name)
|
354 | 359 |
self.current_routine = None
|
|
360 |
return context
|
355 | 361 |
|
356 | 362 |
def analyze_block(self, block, context):
|
357 | 363 |
assert isinstance(block, Block)
|