def add_method_from_parent_class(self, method): name = method.get("name") args = argument_list_for_declaration(method.env, method) if (name, args) in self.methods: # If this method is already defined error_if("final" in modifiers(method), "Cannot override final methods.") error_if("static" in modifiers(self.methods[name, args]), "Cannot override a method with a static methods.") error_if("static" in modifiers(method), "Cannot override a static method.") error_if("protected" in modifiers(self.methods[name, args]) and "public" in modifiers(method), "A protected method must not override a public method.") error_if((return_type(self.methods[name, args]) != return_type(method)), "An overriding method cannot have a different return " + "type from what it is overriding") else: error_if(is_abstract(method) and "abstract" not in modifiers(self.tree), "Must override abstract method.") self.methods[name, args] = method
def add_constructor_declarations_to_environments(self, tree): for ctor in tree.findall(".//constructor_declaration"): name = ctor.get("name") error_if(name != tree.get("name"), "Wrong constructor name.") args = argument_list_for_declaration(self, ctor) error_if(args in self.constructors, "Duplicate constructors not allowed.") self.constructors[args] = ctor
def add_method_declarations_to_environment(self, tree): for method in tree.findall(".//method") + tree.findall( ".//abstract_method"): name = method.get("name") args = argument_list_for_declaration(self, method) error_if((name, args) in self.methods, "Duplicate methods not allowed.") self.methods[name, args] = method self.tree.superclass = self.__superclass(self.tree)
def mega_vtable_for_class(class_declaration): assembly = vtable_name_for_class(class_declaration) + ":\n" assembly += "dd {type_tag}\n".format(type_tag=class_declaration.type_tag) zero_run_length = 0 for method in method_list.method_list: name = method.get("name") args = argument_list_for_declaration(method.env, method) vtable_method = class_declaration.env.find_method_by_name(name, args) if vtable_method and vtable_method.find("block"): if zero_run_length > 0: assembly += reserve_nulls(zero_run_length) zero_run_length = 0 fn_name = mangle_fn_name(vtable_method) assembly += "dd " + fn_name + "\n" else: zero_run_length += 1 assembly += reserve_nulls(zero_run_length) return assembly
def add_method_from_parent_interface(self, method): name = method.get("name") args = argument_list_for_declaration(method.env, method) error_if((name, args) not in self.methods and "abstract" not in modifiers(self.tree) and "class" == self.tree.tag, "Must override interface methods") if ((name, args) in self.methods and "protected" in modifiers(self.methods[name, args]) and "public" in modifiers(method)): concrete_method = self.methods[name, args] if (concrete_method.find(".//block") is None and concrete_method not in self.tree.findall(".//method")): self.methods[name, args] = method else: error_if(True, "A protected method canot override a public method.") if (name, args) in self.methods: error_if((return_type(self.methods[name, args]) != return_type(method)), "An overriding method cannot have a different return " + "type from what it is overriding") else: self.methods[name, args] = method
def mangle_fn_name(method_decl): name = mangle_class_name(classof(method_decl)) + method_decl.get("name") + "_" for arg in argument_list_for_declaration(method_decl.env, method_decl): name += arg.replace("[", "__lbrace__").replace("]", "__rbrace__") + "_" return name.replace(".", "_")