Commit 2ff624a53911216ecf0dd0f2cc0910d1c2913407

Thomas de Grivel 2024-08-17T12:53:43

fix struct_access on Var, facts_with_tags works !

diff --git a/.ikc3_history b/.ikc3_history
index fa20a8e..ece84e2 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,3 +1,27 @@
+server = Socket.listen("192.168.2.50", "58000")
+server_client = Socket.Buf.accept(server)
+req = HTTP.Request.buf_parse(server_client.buf_rw.r)
+%HTTP.Response{}
+Struct.offset(%HTTP.Response{}, :message)
+Sym.type_size(Str)
+Struct.offset(%HTTP.Response{}, :message)
+res = %HTTP.Response{}
+res.message
+Sym.type_size(Str)
+Sym.type_size(HTTP.Response)
+Struct.offset(%HTTP.Response{}, :message)
+Sym.type_size(Str)
+Struct.offset(%HTTP.Response{}, :code)
+Struct.offset(%HTTP.Response{}, :message)
+Struct.offset(%HTTP.Response{}, :response)
+Struct.offset(%HTTP.Response{}, :protocol)
+Struct.offset(%HTTP.Response{}, :code)
+Struct.offset(%HTTP.Response{}, :message)
+Struct.offset(%HTTP.Response{}, :headers)
+Struct.offset(%HTTP.Response{}, :body)
+Struct.offset(%HTTP.Response{}, :message)
+Struct.offset(%HTTP.Response{}, :protocol)
+Struct.offset(%HTTP.Response{}, :code)
 Struct.offset(%HTTP.Response{}, :message)
 Struct.offset(%HTTP.Response{}, :headers)
 Struct.offset(%HTTP.Response{}, :body)
@@ -19,82 +43,58 @@ Struct.offset(%HTTP.Response{}, :body)
 quote "a#{a}"
 "a#{a}"
 "a#{:a}"
+quote "a#{a}"
+quote "a#{:a}"
+quote "a"
+quote "a #{:a}"
+"a #{:a}"
+"""a #{:a}"""
+"""a #{":a"}"""
+quote """a #{":a"}"""
+"""a #{":a"}"""
+quote "a#{a}"
 quote "a#{:a}"
-quote "a#{%KC3.Operator{}}"
-quote "a#{%KC3.Operator{sym: :-}}"
-type(18446744073709551615)
-18446744073709551615
-type(4294967296)
-type( -2147483648)
-type(4294967296)
-type(-9223372036854775808)
-File.exists?("env")
-File.exists?("env4")
-File.exists?("lib/kc3/0.1/file.kc3")
-File.stat("env")
-File.stat("env").st_mode
-def is_directory? = fn (path) { List.has(File.stat(path).st_mode, :directory) }
-File.stat("libkc3").st_mode
-List.has
-def is_directory? = fn (path) { List.has(File.stat(path).st_mode, :directory) }
-List.has
-List.has?
-is_directory?("env")
-def is_directory? = fn (path) { List.has?(File.stat(path).st_mode, :directory) }
-is_directory?("env")
-is_directory?("libkc3")
-def is_directory? = fn (path) { List.has?(File.stat(path).st_mode, :directory) }
-File.is_directory?("env")
-File.is_directory?("libkc3")
-File.is_directory?("plop1234")
-File.is_directory?("env")
-File.list(lib)
-File.list("lib")
-File.list("lib/kc3")
-File.list("lib/kc3/0.1")
-Str.starts_with?("abc", "a")
-Str.starts_with?("abc", "b")
-Str.ends_with?("abc", "b")
-Str.ends_with?("abc", "c")
-Str.ends_with?("abc/", "/")
-File.read("env")
-HTTP.mime_type_load("test/httpd/mime.types")
-HTTP.mime_type("txt")
-HTTP.mime_type("html")
-HTTP.mime_type("zorglub")
-HTTP.mime_type_load("test/httpd/mime.types")
-HTTP.mime_type("zorglub")
-HTTP.mime_type_def(:zorglub, :application/zorglub)
-HTTP.mime_type("zorglub")
-Str.rindex("abc.def", ".")
-Str.rindex_character("abc.def", '.')
-File.ext("abc.def")
-require HTTPd
-HTTP.Event.version
-HTTP.Event.version()
-%KC3.Operator{}
-quote %{a: %{b: "b", c: "c"}, d: "d"}
-%KC3.Operator{}
-%{op1: %KC3.Operator{}, op2: %KC3.Operator{}}
-quote do do do 1 2 3 end end end
-quote do do do 1; 2; 3 end end end
-if true do
-1
-else
-quote if true do if true do 1 else 2 end else if true do 3 else 4 end end
-%Fact{}
-Fact.subject(%Fact{})
-Facts.env_facts
-Fact.subject(%Fact{})
-%Socket.Buf{}
-quote quote quote %Socket.Buf{}
-quote quote quote %Socket.Buf{sockfd: (S32) 1}
-"#{%Socket.Buf{}}"
-%HTTP.Request{}
-"#{%HTTP.Request{}}"
-"#{%HTTP.Request{headers: [{"Content-Type", "text/html"}]}}"
-req = %HTTP.Request{headers: [{"Content-Type", "text/html"}]}
-#{req}
-"#{req}"
-req = %HTTP.Request{headers: ["Content-Type" => "text/html"]}
+quote """a#{:a}"""
+quote """a#{"a"}"""
+quote """a#{:a}"""
+quote """a #{:a}"""
+quote "a #{:a}"
+quote "a"
+%Time{}
+Facts.env_facts()
+(Facts) Facts.env_facts()
+Facts.with_tags(Facts.env_facts(), ?, ?, ?)
+cursor = Facts.with_tags(Facts.env_facts(), ?, ?, ?)
+tuple = {?, ?, ?}
+cursor = Facts.with_tuple(Facts.env_facts(), tuple)
+a = ?
+b = ?
+c = ?
+s = ?
+p = ?
+o = ?
+cursor = Facts.with_tags(Facts.env_facts(), s, p, o)
+ptr = Facts.Cursor.next(cursor)
+s = ?
+p = ?
+o = ?
+cursor = Facts.with_tags(Facts.env_facts(), s, p, o)
+ptr = Facts.Cursor.next(cursor)
+Fact.from_ptr(ptr)
+tuple = {?, ?, ?}
+cursor = Facts.with_tuple(Facts.env_facts(), tuple)
+ptr = Facts.Cursor.next(cursor)
+tuple = {?, ?, ?}
+cursor = Facts.with_tuple(Facts.env_facts(), tuple)
+while (ptr = Facts.Cursor.next(cursor)) do
+  f = Fact.from_ptr(ptr)
+  puts((Tag) f.subject)
+  puts((Tag) f.predicate)
+  puts((Tag) f.object)
+end
+Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact) })
+Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact); void })
+Facts.with_tags(Facts.env_facts(), KC3, ?, ?, fn (fact) { puts(fact); void })
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact); void })
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
 
