Commit 1643d7e29aaec54b552e0be497797cb478508d87

Thomas de Grivel 2023-06-26T16:34:13

wip buf_parse_array

diff --git a/README.md b/README.md
index 329f9a5..576ec4f 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,19 @@
 # C3 v0.1
 
-C3 is a programming language project, inspired by C, Elixir and
-Common Lisp. It could be described as C with Elixir modules,
+C3 is a programming language with meta-programmation and a graph
+database embedded into the language. It aims to be the language
+for semantic programming, and programming the semantic web.
+
+We are currently fundraising for the project to become real and
+there is a working prototype available at
+[https://git.kmx.io/c3-lang/c3/](https://git.kmx.io/c3-lang/c3/),
+please see the [donations](donations.html) page for donations.
+
+C3 is currently a programming language project, inspired by C, Elixir
+and Common Lisp. It could be described as C with Elixir modules,
 pattern matching, and a semantic object system. The idea is to plug
-modules, closures, pattern matching, cl-facts and metaprogramming
-into C99 with a very small set of dependencies.
+modules, closures, pattern matching, a graph database and
+metaprogramming into C99 with an extremely small set of dependencies.
 
 
 ## Structure
@@ -45,10 +54,10 @@ Script interpreter.
 
  - libc3
    - facts
-     - atomic operations
-     - DONE triple serial id
      - negative facts : 4 + 2n = not 3 + 2n
      - with ignore variables
+     - DONE atomic operations
+     - DONE triple serial id
    - math
      - floating point numbers
    - boolean operators
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index eb6bfb1..e667e09 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -389,6 +389,7 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
            (r = buf_read_1(buf, "[")) > 0) {
       if ((r = buf_ignore_spaces(buf)) < 0)
         goto restore_data;
+      printf("dim %lu [\n", i);
       i++;
     }
     if (r < 0)
@@ -399,18 +400,32 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
         r = -1;
         goto clean;
       }
+      address[i]++;
+      printf("dim %lu addr %lu\n", i, address[i]);
       if ((r = buf_ignore_spaces(buf)) < 0)
         goto restore_data;
       if ((r = buf_read_1(buf, ",")) < 0)
         goto restore_data;
-      if ((r = buf_ignore_spaces(buf)) < 0)
+      if (r > 0) {
+        if ((r = buf_ignore_spaces(buf)) < 0)
+          goto restore_data;
+        printf("dim %lu ,", i);
+        continue;
+      }
+      if ((r = buf_peek_1(buf, "]")) < 0)
         goto restore_data;
-      address[i]++;
+      if (r > 0) {
+        printf("dim %lu ] peek\n", i);
+        goto backtrack;
+      }
     }
+  backtrack:
+    printf("backtrack:\n");
     while ((r = buf_read_1(buf, "]")) > 0) {
+      printf("dim %lu ]\n", i);
       if (! tmp.dimensions[i].count) {
-        tmp.dimensions[i].count = address[i];
-        printf("\ndimension %lu = %lu\n", i, address[i]);
+        tmp.dimensions[i].count = address[i] + 1;
+        printf("\ndim %lu addr %lu\n", i, address[i]);
         if (i == tmp.dimension - 1)
           tmp.dimensions[i].item_size = item_size;
         else
@@ -423,11 +438,19 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
           errx(1, "buf_parse_array: dimension size mismatch");
           return -1;
         }
+      if (! i)
+        goto read_data;
       i--;
     }
     if (r < 0)
       goto restore_data;
   }
+ read_data:
+  i = 0;
+  while (i < tmp.dimension) {
+    address[i] = 0;
+    i++;
+  }
   i = tmp.dimension - 1;
   buf_save_restore_rpos(buf, &save_data);
   tmp.size = tmp.dimensions[0].count * tmp.dimensions[0].item_size;
@@ -439,7 +462,7 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
   }
   /* read data */
   item = tmp.data;
-  while (i > 0) {
+  while (1) {
     while (i < tmp.dimension - 1 &&
            (r = buf_read_1(buf, "[")) > 0) {
       result += r;
@@ -457,18 +480,26 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
         goto clean;
       }
       result += r;
+      address[i]++;
       item += item_size;
       if ((r = buf_ignore_spaces(buf)) < 0)
         goto restore_data;
       result += r;
       if ((r = buf_read_1(buf, ",")) < 0)
         goto restore_data;
-      result += r;
-      if ((r = buf_ignore_spaces(buf)) < 0)
+      if (r > 0) {
+        result += r;
+        if ((r = buf_ignore_spaces(buf)) < 0)
+          goto restore_data;
+        result += r;
+        continue;
+      }
+      if ((r = buf_peek_1(buf, "]")) < 0)
         goto restore_data;
-      result += r;
-      address[i]++;
+      if (r > 0)
+        goto backtrack_data;
     }
+  backtrack_data:
     while ((r = buf_read_1(buf, "]")) > 0) {
       result += r;
       if (tmp.dimensions[i].count != address[i]) {
@@ -476,11 +507,14 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
         errx(1, "buf_parse_array: dimension size mismatch");
         return -1;
       }
+      if (i == 0)
+        goto ok;
       i--;
     }
     if (r < 0)
       goto restore_data;
   }
