Commit 1d42364d1e86c85c409f145812789ad76fced5a3

Thomas de Grivel 2023-07-29T16:48:37

ic3

diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index 10c0887..9732d2c 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -14,6 +14,7 @@ add {C3, :symbol, C3.<}
 add {C3, :symbol, C3.==}
 add {C3, :symbol, C3.>=}
 add {C3, :symbol, C3.>}
+add {C3, :symbol, C3._"()"}
 add {C3, :symbol, C3.break}
 add {C3, :symbol, C3.first}
 add {C3, :symbol, C3.||}
@@ -66,7 +67,10 @@ add {C3.!, :arity, 1}
 add {C3.!, :cfn, cfn :bool "tag_not" (:tag)}
 add {C3.!, :is_a, :operator}
 add {C3.!, :operator_precedence, 4}
-add {C3.!, :operator_associativity, :left}
+add {C3._"()", :arity, 1}
+add {C3._"()", :cfn, cfn :tag "tag_paren" (:tag)}
+add {C3._"()", :is_a, :operator}
+add {C3._"()", :operator_precedence, 4}
 add {C3.&&, :arity, 2}
 add {C3.&&, :cfn, cfn :bool "tag_and" (:tag, :tag)}
 add {C3.&&, :is_a, :operator}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 98e5bf5..29ee7f2 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -609,9 +609,6 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
       break;
     if (r > 0 && c == '\n')
       break;
-    if ((r = buf_ignore_spaces(buf)) < 0)
-      break;
-    result += r;
     r = buf_parse_ident_peek(buf, &next_op);
     if (r <= 0)
       break;
@@ -629,9 +626,15 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
       }
       result += r;
       tag_init_call(right, &tmp2);
-      if ((r = buf_ignore_spaces(buf)) < 0)
+      if ((r = buf_ignore_spaces_but_newline(buf)) < 0)
         break;
       result += r;
+      if ((r = buf_peek_character_utf8(buf, &c)) <= 0)
+        break;
+      if (r > 0 && c == '\n') {
+        r = -1;
+        break;
+      }
       r = buf_parse_ident_peek(buf, &next_op);
       if (r > 0)
         next_op_precedence = operator_precedence(&next_op);
@@ -689,6 +692,41 @@ sw buf_parse_call_op_unary (s_buf *buf, s_call *dest)
   return r;
 }
 
+sw buf_parse_call_paren (s_buf *buf, s_call *dest)
+{
+  sw r;
+  sw result = 0;
+  s_call tmp;
+  s_buf_save save;
+  call_init_op_unary(&tmp);
+  ident_init_1(&tmp.ident, "()");
+  buf_save_init(buf, &save);
+  if ((r = buf_read_1(buf, "(")) <= 0)
+    goto restore;
+  result += r;
+  if ((r = buf_ignore_spaces(buf)) < 0)
+    goto restore;
+  result += r;
+  if ((r = buf_parse_tag(buf, &tmp.arguments->tag)) <= 0)
+    goto restore;
+  result += r;
+  if ((r = buf_ignore_spaces(buf)) < 0)
+    goto restore;
+  result += r;
+  if ((r = buf_read_1(buf, ")")) <= 0)
+    goto restore;
+  result += r;
+  *dest = tmp;
+  r = result;
+  goto clean;
+ restore:
+  call_clean(&tmp);
+  buf_save_restore_rpos(buf, &save);
+ clean:
+  buf_save_clean(buf, &save);
+  return r;
+}
+
 sw buf_parse_cfn (s_buf *buf, s_cfn *dest)
 {
   s_list *arg_types = NULL;
@@ -2069,6 +2107,16 @@ sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest)
   return r;
 }
 
+sw buf_parse_tag_call_paren (s_buf *buf, s_tag *dest)
+{
+  sw r;
+  assert(buf);
+  assert(dest);
+  if ((r = buf_parse_call_paren(buf, &dest->data.call)) > 0)
+    dest->type = TAG_CALL;
+  return r;
+}
+
 sw buf_parse_tag_call_op_unary (s_buf *buf, s_tag *dest)
 {
   sw r;
@@ -2155,7 +2203,8 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
       goto restore;
     result += r;
   }
-  if ((r = buf_parse_tag_call_op_unary(buf, dest)) != 0 ||
+  if ((r = buf_parse_tag_call_paren(buf, dest)) != 0 ||
+      (r = buf_parse_tag_call_op_unary(buf, dest)) != 0 ||
       (r = buf_parse_tag_bool(buf, dest)) != 0 ||
       (r = buf_parse_tag_character(buf, dest)) != 0)
     goto end;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 64a01a1..9102496 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -50,6 +50,7 @@ sw buf_parse_call_args_paren (s_buf *buf, s_call *dest);
 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);
 sw buf_parse_call_op_unary (s_buf *buf, s_call *dest);
+sw buf_parse_call_paren (s_buf *buf, s_call *dest);
 sw buf_parse_cfn (s_buf *buf, s_cfn *dest);
 sw buf_parse_character (s_buf *buf, character *dest);
 sw buf_parse_comments (s_buf *buf);
@@ -88,6 +89,7 @@ sw buf_parse_tag_array (s_buf *buf, s_tag *dest);
 sw buf_parse_tag_bool (s_buf *buf, s_tag *dest);
 sw buf_parse_tag_call (s_buf *buf, s_tag *dest);
 sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest);
+sw buf_parse_tag_call_paren (s_buf *buf, s_tag *dest);
 sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest);
 sw buf_parse_tag_character (s_buf *buf, s_tag *dest);
 sw buf_parse_tag_fn (s_buf *buf, s_tag *dest);
diff --git a/libc3/tag.c b/libc3/tag.c
index c182a47..41076ce 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1536,6 +1536,11 @@ bool tag_or (const s_tag *a, const s_tag *b)
   return compare_tag(a, &f) != 0 || compare_tag(b, &f) != 0;
 }
 
+s_tag * tag_paren (s_tag *a)
+{
+  return a;
+}
+
 s_tag * tag_s8 (s_tag *tag, s8 x)
 {
   assert(tag);
diff --git a/libc3/tag.h b/libc3/tag.h
index 3ab71de..49256e8 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -96,6 +96,7 @@ e_bool             tag_is_bound_var (const s_tag *tag);
 e_bool             tag_is_number (const s_tag *tag);
 e_bool             tag_is_unbound_var (const s_tag *tag);
 s8                 tag_number_compare (const s_tag *a, const s_tag *b);
+s_tag *            tag_paren (s_tag *a);
 sw                 tag_size (const s_tag *tag);
 void *             tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
 ffi_type           tag_to_ffi_type(const s_tag *tag);