Exemple #1
0
def _import(inter: InterpretContext) -> Optional[d_Dit]:
    # import LINK
    # import NAMESPACE from LINK
    orig_loc = copy.deepcopy(inter.next_tok.loc)
    name = None

    inter.advance_tokens(False)
    gra = inter.next_tok.grammar
    if gra != d_Grammar.WORD and gra not in STRINGABLES:
        raise d_SyntaxError("Expected a name or filepath string for import")

    if gra == d_Grammar.WORD:
        # import SomeName from "someFilePath.dit";
        if inter.body.find_attr(inter.next_tok.word, scope_mode=True):
            raise d_SyntaxError(
                f"'{inter.next_tok.word}' has already been declared")
        name = inter.next_tok.word
        inter.advance_tokens()
        if inter.next_tok.grammar != d_Grammar.FROM:
            raise d_SyntaxError("Expected 'from'")
        inter.advance_tokens()

    dit = _import_or_pull(inter, orig_loc)
    dit.name = name  # type: ignore
    return _import_or_pull_end(inter, dit, orig_loc)
Exemple #2
0
def _brace_left(inter: InterpretContext) -> d_JSON:
    # JSON j = { ...
    inter.in_json = True
    js = d_JSON()
    js.is_null = False
    js.json_ = {}
    inter.advance_tokens()

    while True:
        if inter.next_tok.grammar == d_Grammar.BRACE_RIGHT:
            # JSON j = { ... }
            inter.in_json = False
            inter.advance_tokens()
            return js
        elif inter.next_tok.grammar == d_Grammar.QUOTE_DOUBLE:
            # JSON j = { "item1": ...
            if inter.curr_tok.grammar not in [
                    d_Grammar.BRACE_LEFT, d_Grammar.COMMA
            ]:
                raise d_SyntaxError("Expected ','", inter.curr_tok.loc)
            name = _str(inter).str_
            if inter.next_tok.grammar != d_Grammar.COLON:
                raise d_SyntaxError("Expected ':'", inter.next_tok.loc)
            else:
                inter.advance_tokens()
            ele = _expression_dispatch(inter)
            js.json_[name] = ele
        elif inter.next_tok.grammar == d_Grammar.COMMA:
            # JSON j = { "item1": 1, ...
            inter.advance_tokens()
            if inter.next_tok.grammar == d_Grammar.BRACE_RIGHT:
                raise d_SyntaxError("Trailing commas are not allowed",
                                    inter.curr_tok.loc)
        else:
            raise d_SyntaxError("Unexpected token for JSON")
Exemple #3
0
def _import_or_pull(inter: InterpretContext, orig_loc: CodeLocation) -> d_Dit:
    # The next token is always the link. We just need to get the dit and return it.
    # import LINK
    # import NAMESPACE from LINK
    # pull ... from LINK
    dit = d_Dit()
    dit.is_null = False
    if inter.next_tok.grammar in [d_Grammar.NULL, d_Grammar.VALUE_NULL]:
        raise d_SyntaxError("Cannot import from null")
    elif inter.next_tok.grammar not in STRINGABLES:
        raise d_SyntaxError("Expected a filepath string for import")

    value = _expression_dispatch(inter)
    if inter.dec.name and not inter.equaling:
        dit.path = inter.dec.name
        inter.dec.name = None  # type: ignore
    elif not value:
        raise NotImplementedError
    elif isinstance(value, d_Str):
        dit.path = value.str_
    else:
        raise d_SyntaxError(f"Expected str value, not {value.public_type}")

    dit.finalize()
    try:
        interpret(dit)
    except d_DitError as err:
        err.add_trace(dit.path, orig_loc, "import")
        raise
    return dit
Exemple #4
0
def _sig(inter: InterpretContext) -> Optional[d_Func]:
    # sig JavaScript Str ... \n func
    dotable_loc = None
    func = _sig_or_func(inter)
    did_dispatch = False

    while True:
        if not did_dispatch:
            inter.advance_tokens()
        did_dispatch = False
        gra = inter.next_tok.grammar
        thing = inter.next_tok.thing
        switches = [func.lang, func.return_, func.return_list]

        # listOf needs additional checking
        # There must be a type after it, and not before it.
        if func.return_list and not func.return_:
            # sig ... listOf ...
            if gra == d_Grammar.VOID:
                raise d_SyntaxError("Cannot have listOf void")
            elif gra not in TYPES and gra not in DOTABLES:
                raise d_SyntaxError("Expected type to follow listOf",
                                    dotable_loc)
            elif gra in DOTABLES:
                dotable_loc = copy.deepcopy(inter.next_tok.loc)

        if gra == d_Grammar.FUNC:
            return _func(inter)
        elif gra == d_Grammar.EOF or None not in switches:
            raise d_SyntaxError("Expected 'func' to follow sig")
        elif thing:
            # handles dotables and explicit Lang/Class objects
            _sig_thing_handler(inter, func)
            did_dispatch = True
        elif gra in TYPES or gra == d_Grammar.VOID:
            # sig ... Str ...
            # sig ... void ...
            _sig_assign_return(inter, func)
            func.return_ = prim_to_value(gra)
        elif gra == d_Grammar.LISTOF:
            # sig ... listOf ...
            if func.return_:
                raise d_SyntaxError("Unexpected 'listOf' after type")
            func.return_list = True
        elif inter.next_tok.grammar == d_Grammar.NEW_NAME:
            raise NotImplementedError
            # TODO: finish unassigned langs feature, issue #14
            # We allow langs to be declared on the fly. This lets library dits
            # specify a language without having to import it, which would be annoying.
            # The lang must be more fully assigned in the dit where it will be called.
            lang = d_Lang()
            lang.is_null = False
            lang.parent_scope = inter.body
            lang.name = inter.next_tok.word
            inter.body.attrs[d_Variable(lang.name)] = lang
            func.lang = lang
        else:
            raise d_SyntaxError("Unrecognized token for signature")
Exemple #5
0
def _sig_thing_handler(inter: InterpretContext, func: d_Func) -> None:
    thing = _expression_dispatch(inter)
    if not thing:
        raise NotImplementedError
    elif isinstance(thing, d_Lang):
        if func.lang:
            raise d_SyntaxError("Language was already assigned")
        func.lang = thing
    elif isinstance(thing, d_Class):
        _sig_assign_return(inter, func)
        func.return_ = thing
    else:
        mes = ("Expected Class or Lang, "
               f"'{thing.name}' is of type '{thing.public_type}'")
        raise d_SyntaxError(mes, inter.terminal_loc)
Exemple #6
0
def _equals(inter: InterpretContext, equal_loc: CodeLocation) -> None:
    orig_loc = copy.deepcopy(inter.next_tok.loc)
    if inter.anon_tok or inter.call_tok:
        # prevent assignment to anonymous tokens.
        raise NotImplementedError
    if inter.dec.type_:
        assignee = None
    else:
        assignee = inter.curr_tok.thing

    inter.advance_tokens()
    inter.equaling = True
    value = _expression_dispatch(inter)
    inter.equaling = False
    if not value:
        if inter.named_statement:
            # Prevent assignment of non-anonymous statements.
            # Class anonName = class RealName {||}
            raise d_SyntaxError(
                "A named declaration cannot be used for assignment", orig_loc)
        else:
            raise d_CriticalError(
                "No value for _expression_dispatch in _equals")
    if assignee:
        assignee.set_value(value)
    else:
        try:
            _add_attr_wrap(inter, value=value)
        except d_TypeMismatchError as err:
            err.loc = equal_loc
            raise
Exemple #7
0
    def get_token(self, find_word: bool = True) -> Token:
        if self.eof:
            return _handle_eof(self)

        res = _clear_whitespace_and_comments(self)
        if res:
            return res

        res = _find_double_chars(self)
        if res:
            return res

        res = _find_single_chars(self)
        if res:
            return res

        res = _find_digit(self)
        if res:
            return res

        res = _find_words(self, find_word)
        if res:
            return res

        raise d_SyntaxError(f"Unrecognized token '{self.char_feed.current()}'")