+ ok:
   buf_save_clean(buf, &save_data);
   *dest = tmp;
   r = result;
@@ -2235,8 +2269,7 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
       goto restore;
     result += r;
   }
-  if ((r = buf_parse_tag_array(buf, dest)) != 0 ||
-      (r = buf_parse_tag_bool(buf, dest)) != 0 ||
+  if ((r = buf_parse_tag_bool(buf, dest)) != 0 ||
       (r = buf_parse_tag_character(buf, dest)) != 0)
     goto end;
   if ((r = buf_parse_tag_integer(buf, dest)) != 0) {
@@ -2251,7 +2284,9 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
       (r = buf_parse_tag_fn(buf, dest)) != 0 ||
       (r = buf_parse_tag_call(buf, dest)) != 0 ||
       (r = buf_parse_tag_ident(buf, dest)) != 0 ||
-      (r = buf_parse_tag_sym(buf, dest)) != 0)
+      (r = buf_parse_tag_sym(buf, dest)) != 0 ||
+      (r = buf_parse_tag_array(buf, dest)) != 0)
+      
     goto end;
   goto restore;
  end:
diff --git a/test/buf_parse_test.c b/test/buf_parse_test.c
index f130441..49bb3b2 100644
--- a/test/buf_parse_test.c
+++ b/test/buf_parse_test.c
@@ -18,22 +18,17 @@
 #include "test.h"
 #include "buf_parse_test_su.h"
 
-#define BUF_PARSE_TEST_ARRAY(test, expected)                           \
+#define BUF_PARSE_TEST_ARRAY(test)                                     \
   do {                                                                 \
-    s_buf buf_result;                                                  \
-    s_buf buf_test;                                                    \
+    s_buf buf;                                                         \
     s_array dest;                                                      \
-    test_context("buf_parse_array(" # test ") -> " # expected);        \
-    buf_init_1(&buf_test, (test));                                     \
-    TEST_EQ(buf_parse_array(&buf_test, &dest), strlen(test));          \
-    TEST_EQ(buf_inspect_array_size(&dest), strlen(expected));          \
-    TEST_EQ(buf_inspect_array(&buf_result, &dest), &buf_result);       \
-    TEST_EQ(buf_result.wpos, strlen(expected));                        \
-    TEST_STRNCMP(buf_result.ptr.p, (expected),                         \
-                 buf_result.wpos);                                     \
-    buf_clean(&buf_test);                                              \
+    test_context("buf_parse_array(" # test ")");                       \
+    buf_init_1(&buf, (test));                                          \
+    printf("%s\n", # test);                                            \
+    TEST_EQ(buf_parse_array(&buf, &dest), strlen(test));               \
+    TEST_EQ(buf.rpos, strlen(test));                                   \
+    buf_clean(&buf);                                                   \
     array_clean(&dest);                                                \
-    buf_clean(&buf_result);                                            \
     test_context(NULL);                                                \
   } while (0)
 
@@ -757,12 +752,11 @@ void buf_parse_test ()
 
 TEST_CASE(buf_parse_array)
 {
-  BUF_PARSE_TEST_ARRAY("(u8)[0]", "(u8) [0]");
-  BUF_PARSE_TEST_ARRAY("(u8) [0]", "(u8) [0]");
-  BUF_PARSE_TEST_ARRAY("(u8) [[0], [0]]", "(u8) [[0], [0]]");
-  BUF_PARSE_TEST_ARRAY("(u8) [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]",
-                       "(u8) [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]");
-  BUF_PARSE_TEST_ARRAY("(u8)[ [ 0 ],[ 0 ] ]", "(u8) [[0], [0]]");
+  BUF_PARSE_TEST_ARRAY("(u8)[0]");
+  BUF_PARSE_TEST_ARRAY("(u8) [0]");
+  BUF_PARSE_TEST_ARRAY("(u8) [[0], [0]]");
+  BUF_PARSE_TEST_ARRAY("(u8) [[[0, 1], [2, 3]], [[4, 5], [6, 7]]]");
+  BUF_PARSE_TEST_ARRAY("(u8)[ [ 0 ],[ 0 ] ]");
 }
 TEST_CASE_END(buf_parse_array)