Sfoglia il codice sorgente

fix `**` associativity

blueloveTH 1 anno fa
parent
commit
6266161118
2 ha cambiato i file con 11 aggiunte e 2 eliminazioni
  1. 7 2
      src/compiler/compiler.c
  2. 4 0
      tests/99_extras.py

+ 7 - 2
src/compiler/compiler.c

@@ -1400,7 +1400,7 @@ static Error* parse_expression(Compiler* self, int precedence, bool allow_slice)
         TokenIndex op = curr()->type;
         advance();
         PrattCallback infix = rules[op].infix;
-        if(infix == NULL){
+        if(infix == NULL) {
             return SyntaxError(self, "expected an infix operator, got %s", TokenSymbols[op]);
         }
         check(infix(self));
@@ -1652,7 +1652,12 @@ static Error* exprBinaryOp(Compiler* self) {
     Error* err;
     int line = prev()->line;
     TokenIndex op = prev()->type;
-    check(parse_expression(self, rules[op].precedence + 1, false));
+    int precedence = rules[op].precedence;
+    if(op != TK_POW) {
+        // if not right associative, increase precedence
+        precedence += 1;
+    }
+    check(parse_expression(self, precedence, false));
     BinaryExpr* e = BinaryExpr__new(line, op, false);
     if(op == TK_IN || op == TK_NOT_IN) {
         e->lhs = Ctx__s_popx(ctx());

+ 4 - 0
tests/99_extras.py

@@ -47,3 +47,7 @@ assert A()[::, :] == (slice(None, None, None), slice(None, None, None))
 assert A()[::, :2] == (slice(None, None, None), slice(None, 2, None))
 assert A()['b':'c':1, :] == (slice('b', 'c', 1), slice(None, None, None))
 assert A()[1:2, :A()[3:4, ::-1]] == (slice(1, 2, None), slice(None, (slice(3, 4, None), slice(None, None, -1)), None))
+
+# test right associative
+assert 2**2**3 == 256
+assert (2**2**3)**2 == 65536