Commit dfee496aff2dc821b21fc035fd95d94030f65249

Thomas de Grivel 2024-08-31T11:15:36

fix buf_parse_call_op

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