Commit 728821777fe88ff82cf7eb0a1e43bc48f7efb51f

Thomas de Grivel 2023-09-07T10:51:28

wip segv

diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 6c06872..ff3995b 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -1435,6 +1435,7 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
     return buf_inspect_character(buf, &tag->data.character);
   case TAG_F32:     return buf_inspect_f32(buf, &tag->data.f32);
   case TAG_F64:     return buf_inspect_f64(buf, &tag->data.f64);
+  case TAG_FACT:    return buf_inspect_fact(buf, &tag->data.fact);
   case TAG_FN:      return buf_inspect_fn(buf, &tag->data.fn);
   case TAG_IDENT:   return buf_inspect_ident(buf, &tag->data.ident);
   case TAG_INTEGER: return buf_inspect_integer(buf, &tag->data.integer);
@@ -1474,6 +1475,7 @@ sw buf_inspect_tag_size (const s_tag *tag)
     return buf_inspect_character_size(&tag->data.character);
   case TAG_F32:      return buf_inspect_f32_size(&tag->data.f32);
   case TAG_F64:      return buf_inspect_f64_size(&tag->data.f64);
+  case TAG_FACT:     return buf_inspect_fact_size(&tag->data.fact);
   case TAG_FN:       return buf_inspect_fn_size(&tag->data.fn);
   case TAG_IDENT:    return buf_inspect_ident_size(&tag->data.ident);
   case TAG_INTEGER:
@@ -1520,6 +1522,8 @@ sw buf_inspect_tag_type (s_buf *buf, e_tag_type type)
     return buf_write_1(buf, "f32");
   case TAG_F64:
     return buf_write_1(buf, "f64");
+  case TAG_FACT:
+    return buf_write_1(buf, "fact");
   case TAG_FN:
     return buf_write_1(buf, "fn");
   case TAG_IDENT:
@@ -1585,6 +1589,8 @@ sw buf_inspect_tag_type_size (e_tag_type type)
     return strlen("f32");
   case TAG_F64:
     return strlen("f64");
+  case TAG_FACT:
+    return strlen("fact");
   case TAG_FN:
     return strlen("fn");
   case TAG_IDENT:
@@ -1626,8 +1632,8 @@ sw buf_inspect_tag_type_size (e_tag_type type)
   case TAG_VAR:
     return strlen("var");
   }
-  assert(! "buf_inspect_tag_type: unknown tag type");
-  errx(1, "buf_inspect_tag_type: unknown tag type");
+  assert(! "buf_inspect_tag_type_size: unknown tag type");
+  errx(1, "buf_inspect_tag_type_size: unknown tag type");
   return -1;
 }
 
diff --git a/libc3/env.c b/libc3/env.c
index d0c31c0..6bd423e 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -389,6 +389,7 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
   case TAG_BOOL:
   case TAG_CFN:
   case TAG_CHARACTER:
+  case TAG_FACT:
   case TAG_FN:
   case TAG_IDENT:
   case TAG_INTEGER:
@@ -532,6 +533,7 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
   case TAG_CHARACTER:
   case TAG_F32:
   case TAG_F64:
+  case TAG_FACT:
   case TAG_FN:
   case TAG_INTEGER:
   case TAG_PTAG:
