def visit(self, node): arg_names, arg_types = [], [] for ids, types in node.params: try: arg_type = self.context.get_type(types.lex) except SemanticError as se: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) arg_type = ErrorType() else: if isinstance(arg_type, SelfType): self.errors.append( ERROR_ON_LN_COL % (node.line, node.column) + f'Type "{arg_type.name}" can not be used as a parameter type' ) arg_type = ErrorType() arg_names.append(ids.lex) arg_types.append(arg_type) try: ret_type = self.context.get_type(node.type.lex) except SemanticError as se: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) ret_type = ErrorType() try: self.current_type.define_method(node.id.lex, arg_names, arg_types, ret_type) except SemanticError as se: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text)
def visit(self, node, scope): obj_type = self.current_type try: obj_method = obj_type.get_method(node.id.lex) node_type = obj_type if isinstance(obj_method.return_type, SelfType) else obj_method.return_type except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) node_type = ErrorType() obj_method = None for arg in node.args: self.visit(arg, scope.create_child()) if obj_method and len(node.args) == len(obj_method.param_types): for arg, param_type in zip(node.args, obj_method.param_types): arg_type = arg.static_type if not arg_type.conforms_to(param_type): self.errors.append(ERROR_ON_LN_COL % (arg.line, arg.column) + INCOMPATIBLE_TYPES % (arg_type.name, param_type.name)) else: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + f'Method "{node.id.lex}" canot be dispatched') node.static_type = node_type
def visit(self, node, scope, expected_type=None): try: node_type = self.context.get_type(node.type.lex) except SemanticError: node_type = ErrorType() node.static_type = node_type
def visit(self, node, scope): try: node_type = self.context.get_type(node.type.lex) except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + ex.text) node_type = ErrorType() node.static_type = node_type
def visit(self, node, scope): if scope.is_defined(node.token.lex): var = scope.find_variable(node.token.lex) node_type = var.type else: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + VARIABLE_NOT_DEFINED % (node.token.lex, self.current_method.name)) node_type = ErrorType() node.static_type = node_type
def visit(self, node, scope, expected_type=None): if scope.is_defined(node.token.lex): var = scope.find_variable(node.token.lex) if expected_type: var.set_calls(expected_type) node_type = var.type if var.infered else AutoType() else: node_type = ErrorType() node.static_type = node_type
def visit(self, node): try: attr_type = self.context.get_type(node.type.lex) except SemanticError as se: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text) attr_type = ErrorType() try: self.current_type.define_attribute(node.id.lex, attr_type) except SemanticError as se: self.errors.append(ERROR_ON_LN_COL % (node.line, node.column) + se.text)
def visit(self, node, scope, expected_type=None): node_type = None if node.type: try: node_type = self.context.get_type(node.type.lex) except SemanticError: node_type = ErrorType() else: if isinstance(node_type, SelfType) or isinstance( node_type, AutoType): node_type = ErrorType() self.visit(node.obj, scope.children[0], node_type) obj_type = node.obj.static_type try: obj_type = node_type if node_type else obj_type obj_method = obj_type.get_method(node.id.lex) # setear el expected_type al retorno node_type = obj_type if isinstance( obj_method.return_type, SelfType) else obj_method.return_type except SemanticError: node_type = ErrorType() obj_method = None if obj_method and len(node.args) == len(obj_method.param_types): for arg, var, child_scope in zip(node.args, obj_method.param_infos, scope.children[1:]): self.visit(arg, child_scope, var.type if var.infered else None) # inferir var.type por arg_type else: for arg, child_scope in zip(node.args, scope.children[1:]): self.visit(arg, child_scope) node.static_type = node_type
def visit(self, node, scope): self.visit(node.expression, scope.create_child()) node.static_type = None for idx, typex, expr in node.branches: try: node_type = self.context.get_type(typex.lex) except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text) node_type = ErrorType() else: if isinstance(node_type, SelfType) or isinstance(node_type, AutoType): self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + f'Type "{node_type.name}" can not be used as case type') node_type = ErrorType() id_type = node_type child_scope = scope.create_child() child_scope.define_variable(idx.lex, id_type) self.visit(expr, child_scope) expr_type = expr.static_type node.static_type = node.static_type.type_union(expr_type) if node.static_type else expr_type
def visit(self, node, scope): for idx, typex, expr in node.let_body: try: node_type = self.context.get_type(typex.lex) except SemanticError as ex: self.errors.append(ERROR_ON_LN_COL % (typex.line, typex.column) + ex.text) node_type = ErrorType() id_type = self.current_type if isinstance(node_type, SelfType) else node_type child = scope.create_child() if expr: self.visit(expr, child) expr_type = expr.static_type if not expr_type.conforms_to(id_type): self.errors.append(ERROR_ON_LN_COL % (expr.line, expr.column) + INCOMPATIBLE_TYPES % (expr_type.name, id_type.name)) scope.define_variable(idx.lex, id_type) self.visit(node.in_body, scope.create_child()) node.static_type = node.in_body.static_type