Commit 0a5d95005037dceb72348b36ef97bd75ae951959

Thomas de Grivel 2024-01-27T12:37:57

wip str_eval

diff --git a/.ic3_history b/.ic3_history
index 94384ec..612f5b4 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,6 +1,3 @@
-type(1 + 1)
-type(2)
-1 + 1
 123.123
 (3)
 type(3)
@@ -97,3 +94,6 @@ hello("Tiyon")
 hello("Baptiste")
 "a"
 "abc"
+hello = fn (name) { "Hello, #{name} !" }
+hello("Thomas")
+hello = fn (name) { "Hello, #{name} !" }
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 6d55dd6..7443865 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -32,3 +32,6 @@ dlopen("/home/dx/c/thodg/c3-lang/c3/libc3/window/sdl2/.libs/libc3_window_sdl2.so
 (Ptr) 0x193a838c800
 type((Ptr) 0x193a838c800)
 type(0x193a838c800)
+"a"
+"abc"
+"abc#{1}"
diff --git a/lib/c3/0.1/str.facts b/lib/c3/0.1/str.facts
new file mode 100644
index 0000000..3d582ee
--- /dev/null
+++ b/lib/c3/0.1/str.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+  version: 1}
+replace {Str, :is_a, :module}
+replace {Str, :symbol, Str.cast}
+replace {Str.cast, :cfn, cfn Str "str_init_cast" (Result, Tag)}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 90e3dc0..e3003af 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2563,19 +2563,17 @@ sw buf_parse_str_character_unicode (s_buf *buf, character *dest)
 sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
 {
   character c;
-  uw end;
   s_str in;
-  s_buf in_buf = {0};
+  s_buf in_buf;
   s_list  *list;
   s_list **list_end;
   s_list  *list_start = NULL;
   s_ident op;
-  s_buf out_buf;
+  s_buf out_buf = {0};
   sw r;
   sw result;
   s_tag *right;
   s_buf_save save;
-  uw start;
   s_tag tmp = {0};
   s_tag tmp1 = {0};
   buf_save_init(buf, &save);
@@ -2584,22 +2582,25 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
     goto save_clean;
   result = r;
   buf_init_str(&in_buf, false, &in);
+  if (! buf_init_alloc(&out_buf, in.size)) {
+    r = -2;
+    goto restore;
+  }
   list_end = &list_start;
-  start = 0;
   while (1) {
-    end = in_buf.rpos;
     r = buf_read_1(&in_buf, "#{");
     if (r < 0)
       break;
     if (r > 0) {
-      if (end > start) {
+      if (out_buf.wpos > 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);
+        buf_read_to_str(&out_buf, &(*list_end)->tag.data.str);
         list_end = &(*list_end)->next.data.list;
+        out_buf.rpos = out_buf.wpos = 0;
       }
       *list_end = list_new(NULL);
-      r = buf_parse_tag(&out_buf, &(*list_end)->tag);
+      r = buf_parse_tag(&in_buf, &(*list_end)->tag);
       if (r <= 0)
         goto restore;
       list_end = &(*list_end)->next.data.list;
@@ -2612,19 +2613,21 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
       r = buf_read_1(&in_buf, "}");
       if (r <= 0)
         goto restore;
-      start = end = in_buf.rpos;
       continue;
     }
-    r = buf_read_character_utf8(&in_buf, &c);
+    r = buf_peek_character_utf8(&in_buf, &c);
     if (r <= 0)
       break;
+    r = buf_xfer(&out_buf, &in_buf, r);
+    if (r <= 0) {
+      r = -2;
+      goto restore;
+    }
   }
-  end = in_buf.rpos;
-  if (end > start) {
+  if (out_buf.wpos > 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;
+    buf_read_to_str(&out_buf, &(*list_end)->tag.data.str);
   }
   if (! list_start)
     tag_init_str_empty(&tmp);
@@ -2674,6 +2677,7 @@ sw buf_parse_str_eval (s_buf *buf, s_tag *dest)
     tag_clean(&list->tag);
     list = list_next(list);
   }
+  buf_clean(&out_buf);
   buf_save_restore_rpos(buf, &save);
  clean:
   while (list_start) {