def visit(self, node):
        self.context = Context()

        bool_type = BoolType()
        int_type = IntType()
        str_type = _create_string_type(int_type)
        self_type = SelfType()
        obj_type = _create_object_type(str_type, self_type)
        io_type = _create_io_type(str_type, self_type, int_type)
        auto_type = AutoType()
        error_type = ErrorType()

        bool_type.set_parent(obj_type)
        int_type.set_parent(obj_type)
        str_type.set_parent(obj_type)
        self_type.set_parent(obj_type)
        io_type.set_parent(obj_type)
        auto_type.set_parent(obj_type)
        error_type.set_parent(obj_type)

        self.context.types[BasicTypes.BOOL.value] = bool_type
        self.context.types[BasicTypes.INT.value] = int_type
        self.context.types[BasicTypes.STRING.value] = str_type
        self.context.types[BasicTypes.SELF.value] = self_type
        self.context.types[BasicTypes.OBJECT.value] = obj_type
        self.context.types[BasicTypes.IO.value] = io_type
        self.context.types[BasicTypes.AUTO.value] = auto_type
        self.context.types[BasicTypes.ERROR.value] = error_type

        for class_dec_node in node.declarations:
            self.visit(class_dec_node)
class TypeCollector(object):
    def __init__(self, errors=None):
        if errors is None:
            errors = []
        self.context = None
        self.errors = errors

    @visitor.on("node")
    def visit(self, node):
        pass

    @visitor.when(ProgramNode)
    def visit(self, node):
        self.context = Context()

        bool_type = BoolType()
        int_type = IntType()
        str_type = _create_string_type(int_type)
        self_type = SelfType()
        obj_type = _create_object_type(str_type, self_type)
        io_type = _create_io_type(str_type, self_type, int_type)
        auto_type = AutoType()
        error_type = ErrorType()

        bool_type.set_parent(obj_type)
        int_type.set_parent(obj_type)
        str_type.set_parent(obj_type)
        self_type.set_parent(obj_type)
        io_type.set_parent(obj_type)
        auto_type.set_parent(obj_type)
        error_type.set_parent(obj_type)

        self.context.types[BasicTypes.BOOL.value] = bool_type
        self.context.types[BasicTypes.INT.value] = int_type
        self.context.types[BasicTypes.STRING.value] = str_type
        self.context.types[BasicTypes.SELF.value] = self_type
        self.context.types[BasicTypes.OBJECT.value] = obj_type
        self.context.types[BasicTypes.IO.value] = io_type
        self.context.types[BasicTypes.AUTO.value] = auto_type
        self.context.types[BasicTypes.ERROR.value] = error_type

        for class_dec_node in node.declarations:
            self.visit(class_dec_node)

    @visitor.when(ClassDeclarationNode)
    def visit(self, node):
        try:
            typex = self.context.create_type(node)
            typex.set_parent(self.context.types[BasicTypes.OBJECT.value])
        except SemanticError as error:
            self.errors.append(SEMANTIC_ERROR % (node.lineno, node.colno, error.text))
            node.id = BasicTypes.ERROR.value
예제 #3
0
def test_context(program_file: str, debug: bool = False):
    program = read_file(program_file)

    context = Context()
    errors = []

    ast = parse(program, debug)
    TypeCollector(context, errors).visit(ast)
    TypeBuilder(context, errors).visit(ast)
    # CyclicDependency(context, errors)
    if not errors:
        print(context)
    else:
        print('\n'.join(errors))
예제 #4
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
예제 #5
0
def test_inference(program_file: str, debug: bool = False):
    program = read_file(program_file)

    context = Context()
    errors = []

    ast = parse(program, debug)
    if ast is None:
        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))
        else:
            print('\n'.join(errors))
예제 #6
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
예제 #7
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)