@@ -631,8 +633,6 @@ void env_longjmp (s_env *env, jmp_buf *jmp_buf)
 bool env_module_load (s_env *env, const s_sym *name,
                       s_facts *facts)
 {
-  s_facts_with_cursor cursor;
-  s_fact *found;
   s_str path;
   s_tag tag_name;
   s_tag tag_load_time;
@@ -654,13 +654,8 @@ bool env_module_load (s_env *env, const s_sym *name,
   str_clean(&path);
   tag_init_sym(&tag_name, name);
   tag_init_sym(&tag_load_time, sym_1("load_time"));
-  tag_init_var(&tag_time);
-  facts_with(facts, &cursor, (t_facts_spec) {
-      &tag_name, &tag_load_time, &tag_time, NULL, NULL });
-  while ((found = facts_with_cursor_next(&cursor)))
-    facts_remove_fact(facts, found);
   tag_init_time(&tag_time);
-  facts_add_tags(facts, &tag_name, &tag_load_time, &tag_time);
+  facts_replace_tags(facts, &tag_name, &tag_load_time, &tag_time);
   return true;
 }
 
diff --git a/libc3/facts.c b/libc3/facts.c
index f77c846..25fa84e 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -23,6 +23,7 @@
 #include "facts.h"
 #include "facts_cursor.h"
 #include "facts_with.h"
+#include "list.h"
 #include "log.h"
 #include "set__fact.h"
 #include "set__tag.h"
@@ -86,6 +87,7 @@ s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
                              const s_tag *object)
 {
   s_facts_cursor cursor;
+  s_list *list;
   s_fact *f;
   s_tag var;
   assert(facts);
@@ -96,9 +98,15 @@ s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
   facts_lock_w(facts);
   facts_with_tags(facts, &cursor, (s_tag *) subject,
                   (s_tag *) predicate, &var);
-  while ((f = facts_cursor_next(&cursor)))
-    facts_remove_fact(facts, f);
+  while ((f = facts_cursor_next(&cursor))) {
+    list = list_new(NULL, list);
+    list->tag.data.fact = *f;
+  }
   facts_cursor_clean(&cursor);
+  while (list) {
+    facts_remove_fact(facts, &list->tag.data.fact);
+    list = list_delete(list);
+  }
   f = facts_add_tags(facts, subject, predicate, object);
   facts_lock_unlock_w(facts);
   return f;
diff --git a/libc3/hash.c b/libc3/hash.c
index 0feb005..57785c0 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -129,6 +129,9 @@ void hash_update_fact (t_hash *hash, const s_fact *fact)
   const s8 type[] = "fact";
   assert(hash);
   assert(fact);
+  assert(fact->subject);
+  assert(fact->predicate);
+  assert(fact->object);
   hash_update(hash, type, sizeof(type));
   hash_update_tag(hash, fact->subject);
   hash_update_tag(hash, fact->predicate);
@@ -273,6 +276,7 @@ void hash_update_tag (t_hash *hash, const s_tag *tag)
     hash_update_character(hash, tag->data.character);          break;
   case TAG_F32: hash_update_f32(hash, tag->data.f32);          break;
   case TAG_F64: hash_update_f64(hash, tag->data.f64);          break;
+  case TAG_FACT: hash_update_fact(hash, &tag->data.fact);      break;
   case TAG_FN: hash_update_fn(hash, &tag->data.fn);            break;
   case TAG_IDENT: hash_update_ident(hash, &tag->data.ident);   break;
   case TAG_INTEGER:
diff --git a/libc3/tag.c b/libc3/tag.c
index 262f08d..3ccab16 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1362,6 +1362,7 @@ void tag_clean (s_tag *tag)
   case TAG_CHARACTER:
   case TAG_F32:
   case TAG_F64:
+  case TAG_FACT:
   case TAG_IDENT:
   case TAG_PTAG:
   case TAG_S8:
@@ -1423,6 +1424,7 @@ s_tag * tag_copy (const s_tag *src, s_tag *dest)
   case TAG_CHARACTER:
   case TAG_F32:
   case TAG_F64:
+  case TAG_FACT:
   case TAG_IDENT:
   case TAG_PTAG:
   case TAG_S8:
@@ -3680,6 +3682,10 @@ void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type)
     if (type == sym_1("f64"))
       return &tag->data.f64;
     goto invalid_type;
+  case TAG_FACT:
+    if (type == sym_1("fact"))
+      return &tag->data.fact;
+    goto invalid_type;
   case TAG_FN:
     if (type == sym_1("fn"))
       return &tag->data.fn;
