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
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))
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
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))
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
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)