예제 #1
0
    def visit(self, node, scope=None):
        scope = Scope()
        self.current_function = self.register_function('main')
        instance = self.define_internal_local(scope=scope, name="instance")
        result = self.define_internal_local(scope=scope, name="result")
        self.register_instruction(CIL_AST.Allocate('Main', self.context.get_type('Main').tag, instance))
        self.register_instruction(CIL_AST.Call(result, 'Main_init', [CIL_AST.Arg(instance)], "Main"))
        self.register_instruction(
            CIL_AST.Call(result, self.to_function_name('main', 'Main'), [CIL_AST.Arg(instance)], "Main"))
        self.register_instruction(CIL_AST.Return(None))
        self.current_function = None

        self.register_data('Abort called from class ')
        self.register_data('\n')
        self.dotdata['empty_str'] = ''

        # Add built-in types in .TYPES section
        self.register_builtin_types(scope)

        # Add string equals function
        self.build_string_equals_function(scope)

        for klass in node.declarations:
            self.visit(klass, scope.create_child())

        return CIL_AST.Program(self.dottypes, self.dotdata, self.dotcode)
예제 #2
0
def test_execution(program_file: str, debug: bool = False):
    program = read_file(program_file)

    context = Context()
    errors = []

    ast = parse(program, debug)
    if ast is None:
        # error en el lexer o en el parser
        #
        errors.append('Syntactic Errors')
    else:
        TypeCollector(context, errors).visit(ast)
        TypeBuilder(context, errors).visit(ast)
        # CyclicDependency(context, errors)
        if not errors:
            InferenceTypeChecker(context, errors).visit(ast, Scope())
            print(CodeBuilder().visit(ast, 0))
            Execution(context).visit(ast, Scope())
        else:
            print('\n'.join(errors))
예제 #3
0
    def visit(self, node, scope):
        token = self.visit(node.obj, scope)

        if isinstance(token, VoidPod):
            raise RuntimeException(
                'Reference to an instance of a void object.')

        _o = self.context.get_type('Object')
        _s = self.context.get_type('String')
        _io = self.context.get_type('IO')

        if token.type.conforms_to(_o) and (_o.name,
                                           node.method) in cl_baseline:
            args = (token, ) + tuple(
                self.visit(arg, scope) for arg in node.args) + (self.context, )
            return cl_baseline[_o.name, node.method](*args)

        if token.type.conforms_to(_s) and (_s.name,
                                           node.method) in cl_baseline:
            args = (token, ) + tuple(
                self.visit(arg, scope) for arg in node.args) + (self.context, )
            return cl_baseline[_s.name, node.method](*args)

        if token.type.conforms_to(_io) and (_io.name,
                                            node.method) in cl_baseline:
            args = (token, ) + tuple(
                self.visit(arg, scope) for arg in node.args) + (self.context, )
            return cl_baseline[_io.name, node.method](*args)

        #si es una instantiate.f() meter en el scope hijo todos sus atributos
        _funcCall_scope = Scope()
        #para el caso [email protected]()
        if not node.parent is None:
            parent_t = self.context.get_type(node.parent)
            method = parent_t.get_method(node.method, parent_t, False)
        else:
            method = token.get_method(node.method, self.currentType, False)

        for _id, _t, _arg in zip(method.param_names, method.param_types,
                                 node.args):
            _funcCall_scope.define_variable(_id, _t).token = self.visit(
                _arg, scope)

        _funcCall_scope.define_variable('self', token.type).token = token

        self.stack.append(self.currentPod)
        self.currentPod = token

        result = self.visit(method.expr, _funcCall_scope)

        self.currentPod = self.stack.pop()
        return result
예제 #4
0
 def __init__(self, program, lexer, parser, verbose=False):
     self.context: Context = Context()
     self.scope: Scope = Scope()
     self.program = program
     self.parser = parser
     self.lexer = lexer
     self.ast = self.parser.parse(self.lexer, self.program)
     self.errors = self.lexer.errors + self.parser.errors
     
     if len(self.errors) != 0:
         return
     
     if self.ast is None:
         return
             
     self.depicter = Depicter()
     if verbose:
         print(self.depicter.visit(self.ast, 0), '\n')
         print()
     
     self.typeCollector = TypeCollector(self.context, self.errors)
     self.typeCollector.visit(self.ast)
     if len(self.errors) == 0:
         self.typeBuilder = TypeBuilder(self.context, self.errors)
         self.typeBuilder.visit(self.ast)
         scope = Scope()
         if len(self.errors) == 0:
             self.typeChecker = TypeChecker(self.context, self.errors)
             self.typeChecker.visit( self.ast, scope)
             if len(self.errors) == 0:
                 self.coolToCil = COOLToCILVisitor(self.context)
                 cil_ast = self.coolToCil.visit(self.ast, scope)
                 
                 self.cilToMips = CILToMipsVisitor()
                 self.mipsCode = self.cilToMips.visit(cil_ast)
     return
