mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
This commit is contained in:
parent
21977a3a8e
commit
71ce764c19
@ -25,10 +25,10 @@ class Compiler {
|
||||
int i = 0;
|
||||
std::vector<Token> tokens;
|
||||
|
||||
const Token& prev() { return tokens.at(i-1); }
|
||||
const Token& curr() { return tokens.at(i); }
|
||||
const Token& next() { return tokens.at(i+1); }
|
||||
const Token& err() {
|
||||
const Token& prev() const{ return tokens.at(i-1); }
|
||||
const Token& curr() const{ return tokens.at(i); }
|
||||
const Token& next() const{ return tokens.at(i+1); }
|
||||
const Token& err() const{
|
||||
if(i >= tokens.size()) return prev();
|
||||
return curr();
|
||||
}
|
||||
@ -89,6 +89,7 @@ class Compiler {
|
||||
rules[TK("|")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_OR };
|
||||
rules[TK("^")] = { nullptr, METHOD(exprBinaryOp), PREC_BITWISE_XOR };
|
||||
rules[TK("?")] = { nullptr, METHOD(exprTernary), PREC_TERNARY };
|
||||
rules[TK("if")] = { nullptr, METHOD(exprTernary), PREC_TERNARY };
|
||||
rules[TK(",")] = { nullptr, METHOD(exprTuple), PREC_TUPLE };
|
||||
rules[TK("not in")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
|
||||
rules[TK("is not")] = { nullptr, METHOD(exprBinaryOp), PREC_TEST };
|
||||
@ -195,7 +196,8 @@ class Compiler {
|
||||
consume(TK(":"));
|
||||
}
|
||||
e->decl->code = push_context(lexer->src, e->decl->name.sv());
|
||||
EXPR(false); // https://github.com/blueloveTH/pocketpy/issues/37
|
||||
// https://github.com/blueloveTH/pocketpy/issues/37
|
||||
parse_expression(PREC_LAMBDA + 1, false);
|
||||
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||
pop_context();
|
||||
ctx()->s_expr.push(std::move(e));
|
||||
@ -235,12 +237,25 @@ class Compiler {
|
||||
|
||||
void exprTernary(){
|
||||
auto e = make_expr<TernaryExpr>();
|
||||
e->cond = ctx()->s_expr.popx();
|
||||
EXPR(); // if true
|
||||
e->true_expr = ctx()->s_expr.popx();
|
||||
consume(TK(":"));
|
||||
EXPR(); // if false
|
||||
e->false_expr = ctx()->s_expr.popx();
|
||||
if(prev().type == TK("if")){
|
||||
e->true_expr = ctx()->s_expr.popx();
|
||||
// cond
|
||||
parse_expression(PREC_TERNARY + 1);
|
||||
e->cond = ctx()->s_expr.popx();
|
||||
consume(TK("else"));
|
||||
// if false
|
||||
parse_expression(PREC_TERNARY + 1);
|
||||
e->false_expr = ctx()->s_expr.popx();
|
||||
}else{ // ?:
|
||||
e->cond = ctx()->s_expr.popx();
|
||||
// if true
|
||||
parse_expression(PREC_TERNARY + 1);
|
||||
e->true_expr = ctx()->s_expr.popx();
|
||||
consume(TK(":"));
|
||||
// if false
|
||||
parse_expression(PREC_TERNARY + 1);
|
||||
e->false_expr = ctx()->s_expr.popx();
|
||||
}
|
||||
ctx()->s_expr.push(std::move(e));
|
||||
}
|
||||
|
||||
@ -291,11 +306,11 @@ class Compiler {
|
||||
ce->expr = std::move(expr);
|
||||
ce->vars = EXPR_VARS();
|
||||
consume(TK("in"));
|
||||
EXPR();
|
||||
parse_expression(PREC_TERNARY + 1);
|
||||
ce->iter = ctx()->s_expr.popx();
|
||||
match_newlines_repl();
|
||||
if(match(TK("if"))){
|
||||
EXPR();
|
||||
parse_expression(PREC_TERNARY + 1);
|
||||
ce->cond = ctx()->s_expr.popx();
|
||||
}
|
||||
ctx()->s_expr.push(std::move(ce));
|
||||
|
@ -72,6 +72,7 @@ struct Token{
|
||||
enum Precedence {
|
||||
PREC_NONE,
|
||||
PREC_TUPLE, // ,
|
||||
PREC_LAMBDA, // lambda
|
||||
PREC_TERNARY, // ?:
|
||||
PREC_LOGICAL_OR, // or
|
||||
PREC_LOGICAL_AND, // and
|
||||
|
@ -65,3 +65,9 @@ while (count < 1000):
|
||||
count = count + 1
|
||||
assert count == 1000
|
||||
|
||||
# ternary operator
|
||||
d = 1 if 2 > 1 else 2
|
||||
assert d == 1
|
||||
d = 1 if 2 < 1 else 2
|
||||
assert d == 2
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user