Exemple #8
0
def _equalable(inter: InterpretContext) -> Optional[d_Thing]:
    if (isinstance(inter.curr_tok.thing, d_Lang)
            and inter.prev_tok.grammar == d_Grammar.PRIMITIVE_LANG):
        # Since Langs can be redeclared, we just remove the type_
        # and pretend it was never there in the first place.
        # Lang JavaScript ...
        inter.dec.type_ = None  # type: ignore
    if inter.dec.type_ and not inter.dec.name:
        # _new_name should have been found, not an existing variable.
        # Str existingValue ...
        raise d_SyntaxError(
            f"'{inter.curr_tok.thing.name}' has already been declared")
    elif inter.next_tok.grammar == d_Grammar.EQUALS:
        # Assign existing or new variables
        # Str value = ...
        equal_loc = copy.deepcopy(inter.next_tok.loc)
        _equals(inter, equal_loc)
        inter.dec.reset()
    elif inter.dec.type_ and not inter.equaling:
        # create variable without assignment
        # Str count;
        _add_attr_wrap(inter)
        inter.dec.reset()

    return _terminal(inter)
Exemple #9
0
 def get_prop(self, name: str) -> str:
     res = self.find_attr(name)
     if not res:
         raise d_MissingPropError(self.name, name)
     elif not isinstance(res, d_Str):
         raise d_SyntaxError(
             f"All properties must be strings. Lang {self.name} with property {name}"
         )
     return res.str_
Exemple #10
0
def _type(inter: InterpretContext) -> None:
    # Str test ...
    # someClass test ...
    # Str someDotable.monkeyPatch ...
    # This function is reused by _primitive and _value_class
    inter.dec.type_ = _token_to_type(inter.curr_tok)
    if inter.next_tok.grammar in DUPLICABLES:
        raise d_SyntaxError(
            f"'{inter.next_tok.thing.name}' has already been declared")
    if inter.next_tok.grammar in NAMEABLES:
        _expression_dispatch(inter)
    else:
        raise d_SyntaxError("Expected a new name to follow type")

    if inter.next_tok.grammar == d_Grammar.NEW_NAME:
        # to handle the specific case when a lang is being legally redeclared
        # The tokens were already advanced in _value_lang.
        inter.advance_tokens()
    _equalable(inter)
Exemple #11
0
def _digit_sign(inter: InterpretContext, neg: bool) -> d_Num:
    # make sure the sign is being used as a positive or negative,
    # not for arithmetic
    if DIGIT.match(inter.char_feed.current()):
        inter.advance_tokens()
        return _digit(inter, neg)
    else:
        raise d_SyntaxError(
            "Expected digit.\nOther arithmetic ops are not yet supported.",
            inter.char_feed.loc,  # Default uses inter.next_tok.lok
        )
Exemple #12
0
def _listof(inter: InterpretContext) -> None:
    # listOf Str values;
    inter.advance_tokens()
    inter.dec.listof = True
    if inter.next_tok.grammar in PRIMITIVES:
        _primitive(inter)
    elif inter.next_tok.grammar in DOTABLES:
        _expression_dispatch(inter)

    else:
        raise d_SyntaxError("Expected type for listOf declaration")
Exemple #13
0
def _get_func_args(inter: InterpretContext, func: d_Func) -> None:
    func.call_loc = copy.deepcopy(inter.curr_tok.loc)
    arg_locs = _arg_list(inter, d_Grammar.PAREN_RIGHT)
    miss = abs(len(func.parameters) - len(arg_locs))
    name = func.pub_name()

    for param, arg_loc in zip_longest(func.parameters, arg_locs):
        param: Declarable
        arg_loc: ArgumentLocation
        if not arg_loc:
            raise d_SyntaxError(f"{name} missing {miss} required arguments")
        elif not param:
            # TODO: implement proper k-args functionality
            raise d_SyntaxError(f"{name} given {miss} too many arguments")
        else:
            res = check_value(arg_loc.thing, param)
            if res:
                o = f"{name} expected '{res.expected}', got '{res.actual}'{res.extra}"
                raise d_TypeMismatchError(o, arg_loc.loc)

        func.add_attr(param, arg_loc.thing, use_ref=True)