예제 #5
0
    def visit(self, node, scope=None):
        if scope is None:
            scope = Scope()

        for declaration in node.declarations:
            current = self.context.get_type(declaration.id)
            parent = current.parent
            while parent is not None:
                current.depth += 1
                parent = parent.parent

        for declaration in node.declarations:
            self.visit(declaration, scope.create_child())

        return scope
 def visit(self, node, scope=None, set_type=None):
     to_revisit = []
     scope = Scope(self.scope_id)
     self.scope_id += 1
     for declaration in node.declarations:
         child_scope = scope.create_child(self.scope_id)
         self.scope_id += 1
         visited = self.visit(declaration, child_scope)
         if not visited:
             to_revisit.append(declaration)
     while to_revisit:
         declaration = to_revisit.pop(0)
         visited = self.visit(declaration, None)
         if not visited:
             to_revisit.append(declaration)
     return scope
예제 #7
0
def check_semantics(program: str, debug: bool = False):
    context = Context()
    scope = Scope()
    errors = []

    ast = parse(program, debug)
    if parser.errorok:
        errors = ['Syntactic Error']
    else:
        TypeCollector(context, errors).visit(ast)
        TypeBuilder(context, errors).visit(ast)
        # CyclicDependency(context, errors)
        if not errors:
            TypeChecker(context, errors).visit(ast, scope)

    return ast, errors, context, scope
예제 #8
0
def final_execution(program_file, program_file_out, debug: bool = False, verbose=False):
    context = Context()
    scope = Scope()
    
    errors, program, tokens = tokenize(program_file, debug, verbose)


    if errors or lexer_errors:
        for (_, line, lexpos, value) in lexer_errors:
            totallines = program.count('\n')
            col = get_tokencolumn(program, lexpos) if get_tokencolumn(program, lexpos) > 1 else 2
            print_errors(f'({line}, {col - 1}) - LexicographicError: ERROR \"{value}\"')
        for e in errors:
            print_errors(e)
        exit(1)

    ast = parse(program, debug=debug)

    # if it has no instructions
    if ast is None and not parser_errors:
        print_errors("(0, 0) - SyntacticError: ERROR at or near EOF")
        exit(1)

    if parser_errors:  
        for (line, lexpos, _, value) in parser_errors:
            totallines = program.count('\n')
            col = get_tokencolumn(program, lexpos) if get_tokencolumn(program, lexpos) > 1 else 2
            print_errors(f'({line - totallines}, {col-1}) - SyntacticError: ERROR at or near "{value}"')
        exit(1)

    else:
        PositionateTokensInAST(tokens).visit(ast)
        TypeCollector(context, errors, program).visit(ast)
        if errors:
            for item in errors:
                print_errors(item)
            exit(1)
        TypeBuilder(context, errors, program).visit(ast)
        cyclicDependency(context, errors, program, ast)
        if errors:
            for item in errors:
                print_errors(item)
            exit(1)
        TypeBuilderFeature(context, errors, program).visit(ast)
        if errors:
            for item in errors:
                print_errors(item)
            exit(1)
        # CyclicDependency(context, errors)
        MethodChecker(context, errors, program).visit(ast)
        InferenceTypeChecker(context, errors, program).visit(ast, scope)

        TypeChecker(context, errors, program).visit(ast, scope)
        
        if errors:
            for item in errors:
                print_errors(item)
            exit(1)

        ### code generation ###  
        
        dict_attr, dict_method = {}, {}
        CollectDeclarationsDict(dict_attr, dict_method, context).visit(ast)
        get_declarations_dict(dict_attr, dict_method)
        
        COOLToCILVisitor(context).visit(ast,scope)