Commit 3b2df74f47f8a1561dcbe7823a19674b32bbfb5e

Thomas de Grivel 2024-01-03T11:28:41

wip data and struct

diff --git a/libc3/env.c b/libc3/env.c
index 4841078..5d52e7e 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -468,6 +468,7 @@ bool env_eval_equal_tag (s_env *env, const s_tag *a, const s_tag *b,
   case TAG_PTR_FREE:
   case TAG_STR:
   case TAG_STRUCT:
+  case TAG_STRUCT_TYPE:
   case TAG_SYM:
   case TAG_VAR:
     if (compare_tag(a, b)) {
@@ -752,6 +753,7 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
   case TAG_S64:
   case TAG_SW:
   case TAG_STR:
+  case TAG_STRUCT_TYPE:
   case TAG_SYM:
   case TAG_U8:
   case TAG_U16:
@@ -1207,9 +1209,9 @@ s_struct_type * env_struct_type_find (s_env *env, const s_sym *module)
   if (tag_var.type != TAG_STRUCT_TYPE) {
     tag_type(&tag_var, &type);
     err_write_1("env_struct_type_find: module ");
-    err_inspect_sym(module);
+    err_inspect_sym(&module);
     err_write_1(": :struct_type is actually a ");
-    err_inspect_sym(type);
+    err_inspect_sym(&type);
     err_write_1("\n");
     assert(! "env_struct_type_find: invalid struct_type");
     return NULL;
diff --git a/libc3/hash.c b/libc3/hash.c
index 0831c2c..c09fb68 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -340,24 +340,24 @@ bool hash_update_struct (t_hash *hash, const s_struct *s)
   assert(hash);
   assert(s);
   if (! hash_update(hash, type, sizeof(type)) ||
-      ! hash_update_sym(hash, &s->type.module) ||
-      ! hash_update(hash, &s->type.map.count,
-                    sizeof(s->type.map.count)))
+      ! hash_update_sym(hash, &s->type->module) ||
+      ! hash_update(hash, &s->type->map.count,
+                    sizeof(s->type->map.count)))
     return false;
-  while (i < s->type.map.count) {
-    if (! hash_update_tag(hash, s->type.map.key + i))
+  while (i < s->type->map.count) {
+    if (! hash_update_tag(hash, s->type->map.key + i))
       return false;
-    if (! tag_type(s->type.map.value + i, &sym))
+    if (! tag_type(s->type->map.value + i, &sym))
       return false;
     if (s->data)
-      data = (s8 *) s->data + s->type.offset[i];
+      data = (s8 *) s->data + s->type->offset[i];
     else {
       if (s->tag) {
         if (! tag_to_const_pointer(s->tag + i, sym, &data))
           return false;
       }
       else {
-        if (! tag_to_const_pointer(s->type.map.value + i, sym, &data))
+        if (! tag_to_const_pointer(s->type->map.value + i, sym, &data))
           return false;
       }
     }
@@ -419,6 +419,8 @@ bool hash_update_tag (t_hash *hash, const s_tag *tag)
   case TAG_STR:   return hash_update_str(hash, &tag->data.str);
   case TAG_STRUCT:
     return hash_update_struct(hash, &tag->data.struct_);
+  case TAG_STRUCT_TYPE:
+    return hash_update_struct_type(hash, tag->data.struct_type);
   case TAG_SYM:   return hash_update_sym(hash, &tag->data.sym);
   case TAG_TUPLE: return hash_update_tuple(hash, &tag->data.tuple);
   case TAG_U8:    return hash_update_u8(hash, &tag->data.u8);
diff --git a/libc3/hash.h b/libc3/hash.h
index 04c7616..5b03a3e 100644
--- a/libc3/hash.h
+++ b/libc3/hash.h
@@ -49,6 +49,7 @@ HASH_UPDATE_PROTOTYPE(s64);
 HASH_UPDATE_PROTOTYPE(sw);
 bool hash_update_str (t_hash *hash, const s_str *str);
 bool hash_update_struct (t_hash *hash, const s_struct *s);
+bool hash_update_struct_type (t_hash *hash, const s_struct_type *st);
 bool hash_update_sym (t_hash *hash, const s_sym * const *sym);
 bool hash_update_tag (t_hash *hash, const s_tag *tag);
 bool hash_update_tuple (t_hash *hash, const s_tuple *tuple);
diff --git a/libc3/list.c b/libc3/list.c
index 50000cf..b7cc567 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -283,14 +283,14 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
     tmp.dimensions[0].count = len;
     tmp.dimensions[0].item_size = size;
     tmp.size = len * size;
-    tmp.data_free = calloc(len, size);
-    if (! tmp.data_free) {
+    tmp.free_data = calloc(len, size);
+    if (! tmp.free_data) {
       err_puts("list_to_array: out of memory: 2");
       assert(! "list_to_array: out of memory: 2");
       free(tmp.dimensions);
       return NULL;
     }
-    data = tmp.data = tmp.data_free;
+    data = tmp.data = tmp.free_data;
     l = list;
     while (l) {
       if (! tag_to_const_pointer(&l->tag, type, &data_list))
diff --git a/libc3/struct.c b/libc3/struct.c
index 62d56ce..bf0dbea 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -31,7 +31,7 @@ s_struct * struct_allocate (s_struct *s)
   assert(! s->data);
   tmp = *s;
   tmp.free_data = true;
-  tmp.data = calloc(1, tmp.type.size);
+  tmp.data = calloc(1, tmp.type->size);
   if (! tmp.data) {
     warn("struct_allocate: data");
     assert(! "struct_allocate: data: failed to allocate memory");
@@ -48,9 +48,9 @@ void struct_clean (s_struct *s)
   assert(s);
   if (s->data) {
     i = 0;
-    while (i < s->type.map.count) {
-      if (tag_type(s->type.map.value + i, &sym))
-        data_clean(sym, (s8 *) s->data + s->type.offset[i]);
+    while (i < s->type->map.count) {
+      if (tag_type(s->type->map.value + i, &sym))
+        data_clean(sym, (s8 *) s->data + s->type->offset[i]);
       i++;
     }
     if (s->free_data)
@@ -58,13 +58,12 @@ void struct_clean (s_struct *s)
   }
   if (s->tag) {
     i = 0;
-    while (i < s->type.map.count) {
+    while (i < s->type->map.count) {
       tag_clean(s->tag + i);
       i++;
     }
     free(s->tag);
   }
-  struct_type_clean(&s->type);
 }
 
 void struct_delete (s_struct *s)
@@ -80,9 +79,9 @@ bool struct_find_key_index (const s_struct *s, const s_sym *key,
   uw i = 0;
   assert(s);
   assert(key);
-  while (i < s->type.map.count) {
-    assert(s->type.map.key[i].type == TAG_SYM);
-    if (s->type.map.key[i].data.sym == key) {
+  while (i < s->type->map.count) {
+    assert(s->type->map.key[i].type == TAG_SYM);
+    if (s->type->map.key[i].data.sym == key) {
       *dest = i;
       return true;
     }
@@ -96,7 +95,8 @@ s_struct * struct_init (s_struct *s, const s_sym *module)
   s_struct tmp = {0};
   assert(s);
   assert(module);
-  if (! struct_type_init_from_env(&tmp.type, module, &g_c3_env))
+  tmp.type = struct_type_find(module);
+  if (! tmp.type)
     return NULL;
   *s = tmp;
   return s;
@@ -134,24 +134,24 @@ s_struct * struct_init_copy (s_struct *s, const s_struct *src)
   s_struct tmp = {0};
   assert(s);
   assert(src);
-  if (! struct_type_init_copy(&tmp.type, &src->type))
-    return NULL;
+  assert(src->type);
+  tmp.type = src->type;
   if (src->data) {
     tmp.free_data = true;
-    tmp.data = calloc(1, tmp.type.size);
+    tmp.data = calloc(1, tmp.type->size);
     i = 0;
-    while (i < tmp.type.map.count) {
-      if (! tag_type(tmp.type.map.value + i, &sym) ||
-          ! data_init_copy(sym, (s8 *) tmp.data + tmp.type.offset[i],
-                           (s8 *) src->data + tmp.type.offset[i]))
+    while (i < tmp.type->map.count) {
+      if (! tag_type(tmp.type->map.value + i, &sym) ||
+          ! data_init_copy(sym, (s8 *) tmp.data + tmp.type->offset[i],
+                           (s8 *) src->data + tmp.type->offset[i]))
         goto ko;
       i++;
     }
   }
   if (src->tag) {
-    tmp.tag = calloc(tmp.type.map.count, sizeof(s_tag));
+    tmp.tag = calloc(tmp.type->map.count, sizeof(s_tag));
     i = 0;
-    while (i < tmp.type.map.count) {
+    while (i < tmp.type->map.count) {
       if (! tag_init_copy(tmp.tag + i, src->tag + i))
         goto ko;
       i++;
@@ -177,7 +177,7 @@ s_struct * struct_init_from_lists (s_struct *s, const s_sym *module,
   assert(list_length(keys) == list_length(values));
   if (! struct_init(&tmp, module))
     return NULL;
-  tmp.tag = calloc(tmp.type.map.count, sizeof(s_tag));
+  tmp.tag = calloc(tmp.type->map.count, sizeof(s_tag));
   if (! tmp.tag) {
     warn("struct_init_from_lists: tag");
     assert(! "struct_init_from_lists: failed to allocate memory");
@@ -205,9 +205,9 @@ s_struct * struct_init_from_lists (s_struct *s, const s_sym *module,
     v = list_next(v);
   }
   i = 0;
-  while (i < tmp.type.map.count) {
+  while (i < tmp.type->map.count) {
     if (! tmp.tag[i].type)
-      if (! tag_init_copy(tmp.tag + i, tmp.type.map.value + i))
+      if (! tag_init_copy(tmp.tag + i, tmp.type->map.value + i))
         goto ko;
     i++;
   }
@@ -224,7 +224,8 @@ s_struct * struct_init_with_data (s_struct *s, const s_sym *module,
   s_struct tmp = {0};
   assert(s);
   assert(module);
-  if (! struct_type_init_from_env(&tmp.type, module, &g_c3_env))
+  tmp.type = struct_type_find(module);
+  if (! tmp.type)
     return NULL;
   tmp.free_data = free_data;
   tmp.data = data;
@@ -288,16 +289,16 @@ s_struct * struct_set (s_struct *s, const s_sym *key,
   uw i;
   const s_sym *type_sym;
   assert(s);
-  assert(s->type.map.count);
+  assert(s->type->map.count);
   assert(key);
   assert(value);
   i = 0;
-  while (i < s->type.map.count) {
-    if (s->type.map.key[i].type == TAG_SYM &&
-        s->type.map.key[i].data.sym == key) {
-      if (! tag_type(s->type.map.value + i, &type_sym))
+  while (i < s->type->map.count) {
+    if (s->type->map.key[i].type == TAG_SYM &&
+        s->type->map.key[i].data.sym == key) {
+      if (! tag_type(s->type->map.value + i, &type_sym))
         return NULL;
-      data = (s8 *) s->data + s->type.offset[i];
+      data = (s8 *) s->data + s->type->offset[i];
       if (! tag_to_const_pointer(value, type_sym, &data_src))
         return NULL;
       data_clean(type_sym, data);
diff --git a/libc3/tag.c b/libc3/tag.c
index a3921d1..d0429b7 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -174,18 +174,19 @@ void tag_clean (s_tag *tag)
 {
   assert(tag);
   switch (tag->type) {
-  case TAG_ARRAY:    array_clean(&tag->data.array);     break;
-  case TAG_CALL:     call_clean(&tag->data.call);       break;
-  case TAG_CFN:      cfn_clean(&tag->data.cfn);         break;
-  case TAG_FN:       fn_clean(&tag->data.fn);           break;
-  case TAG_INTEGER:  integer_clean(&tag->data.integer); break;
-  case TAG_LIST:     list_delete_all(tag->data.list);   break;
-  case TAG_MAP:      map_clean(&tag->data.map);         break;
-  case TAG_PTR_FREE: ptr_free_clean(&tag->data.ptr);    break;
-  case TAG_QUOTE:    quote_clean(&tag->data.quote);     break;
-  case TAG_STR:      str_clean(&tag->data.str);         break;
-  case TAG_STRUCT:   struct_clean(&tag->data.struct_);  break;
-  case TAG_TUPLE:    tuple_clean(&tag->data.tuple);     break;
+  case TAG_ARRAY:       array_clean(&tag->data.array);            break;
+  case TAG_CALL:        call_clean(&tag->data.call);              break;
+  case TAG_CFN:         cfn_clean(&tag->data.cfn);                break;
+  case TAG_FN:          fn_clean(&tag->data.fn);                  break;
+  case TAG_INTEGER:     integer_clean(&tag->data.integer);        break;
+  case TAG_LIST:        list_delete_all(tag->data.list);          break;
+  case TAG_MAP:         map_clean(&tag->data.map);                break;
+  case TAG_PTR_FREE:    ptr_free_clean(&tag->data.ptr);           break;
+  case TAG_QUOTE:       quote_clean(&tag->data.quote);            break;
+  case TAG_STR:         str_clean(&tag->data.str);                break;
+  case TAG_STRUCT:      struct_clean(&tag->data.struct_);         break;
+  case TAG_STRUCT_TYPE: struct_type_clean(tag->data.struct_type); break;
+  case TAG_TUPLE:       tuple_clean(&tag->data.tuple);            break;
   case TAG_BOOL:
   case TAG_CHARACTER:
   case TAG_F32: