Skip to content

Commit 755a579

Browse files
author
Jeremy Siek
committed
new utils
1 parent 80415bf commit 755a579

File tree

1 file changed

+136
-15
lines changed

1 file changed

+136
-15
lines changed

utils.py

Lines changed: 136 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
import sys
33
from sys import platform
4+
import ast
45
from ast import *
56

67
################################################################################
@@ -9,6 +10,8 @@
910

1011
indent_amount = 0
1112

13+
sed = 'sed'
14+
1215
def indent_stmt():
1316
return " " * indent_amount
1417

@@ -232,6 +235,29 @@ def repr_Subscript(self):
232235
Subscript.__repr__ = repr_Subscript
233236

234237

238+
def str_FunctionDef(self):
239+
if isinstance(self.args, ast.arguments):
240+
params = ','.join([a.arg + ':' + str(a.annotation) for a in self.args.args])
241+
else:
242+
params = ','.join([x + ':' + str(t) for (x,t) in self.args])
243+
indent()
244+
if isinstance(self.body, list):
245+
body = ''.join([str(s) for s in self.body])
246+
elif isinstance(self.body, dict):
247+
body = ''
248+
for (l,ss) in self.body.items():
249+
body += l + ':\n'
250+
indent()
251+
body += ''.join([str(s) for s in ss])
252+
dedent()
253+
dedent()
254+
return indent_stmt() + 'def ' + self.name + '(' + params + '):\n' + body
255+
def repr_FunctionDef(self):
256+
return 'FunctionDef(' + self.name + ',' + repr(self.args) + ',' + \
257+
repr(self.body) + ')'
258+
FunctionDef.__str__ = str_FunctionDef
259+
FunctionDef.__repr__ = repr_FunctionDef
260+
235261
################################################################################
236262
# __eq__ and __hash__ for classes in the ast module
237263
################################################################################
@@ -300,6 +326,17 @@ def __str__(self):
300326

301327
def __repr__(self):
302328
return 'CProgram(' + repr(self.body) + ')'
329+
330+
class CProgramDefs:
331+
__match_args__ = ("defs",)
332+
def __init__(self, defs):
333+
self.defs = defs
334+
335+
def __str__(self):
336+
return '\n'.join([str(d) for d in self.defs]) + '\n'
337+
338+
def __repr__(self):
339+
return 'CProgramDefs(' + repr(self.defs) + ')'
303340

304341
class Goto(stmt):
305342
__match_args__ = ("label",)
@@ -352,16 +389,54 @@ def __str__(self):
352389
def __repr__(self):
353390
return 'GlobalValue(' + repr(self.name) + ')'
354391

392+
class Bottom:
393+
def __eq__(self, other):
394+
return isinstance(other, Bottom)
395+
355396
class TupleType:
356397
__match_args__ = ("types",)
357398
def __init__(self, types):
358399
self.types = types
359400
def __str__(self):
360-
return 'tuple' + str(self.types)
401+
return '(' + ','.join([str(p) for p in self.types]) + ')'
361402
def __repr__(self):
362403
return 'TupleType(' + repr(self.types) + ')'
404+
def __eq__(self, other):
405+
if not isinstance(other, TupleType):
406+
return False
407+
result = True
408+
for (t1, t2) in zip(self.types, other.types):
409+
result = result and t1 == t2
410+
return result
411+
412+
class FunctionType:
413+
__match_args__ = ("param_types", "ret_type")
414+
def __init__(self, param_types, ret_type):
415+
self.param_types = param_types
416+
self.ret_type = ret_type
417+
def __str__(self):
418+
return '(' + ','.join([str(p) for p in self.param_types]) + ')' \
419+
+ ' -> ' + str(self.ret_type)
420+
def __repr__(self):
421+
return 'FunctionType(' + repr(self.param_types) + ',' \
422+
+ repr(self.ret_type) + ')'
423+
def __eq__(self, other):
424+
if not isinstance(other, FunctionType):
425+
return False
426+
result = True
427+
for (t1, t2) in zip(self.param_types, other.param_types):
428+
result = result and t1 == t2
429+
return result and self.ret_type == other.ret_type
430+
431+
class FunRef:
432+
__match_args__ = ("name",)
433+
def __init__(self, name):
434+
self.name = name
435+
def __str__(self):
436+
return self.name + '(%rip)'
437+
def __repr__(self):
438+
return 'FunRef(' + self.name + ')'
363439

