Commit 0f07b9aedd9656f066d9b2feede158b9bf33d75a

Thomas de Grivel 2024-01-26T21:10:35

wip buf_parse_str_eval

diff --git a/README.md b/README.md
index 83dfd47..376f3db 100644
--- a/README.md
+++ b/README.md
@@ -297,8 +297,9 @@ Script interpreter. Works the same as ic3 but is not interactive.
      - negative facts : 4 + 2n = not 3 + 2n
      - with ignore variables
    - math
-     - fractions
+     - ratios
      - floating point numbers (decimals)
+     - floating point numbers (ieee854)
    - maps
      - get (get key value)
      - put (return a new map)
diff --git a/libc3/buf.c b/libc3/buf.c
index 3b02fe6..96527d5 100644
--- a/libc3/buf.c
+++ b/libc3/buf.c
@@ -829,6 +829,7 @@ sw buf_refill_compact (s_buf *buf)
 s_str * buf_slice_to_str (const s_buf *buf, uw start, uw end,
                           s_str *dest)
 {
+  s_str tmp;
   assert(buf);
   assert(dest);
   if (start > buf->wpos) {
@@ -846,7 +847,8 @@ s_str * buf_slice_to_str (const s_buf *buf, uw start, uw end,
     assert(! "buf_slice_to_str: end > wpos");
     return NULL;
   }
-  return str_init(dest, NULL, end - start, buf->ptr.ps8 + start);
+  str_init(&tmp, NULL, end - start, buf->ptr.pchar + start);
+  return str_init_copy(dest, &tmp);
 }
 
 sw buf_str_to_hex (s_buf *buf, const s_str *src)
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index c95772c..cef3618 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2566,21 +2566,24 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
   uw end;
   s_str in;
   s_buf in_buf = {0};
-  s_list *list;
+  s_list  *list;
   s_list **list_end;
+  s_list  *list_start;
   s_buf out_buf;
   sw r;
   sw result;
   s_buf_save save;
   uw start;
+  s_tag tmp;
+  s_tag tmp1;
   buf_save_init(buf, &save);
   r = buf_parse_str(buf, &in);
   if (r <= 0)
     goto clean;
   result = r;
   buf_init_str(&in_buf, false, &in);
-  list = NULL;
-  list_end = &list;
+  list_start = NULL;
+  list_end = &list_start;
   start = 0;
   while (1) {
     end = in_buf.rpos;
@@ -2588,10 +2591,12 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
     if (r < 0)
       goto restore;
     if (r > 0) {
-      *list_end = list_new(NULL);
-      (*list_end)->tag.type = TAG_STR;
-      buf_slice_to_str(&in_buf, start, end, &(*list_end)->tag.data.str);
-      list_end = &(*list_end)->next.data.list;
+      if (end > 0) {
+        *list_end = list_new(NULL);
+        (*list_end)->tag.type = TAG_STR;
+        buf_slice_to_str(&in_buf, start, end, &(*list_end)->tag.data.str);
+        list_end = &(*list_end)->next.data.list;
+      }
       *list_end = list_new(NULL);
       buf_parse_tag(&out_buf, &(*list_end)->tag);
       list_end = &(*list_end)->next.data.list;
@@ -2605,14 +2610,35 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
       if (r <= 0)
         goto restore;
       start = in_buf.rpos;
+      continue;
     }
     r = buf_read_character_utf8(&in_buf, &c);
+    if (r < 0)
+      goto restore;
+    if (! r)
+      break;
   }
+  if (! list_start)
+    tag_init_str_empty(&tmp);
+  else {
+    list = list_start;
+    if (list->tag.type == TAG_STR) {
+      tmp = list->tag;
+    }
+    while (list) {
+      if (list->tag.type == TAG_STR)
+        
   r = result;
   goto clean;
  restore:
   buf_save_restore_rpos(buf, &save);
  clean:
+  while (list_start) {
+    list = list_next(list_start);
+    free(list_start);
+    list_start = list;
+  }
+  str_clean(&in);
   buf_save_clean(buf, &save);
   return r;
 }
diff --git a/libc3/list_init.c b/libc3/list_init.c
index 3d18caa..d3b52aa 100644
--- a/libc3/list_init.c
+++ b/libc3/list_init.c
@@ -298,6 +298,17 @@ s_list * list_init_str_cat (s_list *list, const s_str *a,
   return list;
 }
 
+s_list * list_init_str_empty (s_list *list, s_list *next)
+{
+  s_list tmp;
+  assert(list);
+  list_init(&tmp, next);
+  if (! tag_init_str_empty(&tmp.tag))
+    return NULL;
+  *list = tmp;
+  return list;
+}
+
 s_list * list_init_struct (s_list *list, const s_sym *module, 
                            s_list *next)
 {
@@ -746,6 +757,19 @@ s_list * list_new_str_cat (const s_str *a, const s_str *b, s_list *next)
   return list;
 }
 
+s_list * list_new_str_empty (s_list *next)
+{
+  s_list *list;
+  list = list_new(next);
+  if (! list)
+    return NULL;
+  if (! tag_init_str_empty(&list->tag)) {
+    free(list);
+    return NULL;
+  }
+  return list;
+}
+
 s_list * list_new_struct (const s_sym *module, s_list *next)
 {
   s_list *list;
diff --git a/libc3/list_init.h b/libc3/list_init.h
index 418120b..9a2b0fe 100644
--- a/libc3/list_init.h
+++ b/libc3/list_init.h
@@ -49,6 +49,7 @@ s_list * list_init_str_1 (s_list *list, char *p_free, const char *p,
                           s_list *next);
 s_list * list_init_str_cat (s_list *list, const s_str *a, 
                             const s_str *b, s_list *next);
+s_list * list_init_str_empty (s_list *list, s_list *next);
 s_list * list_init_struct (s_list *list, const s_sym *module, 
                            s_list *next);
 s_list * list_init_struct_with_data (s_list *list, const s_sym *module, 
@@ -97,6 +98,7 @@ s_list * list_new_str (char *p_free, uw size, const char *p,
 s_list * list_new_str_1 (char *p_free, const char *p, s_list *next);
 s_list * list_new_str_cat (const s_str *a, const s_str *b, 
                            s_list *next);
+s_list * list_new_str_empty (s_list *next);
 s_list * list_new_struct (const s_sym *module, s_list *next);
 s_list * list_new_struct_with_data (const s_sym *module, 
                                     bool free_data, void *data, 
@@ -142,6 +144,7 @@ s_list * list_s64 (s_list *list, s64 i);
 s_list * list_str (s_list *list, char *p_free, uw size, const char *p);
 s_list * list_str_1 (s_list *list, char *p_free, const char *p);
 s_list * list_str_cat (s_list *list, const s_str *a, const s_str *b);
+s_list * list_str_empty (s_list *list);
 s_list * list_struct (s_list *list, const s_sym *module);
 s_list * list_struct_with_data (s_list *list, const s_sym *module, 
                                 bool free_data, void *data);
diff --git a/libc3/tag_init.c b/libc3/tag_init.c
index d12c67b..acba8d6 100644
--- a/libc3/tag_init.c
+++ b/libc3/tag_init.c
@@ -292,6 +292,17 @@ s_tag * tag_init_str_cat (s_tag *tag, const s_str *a, const s_str *b)
   return tag;
 }
 
+s_tag * tag_init_str_empty (s_tag *tag)
+{
+  s_tag tmp = {0};
+  assert(tag);
+  tmp.type = TAG_STR;
+  if (! str_init_empty(&tmp.data.str))
+    return NULL;
+  *tag = tmp;
+  return tag;
+}
+
 s_tag * tag_init_struct (s_tag *tag, const s_sym *module)
 {
   s_tag tmp = {0};
@@ -754,6 +765,21 @@ s_tag * tag_new_str_cat (const s_str *a, const s_str *b)
   return tag;
 }
 
+s_tag * tag_new_str_empty (void)
+{
+  s_tag *tag;
+  if (! (tag = calloc(1, sizeof(s_tag)))) {
+    warn("tag_new_str_empty: calloc");
+    return NULL;
+  }
+  tag->type = TAG_STR;
+  if (! str_init_empty(&tag->data.str)) {
+    free(tag);
+    return NULL;
+  }
+  return tag;
+}
+
 s_tag * tag_new_struct (const s_sym *module)
 {
   s_tag *tag;
@@ -1200,6 +1226,18 @@ s_tag * tag_str_cat (s_tag *tag, const s_str *a, const s_str *b)
   return tag;
 }
 
+s_tag * tag_str_empty (s_tag *tag)
+{
+  s_tag tmp = {0};
+  assert(tag);
+  tag_clean(tag);
+  tmp.type = TAG_STR;
+  if (! str_init_empty(&tmp.data.str))
+    return NULL;
+  *tag = tmp;
+  return tag;
+}
+
 s_tag * tag_struct (s_tag *tag, const s_sym *module)
 {
   s_tag tmp = {0};
diff --git a/libc3/tag_init.h b/libc3/tag_init.h
index e4662af..652d230 100644
--- a/libc3/tag_init.h
+++ b/libc3/tag_init.h
@@ -42,6 +42,7 @@ s_tag * tag_init_s64 (s_tag *tag, s64 i);
 s_tag * tag_init_str (s_tag *tag, char *p_free, uw size, const char *p);
 s_tag * tag_init_str_1 (s_tag *tag, char *p_free, const char *p);
 s_tag * tag_init_str_cat (s_tag *tag, const s_str *a, const s_str *b);
+s_tag * tag_init_str_empty (s_tag *tag);
 s_tag * tag_init_struct (s_tag *tag, const s_sym *module);
 s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module, 
                                    bool free_data, void *data);
@@ -85,6 +86,7 @@ s_tag * tag_new_s64 (s64 i);
 s_tag * tag_new_str (char *p_free, uw size, const char *p);
 s_tag * tag_new_str_1 (char *p_free, const char *p);
 s_tag * tag_new_str_cat (const s_str *a, const s_str *b);
+s_tag * tag_new_str_empty (void);
 s_tag * tag_new_struct (const s_sym *module);
 s_tag * tag_new_struct_with_data (const s_sym *module, bool free_data, 
                                   void *data);
@@ -128,6 +130,7 @@ s_tag * tag_s64 (s_tag *tag, s64 i);
 s_tag * tag_str (s_tag *tag, char *p_free, uw size, const char *p);
 s_tag * tag_str_1 (s_tag *tag, char *p_free, const char *p);
 s_tag * tag_str_cat (s_tag *tag, const s_str *a, const s_str *b);
+s_tag * tag_str_empty (s_tag *tag);
 s_tag * tag_struct (s_tag *tag, const s_sym *module);
 s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module, 
                               bool free_data, void *data);
diff --git a/libc3/tag_init.rb b/libc3/tag_init.rb
index a37224c..a5372c7 100644
--- a/libc3/tag_init.rb
+++ b/libc3/tag_init.rb
@@ -356,6 +356,7 @@ class TagInitList
        TagInit.new("str", "cat", "TAG_STR", :init_mode_init,
                    [Arg.new("const s_str *", "a"),
                     Arg.new("const s_str *", "b")]),
+       TagInit.new("str", "empty", "TAG_STR", :init_mode_init, []),
        TagInit.new("struct", "TAG_STRUCT", :init_mode_init,
                    [Arg.new("const s_sym *", "module")]),
        TagInit.new("struct", "with_data", "TAG_STRUCT", :init_mode_init,