Exemple #14
0
def _return(inter: InterpretContext) -> NoReturn:
    orig_loc = copy.deepcopy(inter.next_tok.loc)
    if not isinstance(inter.body, d_Func):
        raise d_SyntaxError("'return' outside of function")
    inter.advance_tokens()
    value = _expression_dispatch(inter)
    if not value:
        raise NotImplementedError
    try:
        raise ReturnController(value, inter.body, orig_loc)
    except d_TypeMismatchError as err:
        err.loc = orig_loc
        raise
Exemple #15
0
def _make(inter: InterpretContext) -> d_Func:
    class_: d_Class = inter.curr_tok.thing  # type: ignore
    make = class_.find_attr(MAKE)
    if not make:
        raise d_SyntaxError(f"Class '{class_.name}' does not define a Make")
    elif isinstance(make, d_Func):
        func: d_Func = make
        inst = d_Inst()
        inst.is_null = False
        inst.parent = class_
        func.add_attr(Declarable(class_, THIS), inst, use_ref=True)
        return func
    else:
        raise NotImplementedError
Exemple #16
0
def _clang(inter: InterpretContext,
           clang: Union[d_Class, d_Lang]) -> Optional[Union[d_Class, d_Lang]]:
    # class/lang NAME {||}
    # class/lang {||}; <- Anonymous version
    lang = None
    orig_loc = copy.deepcopy(inter.next_tok.loc)
    clang_name = "class" if isinstance(clang, d_Class) else "lang"

    inter.advance_tokens(False)
    if inter.next_tok.grammar not in [
            d_Grammar.WORD, d_Grammar.BAR_BRACE_LEFT
    ]:
        raise d_SyntaxError(f"Expected name or body to follow {clang_name}")

    if inter.next_tok.grammar == d_Grammar.WORD:
        result = inter.body.find_attr(inter.next_tok.word, scope_mode=True)
        if result:
            if isinstance(result, d_Lang):
                # Langs are allowed to be redeclared
                # lang someLang {||}
                # lang someLang {||}
                lang = result
            else:
                raise d_SyntaxError(
                    f"'{inter.next_tok.word}' has already been declared")
        clang.name = inter.next_tok.word
        inter.advance_tokens()  # get {|
        if inter.next_tok.grammar != d_Grammar.BAR_BRACE_LEFT:
            raise d_SyntaxError(f"Expected a {clang_name} body")

    _bar_brace_left(inter, clang)
    clang.finalize()
    try:
        interpret(clang)
    except d_EndOfFileError as err:
        raise d_EndOfClangError(clang_name) from err
    return _handle_anon(inter, clang, orig_loc, lang)  # type: ignore
Exemple #17
0
def _digit(inter: InterpretContext, neg: bool = False) -> d_Num:
    num = inter.next_tok.word
    num = "-" + num if neg else num
    lead_zero = num == "0"
    frac = False
    exp = False
    while True:
        cur = inter.char_feed.current()
        if DIGIT.match(cur):
            # 3
            if lead_zero and len(num) == 1:
                raise d_SyntaxError("Leading zeros are not allowed")
            num += cur
            inter.char_feed.pop()
            lead_zero = False
        elif cur == ".":
            # 3.
            if frac == True:
                raise d_SyntaxError("Invalid fraction syntax")
            num += cur
            inter.char_feed.pop()
            frac == True
        elif cur == "e" or cur == "E":
            # 3e ... 10
            if exp == True:
                raise d_SyntaxError("Invalid exponent syntax")
            num += cur
            inter.char_feed.pop()
            exp == True
        elif cur == "-" or cur == "+":
            # -3
            num += cur
            inter.char_feed.pop()
        else:
            break
    return _finalize_num(inter, num)
