|
7 | 7 | # repr for classes in the ast module
|
8 | 8 | ################################################################################
|
9 | 9 |
|
| 10 | +def str_Module(self): |
| 11 | + return '\n'.join([str(s) for s in self.body]) |
| 12 | +Module.__str__ = str_Module |
10 | 13 | def repr_Module(self):
|
11 |
| - return '\n'.join([repr(s) for s in self.body]) |
| 14 | + return 'Module(' + repr(self.body) + ')' |
12 | 15 | Module.__repr__ = repr_Module
|
13 | 16 |
|
| 17 | +def str_Expr(self): |
| 18 | + return str(self.value) |
| 19 | +Expr.__str__ = str_Expr |
14 | 20 | def repr_Expr(self):
|
15 |
| - return repr(self.value) |
| 21 | + return 'Expr(' + repr(self.value) + ')' |
16 | 22 | Expr.__repr__ = repr_Expr
|
17 | 23 |
|
| 24 | +def str_Assign(self): |
| 25 | + return str(self.targets[0]) + ' = ' + str(self.value) |
| 26 | +Assign.__str__ = str_Assign |
18 | 27 | def repr_Assign(self):
|
19 |
| - return repr(self.targets[0]) + ' = ' + repr(self.value) |
| 28 | + return 'Assign(' + repr(self.targets) + ', ' + repr(self.value) + ')' |
20 | 29 | Assign.__repr__ = repr_Assign
|
21 | 30 |
|
| 31 | +def str_Return(self): |
| 32 | + return 'return ' + str(self.value) |
| 33 | +Return.__str__ = str_Return |
22 | 34 | def repr_Return(self):
|
23 |
| - return 'return ' + repr(self.value) |
| 35 | + return 'Return(' + repr(self.value) + ')' |
24 | 36 | Return.__repr__ = repr_Return
|
25 | 37 |
|
26 |
| -def repr_Name(self): |
| 38 | +def str_Name(self): |
27 | 39 | return self.id
|
| 40 | +Name.__str__ = str_Name |
| 41 | +def repr_Name(self): |
| 42 | + return 'Name(' + repr(self.id) + ')' |
28 | 43 | Name.__repr__ = repr_Name
|
29 | 44 |
|
| 45 | +def str_Constant(self): |
| 46 | + return str(self.value) |
| 47 | +Constant.__str__ = str_Constant |
30 | 48 | def repr_Constant(self):
|
31 |
| - return repr(self.value) |
| 49 | + return 'Constant(' + repr(self.value) + ')' |
32 | 50 | Constant.__repr__ = repr_Constant
|
33 | 51 |
|
34 |
| -def repr_Add(self): |
| 52 | +def str_Add(self): |
35 | 53 | return '+'
|
| 54 | +Add.__str__ = str_Add |
| 55 | +def repr_Add(self): |
| 56 | + return 'Add()' |
36 | 57 | Add.__repr__ = repr_Add
|
37 | 58 |
|
38 |
| -def repr_And(self): |
| 59 | +def str_Sub(self): |
| 60 | + return '-' |
| 61 | +Sub.__str__ = str_Sub |
| 62 | +def repr_Sub(self): |
| 63 | + return 'Sub()' |
| 64 | +Sub.__repr__ = repr_Sub |
| 65 | + |
| 66 | +def str_And(self): |
39 | 67 | return 'and'
|
| 68 | +And.__str__ = str_And |
| 69 | +def repr_And(self): |
| 70 | + return 'And()' |
40 | 71 | And.__repr__ = repr_And
|
41 | 72 |
|
42 |
| -def repr_Or(self): |
| 73 | +def str_Or(self): |
43 | 74 | return 'or'
|
| 75 | +Or.__str__ = str_Or |
| 76 | +def repr_Or(self): |
| 77 | + return 'Or()' |
44 | 78 | Or.__repr__ = repr_Or
|
45 | 79 |
|
| 80 | +def str_BinOp(self): |
| 81 | + return str(self.left) + ' ' + str(self.op) + ' ' + str(self.right) |
| 82 | +BinOp.__str__ = str_BinOp |
46 | 83 | def repr_BinOp(self):
|
47 |
| - return repr(self.left) + ' ' + repr(self.op) + ' ' + repr(self.right) |
| 84 | + return 'BinOp(' + repr(self.left) + ', ' + repr(self.op) + ', ' + repr(self.right) + ')' |
48 | 85 | BinOp.__repr__ = repr_BinOp
|
49 | 86 |
|
50 | 87 | def repr_BoolOp(self):
|
51 | 88 | return repr(self.values[0]) + ' ' + repr(self.op) + ' ' + repr(self.values[1])
|
52 | 89 | BoolOp.__repr__ = repr_BoolOp
|
53 | 90 |
|
54 |
| -def repr_USub(self): |
| 91 | +def str_USub(self): |
55 | 92 | return '-'
|
| 93 | +USub.__str__ = str_USub |
| 94 | +def repr_USub(self): |
| 95 | + return 'USub()' |
56 | 96 | USub.__repr__ = repr_USub
|
57 | 97 |
|
58 |
| -def repr_Not(self): |
| 98 | +def str_Not(self): |
59 | 99 | return 'not'
|
| 100 | +Not.__str__ = str_Not |
| 101 | +def repr_Not(self): |
| 102 | + return 'Not()' |
60 | 103 | Not.__repr__ = repr_Not
|
61 | 104 |
|
| 105 | +def str_UnaryOp(self): |
| 106 | + return str(self.op) + ' ' + str(self.operand) |
| 107 | +UnaryOp.__str__ = str_UnaryOp |
62 | 108 | def repr_UnaryOp(self):
|
63 |
| - return repr(self.op) + ' ' + repr(self.operand) |
| 109 | + return 'UnaryOp(' + repr(self.op) + ', ' + repr(self.operand) + ')' |
64 | 110 | UnaryOp.__repr__ = repr_UnaryOp
|
65 | 111 |
|
| 112 | +def str_Call(self): |
| 113 | + return str(self.func) \ |
| 114 | + + '(' + ', '.join([str(arg) for arg in self.args]) + ')' |
| 115 | +Call.__str__ = str_Call |
66 | 116 | def repr_Call(self):
|
67 |
| - return repr(self.func) \ |
68 |
| - + '(' + ', '.join([repr(arg) for arg in self.args]) + ')' |
| 117 | + return 'Call(' + repr(self.func) + ', ' + repr(self.args) + ')' |
69 | 118 | Call.__repr__ = repr_Call
|
70 | 119 |
|
71 |
| -def repr_If(self): |
72 |
| - return 'if ' + repr(self.test) + ':\n' \ |
73 |
| - + '\n'.join([repr(s) for s in self.body]) + '\n' \ |
| 120 | +def str_If(self): |
| 121 | + return 'if ' + str(self.test) + ':\n' \ |
| 122 | + + ' ' + '\n '.join([str(s) for s in self.body]) + '\n' \ |
74 | 123 | + 'else:\n' \
|
75 |
| - + '\n'.join([repr(s) for s in self.orelse]) + '\n' |
| 124 | + + ' ' + '\n '.join([str(s) for s in self.orelse]) + '\n' |
| 125 | +If.__str__ = str_If |
| 126 | +def repr_If(self): |
| 127 | + return 'If(' + repr(self.test) + ', ' + repr(self.body) + ', ' + repr(self.orelse) + ')' |
76 | 128 | If.__repr__ = repr_If
|
77 | 129 |
|
| 130 | +def str_IfExp(self): |
| 131 | + return '(' + str(self.body) + ' if ' + str(self.test) + \ |
| 132 | + ' else ' + str(self.orelse) + ')' |
| 133 | +IfExp.__str__ = str_IfExp |
78 | 134 | def repr_IfExp(self):
|
79 |
| - return '(' + repr(self.body) + ' if ' + repr(self.test) + \ |
80 |
| - ' else ' + repr(self.orelse) + ')' |
| 135 | + return 'IfExp(' + repr(self.body) + ', ' + repr(self.test) + ', ' + repr(self.orelse) + ')' |
81 | 136 | IfExp.__repr__ = repr_IfExp
|
82 | 137 |
|
| 138 | +def str_While(self): |
| 139 | + return 'while ' + str(self.test) + ':\n' \ |
| 140 | + + ' ' + '\n '.join([str(s) for s in self.body]) + '\n' |
| 141 | +While.__str__ = str_While |
| 142 | +def repr_While(self): |
| 143 | + return 'While(' + repr(self.test) + ', ' + repr(self.body) + ', ' + repr(self.orelse) + ')' |
| 144 | +While.__repr__ = repr_While |
| 145 | + |
| 146 | +def str_Compare(self): |
| 147 | + return str(self.left) + ' ' + str(self.ops[0]) + ' ' + str(self.comparators[0]) |
| 148 | +Compare.__str__ = str_Compare |
83 | 149 | def repr_Compare(self):
|
84 |
| - return repr(self.left) + ' ' + repr(self.ops[0]) + ' ' + repr(self.comparators[0]) |
| 150 | + return 'Compare(' + repr(self.left) + ', ' + repr(self.ops) + ', ' \ |
| 151 | + + repr(self.comparators) + ')' |
85 | 152 | Compare.__repr__ = repr_Compare
|
86 | 153 |
|
87 |
| -def repr_Eq(self): |
| 154 | +def str_Eq(self): |
88 | 155 | return '=='
|
| 156 | +Eq.__str__ = str_Eq |
| 157 | +def repr_Eq(self): |
| 158 | + return 'Eq()' |
89 | 159 | Eq.__repr__ = repr_Eq
|
90 | 160 |
|
91 |
| -def repr_Lt(self): |
| 161 | +def str_NotEq(self): |
| 162 | + return '!=' |
| 163 | +NotEq.__str__ = str_NotEq |
| 164 | +def repr_NotEq(self): |
| 165 | + return 'NotEq()' |
| 166 | +NotEq.__repr__ = repr_NotEq |
| 167 | + |
| 168 | +def str_Lt(self): |
92 | 169 | return '<'
|
| 170 | +Lt.__str__ = str_Lt |
| 171 | +def repr_Lt(self): |
| 172 | + return 'Lt()' |
93 | 173 | Lt.__repr__ = repr_Lt
|
94 | 174 |
|
| 175 | +def str_LtE(self): |
| 176 | + return '<=' |
| 177 | +LtE.__str__ = str_Lt |
| 178 | +def repr_LtE(self): |
| 179 | + return 'LtE()' |
| 180 | +LtE.__repr__ = repr_LtE |
| 181 | + |
| 182 | +def str_Gt(self): |
| 183 | + return '>' |
| 184 | +Gt.__str__ = str_Gt |
| 185 | +def repr_Gt(self): |
| 186 | + return 'Gt()' |
| 187 | +Gt.__repr__ = repr_Gt |
| 188 | + |
| 189 | +def str_GtE(self): |
| 190 | + return '>=' |
| 191 | +GtE.__str__ = str_GtE |
| 192 | +def repr_GtE(self): |
| 193 | + return 'GtE()' |
| 194 | +GtE.__repr__ = repr_GtE |
| 195 | + |
95 | 196 |
|
96 | 197 | ################################################################################
|
97 | 198 | # __eq__ and __hash__ for classes in the ast module
|
@@ -147,19 +248,24 @@ class CProgram:
|
147 | 248 | def __init__(self, body):
|
148 | 249 | self.body = body
|
149 | 250 |
|
150 |
| - def __repr__(self): |
| 251 | + def __str__(self): |
151 | 252 | result = ''
|
152 | 253 | for (l,ss) in self.body.items():
|
153 | 254 | result += l + ':\n'
|
154 |
| - result += '\n'.join([repr(s) for s in ss]) + '\n\n' |
| 255 | + result += '\n'.join([str(s) for s in ss]) + '\n\n' |
155 | 256 | return result
|
| 257 | + |
| 258 | + def __repr__(self): |
| 259 | + return 'CProgram(' + repr(self.body) + ')' |
156 | 260 |
|
157 | 261 | class Goto(expr):
|
158 | 262 | __match_args__ = ("label",)
|
159 | 263 | def __init__(self, label):
|
160 | 264 | self.label = label
|
161 |
| - def __repr__(self): |
| 265 | + def __str__(self): |
162 | 266 | return 'goto ' + self.label
|
| 267 | + def __repr__(self): |
| 268 | + return 'Goto(' + repr(self.label) + ')' |
163 | 269 |
|
164 | 270 |
|
165 | 271 | ################################################################################
|
@@ -190,6 +296,10 @@ def label_name(n: str) -> str:
|
190 | 296 |
|
191 | 297 | tracing = False
|
192 | 298 |
|
| 299 | +def enable_tracing(): |
| 300 | + global tracing |
| 301 | + tracing = True |
| 302 | + |
193 | 303 | def trace(msg):
|
194 | 304 | if tracing:
|
195 | 305 | print(msg, file=sys.stderr)
|
@@ -293,10 +403,12 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
|
293 | 403 |
|
294 | 404 | trace('\n**********\n prelude and conclusion \n**********\n')
|
295 | 405 | x86 = compiler.prelude_and_conclusion(x86)
|
| 406 | + trace(x86) |
| 407 | + trace("") |
296 | 408 |
|
297 | 409 | x86_filename = program_root + ".s"
|
298 | 410 | with open(x86_filename, "w") as dest:
|
299 |
| - dest.write(repr(x86)) |
| 411 | + dest.write(str(x86)) |
300 | 412 |
|
301 | 413 | total_passes += 1
|
302 | 414 |
|
@@ -328,6 +440,58 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
|
328 | 440 | + ' on test ' + program_root)
|
329 | 441 | return (successful_passes, total_passes, 0)
|
330 | 442 |
|
| 443 | +def trace_ast_and_concrete(ast): |
| 444 | + trace("concrete syntax:") |
| 445 | + trace(ast) |
| 446 | + trace("") |
| 447 | + trace("AST:") |
| 448 | + trace(repr(ast)) |
| 449 | + |
| 450 | +# This function compiles the program without any testing |
| 451 | +def compile(compiler, compiler_name, type_check_P, program_filename): |
| 452 | + program_root = program_filename.split('.')[0] |
| 453 | + with open(program_filename) as source: |
| 454 | + program = parse(source.read()) |
| 455 | + |
| 456 | + trace('\n**********\n type check \n**********\n') |
| 457 | + type_check_P(program) |
| 458 | + trace_ast_and_concrete(program) |
| 459 | + |
| 460 | + if hasattr(compiler, 'shrink'): |
| 461 | + trace('\n**********\n shrink \n**********\n') |
| 462 | + program = compiler.shrink(program) |
| 463 | + trace_ast_and_concrete(program) |
| 464 | + |
| 465 | + trace('\n**********\n remove \n**********\n') |
| 466 | + rco = compiler.remove_complex_operands(program) |
| 467 | + trace_ast_and_concrete(rco) |
| 468 | + |
| 469 | + if hasattr(compiler, 'explicate_control'): |
| 470 | + trace('\n**********\n explicate \n**********\n') |
| 471 | + rco = compiler.explicate_control(rco) |
| 472 | + trace_ast_and_concrete(rco) |
| 473 | + |
| 474 | + trace('\n**********\n select \n**********\n') |
| 475 | + pseudo_x86 = compiler.select_instructions(rco) |
| 476 | + trace_ast_and_concrete(pseudo_x86) |
| 477 | + |
| 478 | + trace('\n**********\n assign \n**********\n') |
| 479 | + almost_x86 = compiler.assign_homes(pseudo_x86) |
| 480 | + trace_ast_and_concrete(almost_x86) |
| 481 | + |
| 482 | + trace('\n**********\n patch \n**********\n') |
| 483 | + x86 = compiler.patch_instructions(almost_x86) |
| 484 | + trace_ast_and_concrete(x86) |
| 485 | + |
| 486 | + trace('\n**********\n prelude and conclusion \n**********\n') |
| 487 | + x86 = compiler.prelude_and_conclusion(x86) |
| 488 | + trace_ast_and_concrete(x86) |
| 489 | + |
| 490 | + # Output x86 program to the .s file |
| 491 | + x86_filename = program_root + ".s" |
| 492 | + with open(x86_filename, "w") as dest: |
| 493 | + dest.write(str(x86)) |
| 494 | + |
331 | 495 |
|
332 | 496 | # Given a test file name, the name of a language, a compiler, a type
|
333 | 497 | # checker and interpreter for the language, and an interpeter for the
|
@@ -372,9 +536,7 @@ def run_tests(lang, compiler, compiler_name, type_check_P, interp_P, interp_C):
|
372 | 536 | total_tests += 1
|
373 | 537 |
|
374 | 538 | # Report the pass/fails
|
375 |
| - print('compiler ' + compiler_name + ' on language ' + lang \ |
376 |
| - + ' passed ' + repr(successful_tests) + '/' + repr(total_tests) \ |
377 |
| - + ' tests') |
378 |
| - print('compiler ' + compiler_name + ' on language ' + lang \ |
379 |
| - + ' passed ' + repr(successful_passes) + '/' + repr(total_passes) \ |
380 |
| - + ' passes') |
| 539 | + print('tests: ' + repr(successful_tests) + '/' + repr(total_tests) \ |
| 540 | + + ' for compiler ' + compiler_name + ' on language ' + lang) |
| 541 | + print('passes: ' + repr(successful_passes) + '/' + repr(total_passes) \ |
| 542 | + + ' for compiler ' + compiler_name + ' on language ' + lang) |
0 commit comments