def METHOD_NAME(self, parent=None, **kwargs):
    types = []
    params = []
    void_type = self.symtab.find("void", Type)
    # Generate definition code
    self.symtab.pushFrame()
    # Lookup return type
    return_type = self.return_type.type
    # Generate function header
    for formal in self.formals:
        # Lookup parameter types
        try:
            type, ident = formal.METHOD_NAME()
            types.append(type)
            params.append(ident)
        except AttributeError:
            types.append(formal.type)
            params.append(None)
    body = self.slicc.codeFormatter()
    if self.statements is None:
        self["external"] = "yes"
    else:
        rtype = self.statements.METHOD_NAME(body, return_type)
    self.symtab.popFrame()
    func_name_args = self.ident
    if parent is None:
        for arg in self.formals:
            from slicc.ast import FormalParamAST
            if isinstance(arg, FormalParamAST):
                arg_name = arg.type_ast.ident
            else:
                arg_name = arg
            func_name_args += "_" + str(arg_name)
    machine = self.state_machine
    func = Func(
        self.symtab,
        func_name_args,
        self.ident,
        self.location,
        return_type,
        types,
        params,
        str(body),
        self.pairs,
    )
    if parent is not None:
        if not parent.addFunc(func):
            self.error(f"Duplicate method: {parent}:{self.ident}()")
        func.class_name = parent.c_ident
    elif machine is not None:
        machine.addFunc(func)
        func.isInternalMachineFunc = True
        func.class_name = f"{machine}_Controller"
    else:
        self.symtab.newSymbol(func)