コード例 #1
0
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
コード例 #2
0
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