diff --git a/ikc3/.ikc3_history b/ikc3/.ikc3_history
index 1778370..4ccc89a 100644
--- a/ikc3/.ikc3_history
+++ b/ikc3/.ikc3_history
@@ -1,5 +1,3 @@
-22
-server = Socket.listen("192.168.1.50
 2
 server = Socket.listen("192.168.2.50", "58000")
 server_client = Socket.Buf.accept(server)
@@ -97,4 +95,5 @@ while (ptr = Facts.Cursor.next(cursor)) do
 end
 Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact) })
 Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact); void })
-
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact); void })
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
diff --git a/libkc3/map.c b/libkc3/map.c
index 475d1c8..19a4e5b 100644
--- a/libkc3/map.c
+++ b/libkc3/map.c
@@ -108,6 +108,21 @@ const s_sym ** map_get_type (const s_map *map, const s_tag *key,
   return NULL;
 }
 
+const s_sym ** map_get_var_type (const s_map *map, const s_tag *key,
+                                 const s_sym **dest)
+{
+  uw i = 0;
+  while (i < map->count) {
+    if (compare_tag(key, map->key + i) == 0)
+      return tag_var_type(map->value + i, dest);
+    i++;
+  }
+  err_write_1("map_get_type: ");
+  err_inspect_tag(key);
+  err_puts(": key not found");
+  return NULL;
+}
+
 s_map * map_init (s_map *map, uw count)
 {
   s_map tmp = {0};
diff --git a/libkc3/map.h b/libkc3/map.h
index a1bc363..f2f9996 100644
--- a/libkc3/map.h
+++ b/libkc3/map.h
@@ -41,6 +41,8 @@ s_map *        map_cast (const s_tag *tag, s_map *map);
 s_tag *        map_get (const s_map *map, const s_tag *key, s_tag *dest);
 const s_sym ** map_get_type (const s_map *map, const s_tag *key,
                              const s_sym **dest);
+const s_sym ** map_get_var_type (const s_map *map, const s_tag *key,
+                                 const s_sym **dest);
 s_map *        map_update (const s_map *map, const s_tag *key,
                            const s_tag *value, s_map *dest);
 s_map *        map_update_list (const s_map *map, const s_list *alist,
diff --git a/libkc3/struct.c b/libkc3/struct.c
index 55006f6..559b1ac 100644
--- a/libkc3/struct.c
+++ b/libkc3/struct.c
@@ -70,19 +70,21 @@ s_tag * struct_access_sym (const s_struct *s, const s_sym *key, s_tag *dest)
   const s_sym *type;
   s_tag tmp = {0};
   void *tmp_data;
-  if (! struct_get_type(s, key, &type))
-    return NULL;
+  if (! struct_get_var_type(s, key, &type))
+    return NULL;    
   data = struct_get(s, key);
   if (! data)
     return NULL;
-  if (! sym_to_tag_type(type, &tmp.type))
-    return NULL;
-  if (! struct_type_find(type, &st))
-    return NULL;
-  if (st) {
-    tmp.data.struct_.type = st;
-    if (! struct_allocate(&tmp.data.struct_))
+  if (type != &g_sym_Tag) {
+    if (! sym_to_tag_type(type, &tmp.type))
       return NULL;
+    if (! struct_type_find(type, &st))
+      return NULL;
+    if (st) {
+      tmp.data.struct_.type = st;
+      if (! struct_allocate(&tmp.data.struct_))
+        return NULL;
+    }
   }
   if (! tag_to_pointer(&tmp, type, &tmp_data))
     return NULL;
@@ -199,6 +201,14 @@ u8 struct_get_u8 (const s_struct *s, const s_sym *key)
   return *(u8 *) struct_get(s, key);
 }
 
+const s_sym ** struct_get_var_type (const s_struct *s, const s_sym *key,
+                                    const s_sym **dest)
+{
+  s_tag tag_key;
+  tag_init_sym(&tag_key, key);
+  return map_get_var_type(&s->type->map, &tag_key, dest);
+}
+
 s_struct * struct_init (s_struct *s, const s_sym *module)
 {
   s_struct tmp = {0};
diff --git a/libkc3/struct.h b/libkc3/struct.h
index f61ffb3..b13bd47 100644
--- a/libkc3/struct.h
+++ b/libkc3/struct.h
@@ -59,6 +59,8 @@ const s_sym ** struct_get_type (const s_struct *s, const s_sym *key,
 const s_sym ** struct_get_sym (const s_struct *s, const s_sym *key);
 const s_tag *  struct_get_tag (const s_struct *s, const s_sym *key);
 u8             struct_get_u8 (const s_struct *s, const s_sym *key);
+const s_sym ** struct_get_var_type (const s_struct *s, const s_sym *key,
+                                    const s_sym **dest);
 uw *           struct_offset (const s_struct *s,
                               const s_sym * const *key,
                               uw *dest);
diff --git a/libkc3/tag.c b/libkc3/tag.c
index b07a303..21e1534 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -1362,6 +1362,10 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
 bool tag_to_pointer (s_tag *tag, const s_sym *type, void **dest)
 {
   e_tag_type tag_type;
+  if (type == &g_sym_Tag) {
+    *dest = tag;
+    return true;
+  }
   if (! sym_to_tag_type(type, &tag_type))
     return false;
   if (tag->type != tag_type) {
@@ -1495,6 +1499,17 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
   return NULL;
 }
 
+const s_sym ** tag_var_type (const s_tag *tag, const s_sym **dest)
+{
+  assert(tag);
+  assert(dest);
+  if (tag->type == TAG_VAR) {
+    *dest = tag->data.var.type;
+    return dest;
+  }
+  return tag_type(tag, dest);
+}
+
 bool tag_xor (const s_tag *a, const s_tag *b)
 {
   s_tag f;
diff --git a/libkc3/tag.h b/libkc3/tag.h
index f61507a..c18fcd7 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -59,6 +59,7 @@ const s_tag *  tag_resolve_cow (const s_tag *tag);
 uw *           tag_size (const s_tag *tag, uw *dest);
 ffi_type       tag_to_ffi_type(const s_tag *tag);
 const s_sym ** tag_type (const s_tag *tag, const s_sym **type);
+const s_sym ** tag_var_type (const s_tag *tag, const s_sym **type);
 
 /* Operators. */
 s_tag * tag_1 (s_tag *tag, const char *p);
diff --git a/test/ikc3/facts_with_tags.kc3 b/test/ikc3/facts_with_tags.kc3
new file mode 100644
index 0000000..9ebc9cd
--- /dev/null
+++ b/test/ikc3/facts_with_tags.kc3
@@ -0,0 +1,8 @@
+quote Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) {
+  puts(fact.object)
+  void
+})
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) {
+  puts(fact.object)
+  void
+})
diff --git a/test/ikc3/facts_with_tags.out.expected b/test/ikc3/facts_with_tags.out.expected
new file mode 100644
index 0000000..269d066
--- /dev/null
+++ b/test/ikc3/facts_with_tags.out.expected
@@ -0,0 +1,30 @@
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
+operator_eq
+operator_gt
+operator_lt
+operator_or
+operator_add
+operator_and
+operator_bor
+operator_div
+operator_gte
+operator_lte
+operator_mod
+operator_mul
+operator_neg
+operator_not
+operator_pin
+operator_sub
+operator_addi
+operator_band
+operator_bnot
+operator_bxor
+operator_equal
+operator_paren
+operator_not_eq
+operator_require
+operator_brackets
+operator_defstruct
+operator_shift_left
+operator_shift_right
+void
diff --git a/test/ikc3/facts_with_tags.ret.expected b/test/ikc3/facts_with_tags.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/facts_with_tags.ret.expected
@@ -0,0 +1 @@
+0