364-
365440
################################################################################
366441
# Miscellaneous Auxiliary Functions
367442
################################################################################
@@ -425,8 +500,8 @@ def test_pass(passname, interp, program_root, ast,
425500
interp(ast)
426501
sys.stdin = stdin
427502
sys.stdout = stdout
428-
os.system("sed -i '$a\\' " + program_root + '.out')
429-
os.system("sed -i '$a\\' " + program_root + '.golden')
503+
os.system(sed + " -i '$a\\' " + program_root + '.out')
504+
os.system(sed + " -i '$a\\' " + program_root + '.golden')
430505
result = os.system('diff ' + output_file + ' ' + program_root + '.golden')
431506
if result == 0:
432507
trace('compiler ' + compiler_name + ' success on pass ' + passname \
@@ -438,7 +513,9 @@ def test_pass(passname, interp, program_root, ast,
438513
return 0
439514

440515

441-
def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
516+
def compile_and_test(compiler, compiler_name,
517+
type_check_P, interp_P,
518+
type_check_C, interp_C,
442519
program_filename):
443520
total_passes = 0
444521
successful_passes = 0
@@ -448,7 +525,11 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
448525
with open(program_filename) as source:
449526
program = parse(source.read())
450527

451-
trace('\n**********\n type check \n**********\n')
528+
trace('\n***************\n source program \n***************\n')
529+
trace(program)
530+
trace('')
531+
532+
trace('\n***************\n type check \n***************\n')
452533
type_check_P(program)
453534

454535
if hasattr(compiler, 'shrink'):
@@ -459,6 +540,26 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
459540
total_passes += 1
460541
successful_passes += \
461542
test_pass('shrink', interp_P, program_root, program, compiler_name)
543+
544+
if hasattr(compiler, 'reveal_functions'):
545+
trace('\n**********\n reveal functions \n**********\n')
546+
type_check_P(program)
547+
program = compiler.reveal_functions(program)
548+
trace(program)
549+
total_passes += 1
550+
successful_passes += \
551+
test_pass('reveal functions', interp_P, program_root, program,
552+
compiler_name)
553+
554+
if hasattr(compiler, 'limit_functions'):
555+
trace('\n**********\n limit functions \n**********\n')
556+
type_check_P(program)
557+
program = compiler.limit_functions(program)
558+
trace(program)
559+
total_passes += 1
560+
successful_passes += \
561+
test_pass('limit functions', interp_P, program_root, program,
562+
compiler_name)
462563

463564
if hasattr(compiler, 'expose_allocation'):
464565
trace('\n**********\n expose allocation \n**********\n')
@@ -470,7 +571,7 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
470571
test_pass('expose allocation', interp_P, program_root, program,
471572
compiler_name)
472573

473-
trace('\n**********\n remove \n**********\n')
574+
trace('\n**********\n remove complex operands \n**********\n')
474575
program = compiler.remove_complex_operands(program)
475576
trace(program)
476577
trace("")
@@ -480,13 +581,17 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
480581
compiler_name)
481582

482583
if hasattr(compiler, 'explicate_control'):
483-
trace('\n**********\n explicate \n**********\n')
584+
trace('\n**********\n explicate control \n**********\n')
484585
program = compiler.explicate_control(program)
485586
trace(program)
486587
total_passes += 1
487588
successful_passes += \
488589
test_pass('explicate control', interp_C, program_root, program,
489590
compiler_name)
591+
592+
if type_check_C:
593+
trace('\n**********\n type check C \n**********\n')
594+
type_check_C(program)
490595

491596
trace('\n**********\n select \n**********\n')
492597
pseudo_x86 = compiler.select_instructions(program)
@@ -546,8 +651,8 @@ def compile_and_test(compiler, compiler_name, type_check_P, interp_P, interp_C,
546651
output_file = program_root + '.out'
547652
os.system('./a.out < ' + input_file + ' > ' + output_file)
548653

549-
os.system("sed -i '$a\\' " + program_root + '.out')
550-
os.system("sed -i '$a\\' " + program_root + '.golden')
654+
os.system(sed + " -i '$a\\' " + program_root + '.out')
655+
os.system(sed = " -i '$a\\' " + program_root + '.golden')
551656
result = os.system('diff ' + program_root + '.out ' \
552657
+ program_root + '.golden')
553658
if result == 0:
@@ -566,7 +671,8 @@ def trace_ast_and_concrete(ast):
566671
trace(repr(ast))
567672

568673
# This function compiles the program without any testing
569-
def compile(compiler, compiler_name, type_check_P, program_filename):
674+
def compile(compiler, compiler_name, type_check_P, type_check_C,
675+
program_filename):
570676
program_root = program_filename.split('.')[0]
571677
with open(program_filename) as source:
572678
program = parse(source.read())
@@ -579,6 +685,17 @@ def compile(compiler, compiler_name, type_check_P, program_filename):
579685
trace('\n**********\n shrink \n**********\n')
580686
program = compiler.shrink(program)
581687
trace_ast_and_concrete(program)
688+
689+
if hasattr(compiler, 'reveal_functions'):
690+
trace('\n**********\n reveal functions \n**********\n')
691+
program = compiler.reveal_functions(program)
692+
trace_ast_and_concrete(program)
693+
694+
if hasattr(compiler, 'expose_allocation'):
695+
trace('\n**********\n expose allocation \n**********\n')
696+
type_check_P(program)
697+
program = compiler.expose_allocation(program)
698+
trace_ast_and_concrete(program)
582699

583700
trace('\n**********\n remove \n**********\n')
584701
program = compiler.remove_complex_operands(program)
@@ -588,6 +705,9 @@ def compile(compiler, compiler_name, type_check_P, program_filename):
588705
trace('\n**********\n explicate \n**********\n')
589706
program = compiler.explicate_control(program)
590707
trace_ast_and_concrete(program)
708+
709+
if type_check_C:
710+
type_check_C(program)
591711

592712
trace('\n**********\n select \n**********\n')
593713
pseudo_x86 = compiler.select_instructions(program)
@@ -617,18 +737,19 @@ def compile(compiler, compiler_name, type_check_P, program_filename):
617737
# checking that the resulting programs produce output that matches the
618738
# golden file.
619739
def run_one_test(test, lang, compiler, compiler_name,
620-
type_check_P, interp_P, interp_C):
740+
type_check_P, interp_P, type_check_C, interp_C):
621741
test_root = test.split('.')[0]
622742
test_name = test_root.split('/')[-1]
623743
return compile_and_test(compiler, compiler_name, type_check_P,
624-
interp_P, interp_C, test)
744+
interp_P, type_check_C, interp_C, test)
625745

626746
# Given the name of a language, a compiler, the compiler's name, a
627747
# type checker and interpreter for the language, and an interpreter
628748
# for the C intermediate language, test the compiler on all the tests
629749
# in the directory of for the given language, i.e., all the
630750
# python files in ./tests/<language>.
631-
def run_tests(lang, compiler, compiler_name, type_check_P, interp_P, interp_C):
751+
def run_tests(lang, compiler, compiler_name, type_check_P, interp_P,
752+
type_check_C, interp_C):
632753
# Collect all the test programs for this language.
633754
homedir = os.getcwd()
634755
directory = homedir + '/tests/' + lang + '/'
@@ -647,7 +768,7 @@ def run_tests(lang, compiler, compiler_name, type_check_P, interp_P, interp_C):
647768
for test in tests:
648769
(succ_passes, tot_passes, succ_test) = \
649770
run_one_test(test, lang, compiler, compiler_name,
650-
type_check_P, interp_P, interp_C)
771+
type_check_P, interp_P, type_check_C, interp_C)
651772
successful_passes += succ_passes
652773
total_passes += tot_passes
653774
successful_tests += succ_test

0 commit comments

Comments
 (0)