def set_parent(self, parent): try: DeprecatedType.set_parent(self, parent) if not parent.can_have_children: self.parent = None raise SemanticError(TYPE_CANT_BE_INHERITED, self.name, parent.name) except DeprecatedSemanticError as er: raise SemanticError(er.text)
def define_attribute(self, name: str, typex): try: attribute = self.get_attribute(name) except SemanticError: attribute = Attribute(name, typex) self.attributes.append(attribute) return attribute else: if attribute in self.attributes: raise SemanticError(ATTRIBUTE_ALREADY_DEFINED, name) else: raise SemanticError(ATTRIBUTE_ALREADY_DEFINED_IN_PARENT, name)
def _get_attribute(self, name: str, visited_types: set): if self in visited_types: raise SemanticError(ATTRIBUTE_NOT_DEFINED, name, self.name) try: return next(attr for attr in self.attributes if attr.name == name) except StopIteration: if self.parent is None or self.parent == self: raise SemanticError(ATTRIBUTE_NOT_DEFINED, name, self.name) try: visited_types.add(self) return self.parent._get_attribute(name, visited_types) except SemanticError: raise SemanticError(ATTRIBUTE_NOT_DEFINED, name, self.name)
def define_method(self, name: str, param_names: list, param_types: list, return_type): if (name, len(param_names)) in ((method.name, len(method.param_names)) for method in self.methods): raise SemanticError(METHOD_ALREADY_DEFINED, name) method = Method(name, param_names, param_types, return_type) self.methods.append(method) return method
def get_type(self, name:str,self_type=None,current_type=None): if name == 'SELF_TYPE': if self_type: name = self_type.name else: return SelfType(current_type) # raise TypeError('Wrong argument combination: name is "SELF_TYPE" and no self_type given') elif name == 'AUTO_TYPE': return AutoType(self) try: return self.types[name] except KeyError: raise SemanticError(TYPE_NOT_DEFINED, name)
def get_method(self, name: str, args: int, current_type=None, only_local=False): self = self if not isinstance( self, SelfType) or not current_type else current_type try: return next( method for method in self.methods if method.name == name and len(method.param_names) == args) except StopIteration: if self.parent is None or self.parent == self: raise SemanticError(METHOD_NOT_DEFINED, name, "", self.name, args) try: if not only_local: return self.parent.get_method(name, args) raise SemanticError() except SemanticError: raise SemanticError(METHOD_NOT_DEFINED, name, "" if not only_local else " locally", self.name, args)
def create_type(self, name:str): if name in self.types: raise SemanticError(TYPE_ALREADY_DEFINED, name) typex = self.types[name] = Type(name) return typex