@@ -3800,6 +3806,8 @@ void * tag_to_pointer (s_tag *tag, e_tag_type type)
     return &tag->data.f32;
   case TAG_F64:
     return &tag->data.f64;
+  case TAG_FACT:
+    return &tag->data.fact;
   case TAG_FN:
     return &tag->data.fn;
   case TAG_IDENT:
@@ -3873,6 +3881,8 @@ sw tag_type_size (e_tag_type type)
     return sizeof(f32);
   case TAG_F64:
     return sizeof(f64);
+  case TAG_FACT:
+    return sizeof(s_fact);
   case TAG_FN:
     return sizeof(s_fn);
   case TAG_IDENT:
@@ -3937,6 +3947,8 @@ f_buf_inspect tag_type_to_buf_inspect (e_tag_type type)
     return (f_buf_inspect) buf_inspect_f32;
   case TAG_F64:
     return (f_buf_inspect) buf_inspect_f64;
+  case TAG_FACT:
+    return (f_buf_inspect) buf_inspect_fact;
   case TAG_FN:
     return (f_buf_inspect) buf_inspect_fn;
   case TAG_IDENT:
@@ -4001,6 +4013,8 @@ f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type)
     return (f_buf_inspect_size) buf_inspect_f32_size;
   case TAG_F64:
     return (f_buf_inspect_size) buf_inspect_f64_size;
+  case TAG_FACT:
+    return (f_buf_inspect_size) buf_inspect_fact_size;
   case TAG_FN:
     return (f_buf_inspect_size) buf_inspect_fn_size;
   case TAG_IDENT:
@@ -4066,6 +4080,8 @@ f_buf_parse tag_type_to_buf_parse (e_tag_type type)
     return (f_buf_parse) buf_parse_f32;
   case TAG_F64:
     return (f_buf_parse) buf_parse_f64;
+  case TAG_FACT:
+    return (f_buf_parse) buf_parse_fact;
   case TAG_FN:
     return (f_buf_parse) buf_parse_fn;
   case TAG_IDENT:
@@ -4129,6 +4145,8 @@ ffi_type * tag_type_to_ffi_type (e_tag_type type)
     return &ffi_type_float;
   case TAG_F64:
     return &ffi_type_double;
+  case TAG_FACT:
+    return &ffi_type_pointer;
   case TAG_FN:
     return &ffi_type_pointer;
   case TAG_IDENT:
@@ -4188,6 +4206,7 @@ s8 * tag_type_to_string (e_tag_type type)
   case TAG_CHARACTER: return "character";
   case TAG_F32: return "f32";
   case TAG_F64: return "f64";
+  case TAG_FACT: return "fact";
   case TAG_FN: return "fn";
   case TAG_IDENT: return "ident";
   case TAG_INTEGER: return "integer";
@@ -4225,6 +4244,7 @@ const s_sym * tag_type_to_sym (e_tag_type tag_type)
   case TAG_CHARACTER:  return sym_1("character");
   case TAG_F32:        return sym_1("f32");
   case TAG_F64:        return sym_1("f64");
+  case TAG_FACT:       return sym_1("fact");
   case TAG_FN:         return sym_1("fn");
   case TAG_IDENT:      return sym_1("ident");
   case TAG_INTEGER:    return sym_1("integer");
diff --git a/libc3/types.h b/libc3/types.h
index 8d90dbf..a7cd61d 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -75,6 +75,7 @@ typedef enum {
   TAG_CHARACTER,
   TAG_F32,
   TAG_F64,
+  TAG_FACT,
   TAG_FN,
   TAG_IDENT,
   TAG_INTEGER,
@@ -343,6 +344,7 @@ union tag_data {
   character    character;
   f32          f32;
   f64          f64;
+  s_fact       fact;
   s_fn         fn;
   s_ident      ident;
   s_integer    integer;