def _sema(self): """ Decorate AST with semantic actions. If sem_file != None, prints out the abstract syntax tree. """ try: self.sema = Visitor() self.sema.visit(self.ast) if not self.args.yaml and self.sem_file is not None: self.ast.show(buf=self.sem_file, showcoord=True) except AssertionError as e: error(None, e)
def test_sema(test_name, capsys): input_path, expected_path = resolve_test_files(test_name) p = UCParser(debug=False) with open(input_path) as f_in, open(expected_path) as f_ex: ast = p.parse(f_in.read()) sema = Visitor() sema.visit(ast) captured = capsys.readouterr() expect = f_ex.read() assert captured.out == expect assert captured.err == ""
def test_sema_error(test_name, capsys): input_path, expected_path = resolve_test_files(test_name) p = UCParser(debug=False) with open(input_path) as f_in, open(expected_path) as f_ex: ast = p.parse(f_in.read()) sema = Visitor() with pytest.raises(SystemExit) as sys_error: sema.visit(ast) assert sys_error.value.code == 1 captured = capsys.readouterr() expect = f_ex.read() assert captured.out == expect assert captured.err == ""
def test_code_error(test_name, capsys): input_path, expected_path = resolve_test_files(test_name) p = UCParser(debug=False) with open(input_path) as f_in, open(expected_path) as f_ex: ast = p.parse(f_in.read()) sema = Visitor() sema.visit(ast) gen = CodeGenerator(False) gen.visit(ast) gencode = gen.code vm = Interpreter(False) with pytest.raises(SystemExit) as sys_error: vm.run(gencode) captured = capsys.readouterr() assert sys_error.value.code == 1 expect = f_ex.read() assert captured.out == expect assert captured.err == ""
def speedup_points(): total_grade = 0 for test_name in name: input_path, expected_path, speedup_path = resolve_test_files(test_name) cap_stdout = io.StringIO() cap_stderr = io.StringIO() code_err = -1 with redirect_stdout(cap_stdout), redirect_stderr(cap_stderr): p = UCParser(debug=False) with open(input_path) as f_in, open(expected_path) as f_ex: ast = p.parse(f_in.read()) sema = Visitor() sema.visit(ast) gen = CodeGenerator(False) gen.visit(ast) gencode = gen.code opt = DataFlow(False) opt.visit(ast) optcode = opt.code vm = Interpreter(False) try: vm.run(optcode) except SystemExit as e: code_err = e.code expect = f_ex.read() if (cap_stdout.getvalue() != expect or cap_stderr.getvalue() != "" or len(optcode) >= len(gencode) or code_err != 0): print(test_name, 0.0) continue with open(speedup_path) as f_sp: reference = f_sp.read().split() grade = 0 optimized_instructions = int(reference[4]) if len(optcode) != 0: grade = optimized_instructions / len(optcode) grade = 1.0 if grade > 1.0 else grade print("{} {:.2f}".format(test_name, grade)) total_grade += grade print("{} {:.2f}".format("[Total]", total_grade))
# get input path input_file = args.input_file input_path = pathlib.Path(input_file) # check if file exists if not input_path.exists(): print("Input", input_path, "not found", file=sys.stderr) sys.exit(1) # set error function p = UCParser() # open file and parse it with open(input_path) as f: ast = p.parse(f.read()) sema = Visitor() sema.visit(ast) gen = CodeGenerator(False) gen.visit(ast) gencode = gen.code opt = DataFlow(create_cfg) opt.visit(ast) optcode = opt.code if print_opt_ir: print("Optimized uCIR: --------") opt.show() print("------------------------\n") speedup = len(gencode) / len(optcode)
class Compiler: """ This object encapsulates the compiler and serves as a facade interface to the 'meat' of the compiler underneath. """ def __init__(self, cl_args): self.code = None self.total_errors = 0 self.total_warnings = 0 self.args = cl_args def _parse(self): """ Parses the source code. If ast_file != None, prints out the abstract syntax tree. """ try: self.parser = UCParser() self.ast = self.parser.parse(self.code, '', False) if not self.args.yaml and self.ast_file is not None: self.ast.show(buf=self.ast_file, showcoord=True) except AssertionError as e: error(None, e) def _sema(self): """ Decorate AST with semantic actions. If sem_file != None, prints out the abstract syntax tree. """ try: self.sema = Visitor() self.sema.visit(self.ast) if not self.args.yaml and self.sem_file is not None: self.ast.show(buf=self.sem_file, showcoord=True) except AssertionError as e: error(None, e) def _codegen(self): self.gen = CodeGenerator(self.args.cfg) self.gen.visit(self.ast) self.gencode = self.gen.code if not self.args.yaml and self.ir_file is not None: self.gen.show(buf=self.ir_file) def _opt(self): self.opt = DataFlow(self.args.cfg, self.args.verbose) self.opt.visit(self.ast) self.optcode = self.opt.code if not self.args.yaml and self.opt_file is not None: self.opt.show(buf=self.opt_file) def _llvm(self): self.llvm = LLVMCodeGenerator(self.args.cfg) self.llvm.visit(self.ast) if not self.args.yaml and self.llvm_file is not None: self.llvm.save_ir(self.llvm_file) if self.run: if self.args.llvm_opt: self.llvm.execute_ir(self.args.llvm_opt, self.llvm_opt_file) else: self.llvm.execute_ir(self.args.llvm_opt, self.llvm_file) def _do_compile(self): """ Compiles the code to the given source file. """ self._parse() if not errors_reported(): self._sema() if not errors_reported(): self._codegen() if self.args.opt: self._opt() if self.args.llvm: self._llvm() def compile(self): """ Compiles the given filename """ if self.args.filename[-3:] == '.uc': filename = self.args.filename else: filename = self.args.filename + '.uc' open_files = [] self.ast_file = None if self.args.ast and not self.args.yaml: ast_filename = filename[:-3] + '.ast' sys.stderr.write("Outputting the AST to %s.\n" % ast_filename) self.ast_file = open(ast_filename, 'w') open_files.append(self.ast_file) self.sem_file = None if self.args.sem and not self.args.yaml: sem_filename = filename[:-3] + '.sem' sys.stderr.write("Outputting the sem to %s.\n" % sem_filename) self.sem_file = open(sem_filename, 'w') open_files.append(self.sem_file) self.ir_file = None if self.args.ir and not self.args.yaml: ir_filename = filename[:-3] + '.ir' sys.stderr.write("Outputting the uCIR to %s.\n" % ir_filename) self.ir_file = open(ir_filename, 'w') open_files.append(self.ir_file) self.opt_file = None if self.args.opt and not self.args.yaml: opt_filename = filename[:-3] + '.opt' sys.stderr.write("Outputting the optimized uCIR to %s.\n" % opt_filename) self.opt_file = open(opt_filename, 'w') open_files.append(self.opt_file) self.llvm_file = None if self.args.llvm and not self.args.yaml: llvm_filename = filename[:-3] + '.ll' sys.stderr.write("Outputting the LLVM IR to %s.\n" % llvm_filename) self.llvm_file = open(llvm_filename, 'w') open_files.append(self.llvm_file) self.llvm_opt_file = None if self.args.llvm_opt and not self.args.yaml: llvm_opt_filename = filename[:-3] + '.opt.ll' sys.stderr.write("Outputting the optimized LLVM IR to %s.\n" % llvm_opt_filename) self.llvm_opt_file = open(llvm_opt_filename, 'w') open_files.append(self.llvm_opt_file) source = open(filename, 'r') self.code = source.read() source.close() self.run = not self.args.no_run if self.args.verbose: sys.stderr.write("Compiling {}:\n".format(filename)) with subscribe_errors(lambda msg: sys.stderr.write(msg + "\n")): self._do_compile() if errors_reported(): sys.stderr.write("{} error(s) encountered.".format( errors_reported())) elif not self.args.llvm: if self.args.opt: speedup = len(self.gencode) / len(self.optcode) sys.stderr.write( "default = %d, optimized = %d, speedup = %.2f\n" % (len(self.gencode), len(self.optcode), speedup)) if self.run and not self.args.cfg: vm = Interpreter(self.args.idb) if self.args.opt: vm.run(self.optcode) else: vm.run(self.gencode) for f in open_files: f.close() return 0