Exemple #18
0
def _run_func(inter: InterpretContext, func: d_Func) -> Token:
    try:
        if func.is_built_in:
            if func.name == "getConfig":
                _handle_get_config(inter, func)
            else:
                func.py_func(func)
        elif func.lang is b_Ditlang:
            interpret(func)
        else:
            if not func.code:
                raise ReturnController(d_Thing.get_null_thing(), func,
                                       func.call_loc)
            _job_loop(GuestDaemonJob(JobType.CALL_FUNC, func))

    except d_CodeError as err:
        err.loc = func.call_loc
        # err.set_origin(
        #    inter.body.path, func.call_loc, inter.char_feed.get_line(func.call_loc)
        # )
        raise err
    except d_DitError as err:
        err.add_trace(func.path, func.call_loc, func.name)
        raise err
    except ReturnController as ret:
        if func.lang is not b_Ditlang:
            job = GuestDaemonJob(JobType.RETURN_KEYWORD, func)
            run_job(job)
        return ret.token
    except d_TypeMismatchError as mis:
        raise NotImplementedError
    else:
        if func.return_ and func.return_ != d_Grammar.VOID:
            raise d_SyntaxError(f"{func.pub_name()} expected a return",
                                func.call_loc)
        elif func.name == MAKE:
            thing = func.find_attr(THIS)
            if not thing:
                raise NotImplementedError
            return Token(d_Grammar.VALUE_INST, func.call_loc, thing=thing)
        else:
            # func ended without 'return' keyword
            return Token(d_Grammar.NULL, func.call_loc)
Exemple #19
0
def _missing_terminal(inter: InterpretContext, message: str) -> NoReturn:
    tok = inter.curr_tok
    target = tok.loc
    code = inter.char_feed.get_line(target)

    if isinstance(tok.grammar.value, str):
        length = len(tok.grammar.value)  # class, Str, =
    elif tok.thing:
        length = len(tok.thing.name)  # Object names
    else:
        length = len(tok.word)  # New Names

    # Shift locaton to end of token
    target.pos += length
    target.col += length

    err = d_SyntaxError(message, target)
    err.set_origin(inter.body.path, code)
    raise err
Exemple #20
0
def _dot(inter: InterpretContext) -> Token:
    inter.advance_tokens(False)  # We want to manage the next word ourselves
    if inter.next_tok.grammar != d_Grammar.WORD:
        raise d_SyntaxError(f"'{inter.next_tok.grammar}' is not dotable")

    # Allows dotting of anonymous tokens and function calls.
    target = (inter.anon_tok or inter.call_tok or inter.prev_tok).thing

    if isinstance(target, d_Inst):
        # We need to prepare in case the instance has inherited parents
        target.clear_prefix_to_func()
        inter.dotted_inst = target
    elif not isinstance(target, d_Container):
        raise d_CriticalError(f"Expected container, got {target.public_type}")

    result = target.find_attr(inter.next_tok.word)
    if not result and inter.dotted_inst:
        # this.B.attribute
        # We are doing explicit name disambiguation, looking in parent B instead of A.
        # B obviously doesn't have the attribute, the instance does.
        # So we look again in the instance.
        result = inter.dotted_inst.find_attr(inter.next_tok.word)

    if result:
        # The dot had a known variable, which we just need to return
        if isinstance(result, d_Func) and inter.dotted_inst:
            # this.func()
            # if `func` is an inherited function, we need to remember that we
            # called it so the prefixes are set up correctly.
            inter.dotted_inst.add_func_sep()
        return Token(result.grammar,
                     copy.deepcopy(inter.next_tok.loc),
                     thing=result)
    else:
        # The name was not found in the dotted body, so its a new name.
        # This means we are declaring a new var in the dotted body.
        # AKA Monkey patching
        inter.next_tok.grammar = d_Grammar.NEW_NAME
        inter.dotted_body = target  # Save for assignment
        return inter.next_tok
