Commit 19a43eeb899d807f229b6dfa8a9c1ae34f436812

Thomas de Grivel 2023-03-13T17:41:50

wip

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 41fe637..a3c2e2b 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -110,7 +110,7 @@ sw buf_parse_call_args_paren (s_buf *buf, s_call *dest)
     if ((r = buf_parse_tag(buf, &tag)) <= 0)
       goto restore;
     result += r;
-    *args = list_new();
+    *args = list_new(NULL);
     (*args)->tag = tag; 
     if ((r = buf_parse_comments(buf)) < 0)
       goto restore;
@@ -205,6 +205,7 @@ sw buf_parse_call_op (s_buf *buf, s_call *dest)
 sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
 {
   s_tag *left;
+  s_list *next_arg;
   s_ident next_op;
   s8 next_op_precedence;
   s_ident op;
@@ -220,7 +221,11 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
   buf_save_init(buf, &save);
   call_init_op(&tmp);
   left = &tmp.arguments->tag;
-  right = &list_next(tmp.arguments)->tag;
+  printf("tmp.arguments=%p\n", (void *) tmp.arguments);
+  next_arg = list_next(tmp.arguments);
+  printf("next_arg=%p\n", (void *) next_arg);
+  right = &next_arg->tag;
+  printf("right=%p\n", (void *) right);
   *left = dest->arguments->tag;
   if ((r = buf_parse_ident_peek(buf, &next_op)) <= 0)
     goto clean;
@@ -230,7 +235,7 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
   }
   while (r && op_precedence >= min_precedence) {
     if ((r = buf_parse_ident(buf, &next_op)) <= 0)
-      goto clean;
+      goto restore;
     result += r;
     op = next_op;
     if ((r = buf_ignore_spaces(buf)) < 0)
@@ -242,29 +247,31 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
       goto restore;
     if ((r = buf_parse_ident_peek(buf, &next_op)) < 0)
       goto restore;
-    result += r;
-    next_op_precedence = operator_precedence(&next_op);
-    while (r && (next_op_precedence >= op_precedence ||
-                 (operator_is_right_associative(&next_op) &&
-                  next_op_precedence == op_precedence))) {
-      result += r;
-      call_init_op(&tmp2);
-      tmp2.arguments->tag = *right;
-      if ((r = buf_parse_call_op_rec(buf, &tmp2, (next_op_precedence > op_precedence) ? op_precedence + 1 : op_precedence)) <= 0)
-        goto restore;
-      bzero(right, sizeof(s_tag));
-      right->type.type = TAG_CALL;
-      right->data.call = tmp2;
+    if (r) {
       result += r;
-      if ((r = buf_ignore_spaces(buf)) < 0)
-        goto restore;
-      result += r;
-      if ((r = buf_parse_ident_peek(buf, &next_op)) < 0)
-        goto restore;
       next_op_precedence = operator_precedence(&next_op);
+      while (r && (next_op_precedence >= op_precedence ||
+                   (operator_is_right_associative(&next_op) &&
+                    next_op_precedence == op_precedence))) {
+        result += r;
+        call_init_op(&tmp2);
+        tmp2.arguments->tag = *right;
+        if ((r = buf_parse_call_op_rec(buf, &tmp2, (next_op_precedence > op_precedence) ? op_precedence + 1 : op_precedence)) <= 0)
+          goto restore;
+        bzero(right, sizeof(s_tag));
+        right->type.type = TAG_CALL;
+        right->data.call = tmp2;
+        result += r;
+        if ((r = buf_ignore_spaces(buf)) < 0)
+          goto restore;
+        result += r;
+        if ((r = buf_parse_ident_peek(buf, &next_op)) < 0)
+          goto restore;
+        next_op_precedence = operator_precedence(&next_op);
+      }
     }
-    if ((op_precedence = operator_precedence(&next_op)) < 0)
-      goto restore;
+    if ((op_precedence = next_op_precedence) < 0)
+      break;
     call_init_op(&tmp2);
     tmp2.ident = op;
     tmp2.arguments->tag = *left;
@@ -738,7 +745,7 @@ sw buf_parse_fn_algo (s_buf *buf, s_list **dest)
     if (! r)
       break;
     result += r;
-    *tail = list_new();
+    *tail = list_new(NULL);
     (*tail)->tag = tag;
     tail = &(*tail)->next.data.list;
     if ((r = buf_ignore_spaces(buf)) < 0)
@@ -787,7 +794,7 @@ sw buf_parse_fn_pattern (s_buf *buf, s_list **dest)
     if ((r = buf_parse_tag(buf, &tag)) <= 0)
       goto restore;
     result += r;
-    *tail = list_new();
+    *tail = list_new(NULL);
     (*tail)->tag = tag;
     tail = &(*tail)->next.data.list;
     if ((r = buf_ignore_spaces(buf)) < 0)
@@ -1124,7 +1131,7 @@ sw buf_parse_list (s_buf *buf, s_list **list)
   }
   *i = NULL;
   while (1) {
-    *i = list_new();
+    *i = list_new(NULL);
     if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
       goto restore;
     result += r;
@@ -1742,7 +1749,7 @@ sw buf_parse_tuple (s_buf *buf, s_tuple *tuple)
     if ((r = buf_ignore_spaces(buf)) < 0)
       goto restore;
     result += r;
-    *i = list_new();
+    *i = list_new(NULL);
     if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
       goto restore;
     result += r;
diff --git a/libc3/env.c b/libc3/env.c
index 4740ab7..7d6ddd0 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -132,7 +132,7 @@ bool env_eval_call_arguments (s_env *env, s_list *args, s_list **dest)
   s_list *tmp;
   t = &tmp;
   while (args) {
-    *t = list_new();
+    *t = list_new(NULL);
     if (! env_eval_tag(env, &args->tag, &(*t)->tag)) {
       list_delete_all(tmp);
       err_puts("env_eval_call_arguments: invalid argument: ");
@@ -220,7 +220,7 @@ bool env_eval_equal_list (s_env *env, const s_list *a, const s_list *b,
       goto ko;
     if (! b)
       goto ko;
-    *t = list_new();
+    *t = list_new(NULL);
     if (! env_eval_equal_tag(env, &a->tag, &b->tag, &(*t)->tag))
       goto ko;
     a_next = list_next(a);
diff --git a/libc3/list.c b/libc3/list.c
index a5edd3f..80aa47f 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -50,7 +50,7 @@ s_list * list_copy (const s_list *src, s_list **dest)
   s_list *result = NULL;
   *dest = NULL;
   while (src) {
-    *dest = list_new();
+    *dest = list_new(NULL);
     if (! result)
       result = *dest;
     tag_copy(&src->tag, &(*dest)->tag);
@@ -83,11 +83,11 @@ void list_delete_all (s_list *list)
     list = list_delete(list);
 }
 
-s_list * list_init (s_list *list)
+s_list * list_init (s_list *list, s_list *next)
 {
   assert(list);
   tag_init_void(&list->tag);
-  tag_init_list(&list->next, NULL);
+  tag_init_list(&list->next, next);
   return list;
 }
 
@@ -128,11 +128,11 @@ s_list * list_next (const s_list *list)
   }
 }
 
-s_list * list_new ()
+s_list * list_new (s_list *next)
 {
   s_list *list;
   list = calloc(1, sizeof(s_list));
   if (! list)
     errx(1, "list_new: out of memory");
-  return list_init(list);
+  return list_init(list, next);
 }
diff --git a/libc3/list.h b/libc3/list.h
index c104b4d..159c64b 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -26,12 +26,12 @@
 #include "types.h"
 
 /* Stack allocation compatible functions, do not use */
-s_list * list_init (s_list *list);
+s_list * list_init (s_list *list, s_list *next);
 void     list_clean (s_list *list);
 
 /* Constructors, call list_delete after use */
 s_list * list_1 (const s8 *p);
-s_list * list_new ();
+s_list * list_new (s_list *next);
 
 /* Destructor */
 s_list * list_delete (s_list *list);