def visit(self, node, scopex: Scope()): scope: Scope = scopex.next_child() self.current_method = self.current_type.get_method(node.id) for idx, typex in zip(self.current_method.param_names, self.current_method.param_types): var = scope.find_variable(idx) var.type = self.compare_types(var.type, typex) decl_inferred = node.inferenced_type expr_inferred = node.body.inferenced_type ret_type_decl = self.update_type(self.current_method.return_type) self.visit(node.body, scope) ret_type_expr = self.update_type(node.body.inferenced_type) conforms(ret_type_expr, ret_type_decl) print("Comapring inferenced type in FuncDecl") node.inferenced_type = self.compare_types(decl_inferred, ret_type_decl) print("Comapring Body inferenced type in FuncDecl") node.body.inferenced_type = self.compare_types(expr_inferred, ret_type_expr) if isinstance(self.current_method.return_type, AutoType): auto_return = self.current_method.return_type ret_type_decl = conforms(ret_type_decl, ret_type_expr) print("Comapring inferenced type in FuncDecl Once Agagin") node.inferenced_type = self.compare_types(decl_inferred, ret_type_decl) if is_subset(ret_type_decl, auto_return): self.current_method.return_type = ret_type_decl self.current_method = None
def visit(self, node, scope): if node.obj == None: obj_type = self.current_type elif isinstance(node.obj, tuple): self.visit(node.obj[0], scope) child_type = self.update_type(node.obj[0].inferenced_type) try: obj_type = self.context.get_type(node.obj[1], selftype=False, autotype=False) if isinstance(child_type, AutoType): child_type.set_upper_limmit([obj_type]) except SemanticError: obj_type = ErrorType() else: self.visit(node.obj, scope) obj_type = self.update_type(node.obj.inferenced_type) methods = None try: methods = [(obj_type, obj_type.get_method(node.id))] except SemanticError as err: if isinstance(obj_type, AutoType): result = self.context.get_method_by_name( node.id, len(node.args)) types = [typex for _, typex in result] obj_type.set_upper_limmit(types) if len(obj_type.upper_limmit): methods = [(t, t.get_method(node.id)) for t in obj_type.upper_limmit] else: self.AddError(err) node.inferenced_obj_type = obj_type if methods: type_set = set() heads = [] for typex, method in methods: ret_type = method.return_type ret_type = typex if isinstance(ret_type, SelfType) else ret_type heads, type_set = smart_add(type_set, heads, ret_type) if len(node.args) == len(method.param_types): for i in range(len(node.args)): arg, param_type = node.args[i], method.param_types[i] self.visit(arg, scope) arg_type = self.update_type(arg.inferenced_type) arg_type = conforms(arg_type, param_type) if isinstance(param_type, AutoType): param_type = conforms(param_type, arg_type) method.param_types[i] = param_type self.update_graph(arg_type, param_type) arg.inferenced_type = arg_type node.inferenced_type = AutoType(node.id, heads, type_set) else: node.inferenced_type = ErrorType()
def visit(self, node, scope): self.visit(node.left, scope) left_type = self.update_type(node.left.inferenced_type) self.visit(node.right, scope) right_type = self.update_type(node.right.inferenced_type) left_type = conforms(left_type, right_type) node.left.inferenced_type = left_type right_type = conforms(right_type, left_type) node.right.inferenced_type = right_type node.inferenced_type = self.context.get_type("Bool")
def visit(self, node, scope): left_infer = node.left.inferenced_type self.visit(node.left, scope) left_type = self.update_type(node.left.inferenced_type) right_infer = node.right.inferenced_type self.visit(node.right, scope) right_type = self.update_type(node.right.inferenced_type) left_type = conforms(left_type, right_type) node.left.inferenced_type = self.compare_types(left_infer, left_type) right_type = conforms(right_type, left_type) node.right.inferenced_type = self.compare_types( right_infer, right_type) node.inferenced_type = self.context.get_type( "Bool" ) # if len(right_type.type_set) > 0 and len(left_type.type_set) > 0 else ErrorType()
def visit(self, node, scope: Scope): var = scope.find_variable(node.id) if not var: node.define = False var_type = ErrorType() else: node.define = True var_type = var.type self.visit(node.expr, scope) node_expr = self.update_type(node.expr.inferenced_type) if var and var.name != "self": node_expr = conforms(node_expr, var_type) node.expr.inferenced_type = node_expr if isinstance(var_type, AutoType): var_type = conforms(var_type, node_expr) var.type = var_type node.inferenced_type = var_type
def visit(self, node, scope: Scope): if not node.define: var = None var_type = ErrorType() else: var = scope.find_variable(node.id) var_type = var.type expr_inferred = node.expr.inferenced_type self.visit(node.expr, scope) node_expr = self.update_type(node.expr.inferenced_type) if node.define: node_expr = conforms(node_expr, var_type) node.expr.inferenced_type = self.compare_types( expr_inferred, node_expr) if isinstance(var_type, AutoType): var_type = conforms(var_type, node_expr) var.type = self.compare_types(var.type, var_type) node.inferenced_type = self.compare_types(node.inferenced_type, var_type)
def visit(self, node, scopex): scope = scopex.create_child() self.current_method = self.current_type.get_method(node.id) for idx, typex in zip(self.current_method.param_names, self.current_method.param_types): scope.define_variable(idx, typex) self.visit(node.body, scope) ret_type_decl = self.update_type(self.current_method.return_type) ret_type_expr = self.update_type(node.body.inferenced_type) ret_type_expr = conforms(ret_type_expr, ret_type_decl) node.body.inferenced_type = ret_type_expr if isinstance(self.current_method.return_type, AutoType): auto_return = self.current_method.return_type ret_type_decl = conforms(ret_type_decl, ret_type_expr) if is_subset(ret_type_decl, auto_return): self.update_graph(ret_type_decl, ret_type_expr) self.current_method.return_type = ret_type_decl node.inferenced_type = ret_type_decl self.current_method = None
def visit(self, node, scope: Scope): if node.define: node_type = scope.find_variable(node.id).type else: node_type = ErrorType() if node.expr: expr_inferr = node.expr.inferenced_type self.visit(node.expr, scope) expr_type = self.update_type(node.expr.inferenced_type) expr_type = conforms(expr_type, node_type) node.expr.inferenced_type = self.compare_types( expr_inferr, expr_type) node.inferenced_type = self.compare_types(node.inferenced_type, node_type)
def visit(self, node, scope): self.current_attrb = self.current_type.get_attribute(node.id) node_type = self.update_type(self.current_attrb.type) if not node.expr: self.current_attrb = None node.inferenced_type = node_type return self.visit(node.expr, scope) node_expr = self.update_type(node.expr.inferenced_type) node_expr = conforms(node_expr, node_type) node.expr.inferenced_type = node_expr node.inferenced_type = node_type # if len(node_expr.type_set) else ErrorType() var = scope.find_variable(node.id) var.type = node.inferenced_type self.current_attrb = None
def visit(self, node, scope): self.current_attrb = self.current_type.get_attribute(node.id) node_type = self.current_attrb.type if not node.expr: self.current_attrb = None return type_infered = node.inferenced_type expr_infered = node.expr.inferenced_type self.visit(node.expr, scope) node_expr = self.update_type(node.expr.inferenced_type) node_expr = conforms(node_expr, node_type) node.inferenced_type = self.compare_types(type_infered, node_type) node.expr.inferenced_type = self.compare_types(expr_infered, node_expr) var = scope.find_variable(node.id) var.type = node.inferenced_type self.current_attrb = None
def visit(self, node, scope): try: node_type = self.context.get_type(node.type) except SemanticError as err: node_type = ErrorType() if not scope.is_local(node.id): scope.define_variable(node.id, node_type) node.define = True else: node.define = False self.AddError(f"Declaring Variable \"{node.id}\":", LOCAL_ALREADY_DEFINED.replace('%s', node.id, 1)) if node.expr: self.visit(node.expr, scope) expr_type = self.update_type(node.expr.inferenced_type) expr_type = conforms(expr_type, node_type) node.expr.inferenced_type = expr_type node.inferenced_type = node_type
def visit(self, node, scope): if isinstance(node.inferenced_type, ErrorType): return if node.obj == None: obj_type = self.current_type elif isinstance(node.obj, tuple): self.visit(node.obj[0], scope) child_type = self.update_type(node.obj[0].inferenced_type) try: obj_type = self.context.get_type(node.obj[1], selftype=False, autotype=False) if isinstance(child_type, AutoType): child_type.set_upper_limmit([obj_type]) except SemanticError: obj_type = ErrorType() else: self.visit(node.obj, scope) obj_type = self.update_type(node.obj.inferenced_type) method = None try: method = obj_type.get_method(node.id) except SemanticError: if isinstance(obj_type, AutoType): result = self.context.get_method_by_name( node.id, len(node.args)) valid = [] for meth, typex in result: if typex in obj_type.type_set: valid.append((meth, typex)) if len(valid) > 1: error = f"Method \"{node.id}\" found in {len(valid)} unrelated types:\n" error += " -Found in: " error += ", ".join(typex.name for _, typex in valid) self.AddError(error) obj_type = ErrorType() elif len(valid) == 0: self.AddError( f"There is no method called {node.id} which takes {len(node.args)} paramters." ) obj_type == ErrorType() else: method, types = valid[0] obj_type.set_upper_limmit([types]) node.inferenced_obj_type = self.compare_types(node.inferenced_obj_type, obj_type) if method: type_set = set() heads = [] ret_type = self.update_type(method.return_type) heads, type_set = smart_add(type_set, heads, ret_type) if len(node.args) == len(method.param_types): for i in range(len(node.args)): arg, param_type = node.args[i], method.param_types[i] arg_infer = arg.inferenced_type self.visit(arg, scope) arg_type = self.update_type(arg.inferenced_type) arg_type = conforms(arg_type, param_type) if isinstance(param_type, AutoType): param_type = conforms(param_type, arg_type) method.param_types[i] = self.compare_types( method.param_types[i], param_type) arg.inferenced_type = self.compare_types( arg_infer, arg_type) inferred = node.inferenced_type if isinstance(ret_type, AutoType) and is_subset( inferred, ret_type): method.return_type.set_upper_limmit(heads) node.inferenced_type = self.compare_types( inferred, method.return_type) elif is_subset(ret_type, inferred): node.inferenced_type = self.compare_types(inferred, ret_type) else: node.inferenced_type = ErrorType()