diff --git a/libkc3/buf_parse.c b/libkc3/buf_parse.c
index 370ba13..50908d3 100644
--- a/libkc3/buf_parse.c
+++ b/libkc3/buf_parse.c
@@ -944,18 +944,17 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, sw min_precedence)
if ((r = buf_peek_ident(buf, &next_op)) <= 0)
goto restore;
if (! operator_resolve(&next_op, 2, &next_op) ||
- ! operator_precedence(&next_op, &next_op_precedence)) {
+ ! operator_precedence(&next_op, &op_precedence)) {
r = 0;
goto restore;
}
- while (r > 0 && next_op_precedence >= min_precedence) {
+ while (r > 0 && op_precedence >= min_precedence) {
if ((r = buf_parse_ident(buf, &next_op)) <= 0)
goto restore;
result += r;
if (! operator_resolve(&next_op, 2, &next_op))
goto restore;
op = next_op;
- op_precedence = next_op_precedence;
tmp.ident = op;
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
@@ -976,21 +975,23 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, sw min_precedence)
if (! operator_resolve(&next_op, 2, &next_op) &&
! operator_resolve(&next_op, 1, &next_op))
break;
- operator_precedence(&next_op, &next_op_precedence);
+ if (! operator_precedence(&next_op, &next_op_precedence)) {
+ r = -1;
+ break;
+ }
while (1) {
if (r <= 0 ||
operator_arity(&next_op) != 2) {
break;
}
- if (next_op_precedence < op_precedence)
- break;
- if (! operator_is_right_associative(&op, &b)) {
- r = -1;
- break;
- }
- if (! b ||
- next_op_precedence != op_precedence) {
- break;
+ if (next_op_precedence <= op_precedence) {
+ if (! operator_is_right_associative(&next_op, &b)) {
+ r = -1;
+ break;
+ }
+ if (! b ||
+ next_op_precedence != op_precedence)
+ break;
}
call_init_op(&tmp2);
tmp2.arguments->tag = *right;
diff --git a/test/ikc3/op.kc3 b/test/ikc3/op.kc3
index dc7e749..29125ba 100644
--- a/test/ikc3/op.kc3
+++ b/test/ikc3/op.kc3
@@ -2,13 +2,23 @@ quote 1 + 20
1 + 20
quote 1 + 20 / 3
1 + 20 / 3
+quote to_lisp(quote 1 + 20 / 3)
+to_lisp(quote 1 + 20 / 3)
quote 1 + 20 / 3 * 4
1 + 20 / 3 * 4
+quote to_lisp(quote 1 + 20 / 3 * 4)
+to_lisp(quote 1 + 20 / 3 * 4)
quote 1 + 20 / 3 * 4 - 5
1 + 20 / 3 * 4 - 5
+quote to_lisp(quote 1 + 20 / 3 * 4 - 5)
+to_lisp(quote 1 + 20 / 3 * 4 - 5)
quote 20 / 3 * 4 - 5
20 / 3 * 4 - 5
+quote to_lisp(quote 20 / 3 * 4 - 5)
+to_lisp(quote 20 / 3 * 4 - 5)
quote (1 + 20)
(1 + 20)
+quote to_lisp(quote (1 + 20))
+to_lisp(quote (1 + 20))
quote a = (1 + 20)
a = (1 + 20)
diff --git a/test/ikc3/op.out.expected b/test/ikc3/op.out.expected
index 7ff43c5..1772537 100644
--- a/test/ikc3/op.out.expected
+++ b/test/ikc3/op.out.expected
@@ -2,13 +2,23 @@
21
1 + 20 / 3
7
+to_lisp(quote 1 + 20 / 3)
+[operator_add, 1, [operator_div, 20, 3]]
1 + 20 / 3 * 4
25
+to_lisp(quote 1 + 20 / 3 * 4)
+[operator_add, 1, [operator_mul, [operator_div, 20, 3], 4]]
1 + 20 / 3 * 4 - 5
20
+to_lisp(quote 1 + 20 / 3 * 4 - 5)
+[operator_add, 1, [operator_sub, [operator_mul, [operator_div, 20, 3], 4], 5]]
20 / 3 * 4 - 5
19
+to_lisp(quote 20 / 3 * 4 - 5)
+[operator_sub, [operator_mul, [operator_div, 20, 3], 4], 5]
(1 + 20)
21
+to_lisp(quote (1 + 20))
+[operator_paren, [operator_add, 1, 20]]
a = (1 + 20)
21