1
0
Эх сурвалжийг харах

fix https://github.com/blueloveTH/pocketpy/issues/35

blueloveTH 2 жил өмнө
parent
commit
71ce764c19
3 өөрчлөгдсөн 35 нэмэгдсэн , 13 устгасан
  1. 28 13
      src/compiler.h
  2. 1 0
      src/lexer.h
  3. 6 0
      tests/20_controlflow.py

+ 28 - 13
src/compiler.h

@@ -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));

+ 1 - 0
src/lexer.h

@@ -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

+ 6 - 0
tests/20_controlflow.py

@@ -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
+