示例#1
0
def to_if(tokens: tc.TokenSeq) -> tp.Union[stmt.IfStmt, stmt.ErrorStmt]:
    paren = next(tu.token_find_index(tokens, {tt.RIGHT_PAREN}), len(tokens))
    condition = ep.conditional(tokens[:paren + 1])
    if condition.has_error():
        return stmt.ErrorStmt()
    else_index = next(tu.token_find_index(tokens, {tt.ELSE}), len(tokens))
    then_stmt = to_meta_dec(tokens[paren + 1:else_index])
    else_stmt = to_meta_dec(
        tokens[else_index:]) if tokens[else_index:] else None
    return stmt.IfStmt(condition, then_stmt, else_stmt)
示例#2
0
def to_while(tokens: tc.TokenSeq) -> tp.Union[stmt.WhileStmt, stmt.ErrorStmt]:
    right_paren = next(tu.token_find_index(tokens, {tt.RIGHT_PAREN}),
                       len(tokens))
    condition = ep.conditional(tokens[:right_paren + 1])
    if condition.has_error():
        return stmt.ErrorStmt()
    body = to_meta_dec(tokens[right_paren + 1:])
    return stmt.WhileStmt(condition, body)
示例#3
0
def call(tokens: tc.TokenSeq) -> ae.Expr:
    last_paren = next(tu.token_find_index(tokens, {tt.LEFT_PAREN, tt.DOT}),
                      len(tokens))
    if last_paren == 0:
        return primary(tokens)
    if tokens[last_paren - 1].type is tt.SUPER:
        lox_function = primary(tokens[:last_paren + 2])
    else:
        lox_function = primary(tokens[:last_paren])
    for paren_index in tu.token_find_index(tokens, {tt.RIGHT_PAREN, tt.DOT}):
        if tokens[paren_index].type is tt.RIGHT_PAREN:
            args = tuple(
                function_call_args(
                    tokens[last_paren + CallIncrements[tokens[last_paren].
                                                       type]:paren_index], ))
            lox_function = expr.Call(lox_function, tokens[paren_index], args)
        elif tokens[paren_index - 1].type is not tt.SUPER:
            lox_function = expr.Get(lox_function, tokens[paren_index + 1])
        last_paren = paren_index
    return lox_function
示例#4
0
def assignment(tokens: tc.TokenSeq) -> ae.Expr:
    equal_index = next(tu.token_find_index(tokens, {tt.EQUAL}), None)
    if equal_index is None or not lu.is_lox_identifier(tokens[:equal_index]):
        return logic_or(tokens)
    var = call(tokens[:equal_index])
    if not isinstance(var, (expr.Variable, expr.Get)):
        error(tokens[equal_index].line, "Invalid assignment target.")
        return expr.ErrorExpr()
    value = equality(tokens[equal_index + 1:])
    if isinstance(var, expr.Get):
        return expr.Set(var, value)
    return expr.Assign(var.name, value)
示例#5
0
def to_var(
        tokens: tp.Sequence[tc.Token]
) -> tp.Union[stmt.ErrorStmt, stmt.VarStmt]:
    relevant_tokens = tu.token_find_index(tokens, {tt.IDENTIFIER, tt.EQUAL})
    index = next(relevant_tokens, None)
    name = tokens[index] if index is not None else tc.sentinel_token
    if name.type is not tt.IDENTIFIER:
        error(name.line, "Expect variable name.")
        return stmt.ErrorStmt()
    equal_index = next(relevant_tokens, None)
    if equal_index is None and index != len(tokens) - 1:
        error(name.line,
              "Expect nothing between the variable name and the equals sign.")
        return stmt.ErrorStmt()
    initializer = (ep.expression(tokens[equal_index + 1:])
                   if equal_index is not None else None)
    return stmt.VarStmt(name, initializer)