def visit(self, node: AttrDeclarationNode, scope: Scope, set_type=None): # print('attr declaration') if node.id == "self": self.errors.append(SEMANTIC_ERROR % ( node.lineno, node.colno, f'"self" is used as attribute name in class "{self.current_type.name}".' )) if node.val is not None: self.visit(node.val, scope) return var, _ = scope.my_find_var(node.id) attr_type = self.context.get_type(node.type) if var is not None: self.errors.append(ATTR_ALREADY_DEFINED % (node.lineno, node.colno, node.id)) else: scope.define_variable(node.id, attr_type) if node.val is not None: return_type = self.visit(node.val, scope) else: return_type = attr_type if attr_type.name == BasicTypes.SELF.value: attr_type = self.current_type if return_type.name == BasicTypes.SELF.value: return_type = self.current_type if not return_type.conforms_to(attr_type): self.errors.append( INCOMPATIBLE_TYPES % (node.lineno, node.colno, return_type.name, attr_type.name))
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