Exemple #21
0
def _str(inter: InterpretContext) -> d_Str:
    # note that _str is reused for parsing JSON element names
    left = inter.next_tok.grammar.value
    data = ""
    if inter.char_feed.current() != left:
        while True:
            if inter.char_feed.current() == "\n":
                lok = copy.deepcopy(inter.next_tok.loc)
                length = len(data)
                lok.pos += length
                lok.col += length
                raise d_SyntaxError("Unexpected EOL while reading string", lok)
            elif inter.char_feed.current() == d_Grammar.BACKSLASH.value:
                # Str test = "some\t"
                # Str test = 'Let\'s'
                escape_char = inter.char_feed.pop()
                inter.char_feed.pop()
                if escape_char in [
                        d_Grammar.QUOTE_DOUBLE.value,
                        d_Grammar.QUOTE_SINGLE.value,
                        d_Grammar.BACKSLASH.value,
                ]:
                    data += escape_char
                elif escape_char == d_Grammar.ESCAPE_NEWLINE.value:
                    data += "\n"
                elif escape_char == d_Grammar.ESCAPE_TAB.value:
                    data += "\t"
            else:
                data += inter.char_feed.current()
                inter.char_feed.pop()

            if inter.char_feed.current() == left:
                break

    inter.advance_tokens()  # next_tok is now ' "
    inter.advance_tokens()  # next_tok is now ; , ] ) :
    thing = d_Str()
    thing.str_ = data
    thing.is_null = False
    return thing
Exemple #22
0
def _illegal_statement(inter: InterpretContext) -> NoReturn:
    raise d_SyntaxError("Illegal start of statement")
Exemple #23
0
def _sig_assign_return(inter: InterpretContext, func: d_Func) -> None:
    if func.return_:
        raise d_SyntaxError("Return type was already assigned")
    func.return_list = bool(func.return_list)
Exemple #24
0
def _pull(inter: InterpretContext) -> None:
    # pull TARGET (as REPLACEMENT), ... from LINK
    orig_loc = copy.deepcopy(inter.next_tok.loc)
    targets: List[Tuple[str, Optional[str]]] = []
    langs: List[Optional[d_Lang]] = []
    while True:
        # pull ...
        # pull THING, ...
        # pull THING as NAME, ...
        inter.advance_tokens(False)
        if inter.next_tok.grammar != d_Grammar.WORD:
            raise d_SyntaxError("Expected name to pull from linked dit")
        # pull NAME ...
        target = inter.next_tok.word
        loc = copy.deepcopy(inter.next_tok.loc)
        replacement = None
        inter.advance_tokens()
        if inter.next_tok.grammar == d_Grammar.AS:
            # pull NAME as ...
            inter.advance_tokens(False)
            if inter.next_tok.grammar != d_Grammar.WORD:
                raise d_SyntaxError("Expected name to replace target name")
            replacement = inter.next_tok.word
            loc = inter.next_tok.loc
            inter.advance_tokens()

        name = replacement or target
        result = inter.body.find_attr(name, True)
        if result:
            if isinstance(result, d_Lang):
                # Langauges can overwrite langs already in this dit
                # lang someLang {||}
                # pull someLang from LINK
                langs.append(result)
            else:
                raise d_SyntaxError(f"'{name}' has already been declared", loc)
        else:
            langs.append(None)
        targets.append((target, replacement))

        if inter.next_tok.grammar == d_Grammar.FROM:
            break
        elif inter.next_tok.grammar == d_Grammar.COMMA:
            continue
        else:
            raise d_SyntaxError("Expected 'from' or ',' to follow target")

    inter.advance_tokens()
    dit = _import_or_pull(inter, orig_loc)
    for (tar, rep), lang in zip(targets, langs):
        # pull TARGET (as REPLACEMENT), ... from LINK
        result = dit.find_attr(tar)
        if not result:
            raise d_SyntaxError(f"'{tar}' is not a valid member of this dit")
        result.name = rep or tar
        if lang and isinstance(result, d_Lang):
            # explicit call to set_value, to activate Priority comparisons
            lang.set_value(result)
            result.attrs = lang.attrs  # TODO: proper unassigned lang logic
        else:
            inter.body.attrs[d_Variable(result.name)] = result
    _import_or_pull_end(inter, dit, orig_loc)
Exemple #25
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
Exemple #26
0
def _not_implemented(inter: InterpretContext) -> NoReturn:
    raise d_SyntaxError("This keyword is reserved for later development")
Exemple #27
0
def _illegal_expression(inter: InterpretContext) -> NoReturn:
    raise d_SyntaxError("Illegal start of expression")