Пример #1
0
 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)
Пример #2
0
def test_parser_error(test_name, capsys):
    input_path, expected_path = resolve_test_files(test_name)

    p = UCParser(debug=False)
    with pytest.raises(SystemExit):
        with open(input_path) as f_in, open(expected_path) as f_ex:
            ast = p.parse(f_in.read())
            ast.show(showcoord=True)
            captured = capsys.readouterr()
            expect = f_ex.read()
        assert captured.out == expect
        assert captured.err == ""
Пример #3
0
def test_parser(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())
        # pytest fails to substitute sys.stdout if not passed here
        ast.show(buf=sys.stdout, showcoord=True)
        captured = capsys.readouterr()
        expect = f_ex.read()
    assert captured.out == expect
    assert captured.err == ""
Пример #4
0
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 == ""
Пример #5
0
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 == ""
Пример #6
0
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 == ""
Пример #7
0
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))
Пример #8
0
    speedup = args.speedup
    print_opt_ir = args.opt
    create_cfg = args.cfg
    interpreter_debug = args.debug

    # 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:
Пример #9
0
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