def _sig_or_func(inter: InterpretContext) -> d_Func: # sig Python Str ... # OR # func hello() {||} if not inter.declaring_func: func = d_Func() func.parent_scope = inter.body func.is_null = False inter.declaring_func = func return inter.declaring_func
def _func(inter: InterpretContext) -> Optional[d_Func]: # func test(Str right, Str left) {||} # func () {||} orig_loc = copy.deepcopy(inter.next_tok.loc) func = _sig_or_func(inter) if not func.return_: func.return_ = d_Grammar.VOID if not func.return_list: func.return_list = False if not func.lang: func.lang = b_Ditlang inter.advance_tokens(False) if inter.next_tok.grammar == d_Grammar.WORD: # func someName result: d_Thing = inter.body.find_attr(inter.next_tok.word, scope_mode=True) # type: ignore if result: raise d_SyntaxError(f"'{result.name}' has already been declared") else: func.name = inter.next_tok.word # Advance only if the name was there # If no name, then this is an anonymous function inter.advance_tokens() if inter.next_tok.grammar != d_Grammar.PAREN_LEFT: # func Ditlang void someName( raise d_SyntaxError("Expected parameter list") inter.advance_tokens() while True: if inter.next_tok.grammar == d_Grammar.PAREN_RIGHT: inter.advance_tokens() break param_list = False if inter.next_tok.grammar == d_Grammar.LISTOF: param_list = True inter.advance_tokens() if inter.next_tok.grammar in DOTABLES: # someName(numLib.Number result: d_Thing = _expression_dispatch(inter) # type: ignore if result.grammar == d_Grammar.VALUE_CLASS: param_type = _token_to_type(inter.curr_tok) else: mes = ("Expected class for parameter type, " f"'{result.name}' is of type '{result.public_type}'") raise d_SyntaxError(mes, inter.terminal_loc) elif inter.next_tok.grammar in PRIMITIVES: # someName(d_String param_type = _token_to_type(inter.next_tok) inter.advance_tokens(False) else: raise d_SyntaxError("Expected parameter type") if inter.next_tok.grammar != d_Grammar.WORD: raise d_SyntaxError("Expected parameter name") else: # someName(d_String someParam param_name = inter.next_tok.word result: d_Thing = inter.body.find_attr( param_name, scope_mode=True) # type: ignore if result: raise d_SyntaxError( f"'{param_name}' has already been declared") elif param_name in [p.name for p in func.parameters]: raise d_SyntaxError( f"'{param_name}' is already a parameter name") func.parameters.append(Declarable(param_type, param_name, param_list)) inter.advance_tokens() _trailing_comma(inter, d_Grammar.PAREN_RIGHT) if inter.next_tok.grammar != d_Grammar.BAR_BRACE_LEFT: raise d_SyntaxError("Expected function body") _bar_brace_left(inter, func) func.finalize() inter.declaring_func = None # type: ignore return _handle_anon(inter, func, orig_loc) # type: ignore