diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 1292df50..9f880dab 100644 --- a/src/compiler/compiler.c +++ b/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()); diff --git a/tests/99_extras.py b/tests/99_extras.py index f2a27c02..299ddaf8 100644 --- a/tests/99_extras.py +++ b/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