Commit 147decaf87fa7d782c9bae5f448ce437c1e79edb

Thomas de Grivel 2023-04-02T16:48:56

array

diff --git a/libc3/array.h b/libc3/array.h
index 72afdaf..2294c92 100644
--- a/libc3/array.h
+++ b/libc3/array.h
@@ -16,6 +16,7 @@
 #include "types.h"
 
 void      array_clean (s_array *a);
+s_array * array_copy (const s_array *src, s_array *dest);
 s_array * array_init (s_array *a, uw dimension, const uw *sizes);
 void *    array_data (const s_array *a, const uw *address);
 
diff --git a/libc3/hash.c b/libc3/hash.c
index 61a580e..e928d29 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -78,11 +78,17 @@ void hash_update_array (t_hash *hash, const s_array *a)
   assert(hash);
   assert(a);
   hash_update(hash, type, sizeof(type));
-  
+  hash_update(hash, &a->dimension, sizeof(a->dimension));
+  hash_update(hash, &a->type, sizeof(a->type));
+  hash_update(hash, &a->sizes, a->dimension * sizeof(uw));
+  hash_update(hash, a->data, a->size);
 }
 
 void hash_update_bool (t_hash *hash, e_bool x)
 {
+  const s8 type[] = "bool";
+  assert(hash);
+  hash_update(hash, type, sizeof(type));
   bool b = x ? 1 : 0;
   hash_update(hash, &b, sizeof(b));
 }
@@ -90,8 +96,10 @@ void hash_update_bool (t_hash *hash, e_bool x)
 
 void hash_update_call (t_hash *hash, const s_call *call)
 {
+  const s8 type[] = "call";
   assert(hash);
   assert(call);
+  hash_update(hash, type, sizeof(type));
   hash_update_ident(hash, &call->ident);
   hash_update_list(hash, call->arguments);
 }
@@ -114,10 +122,10 @@ HASH_UPDATE_DEF(f64)
 
 void hash_update_fact (t_hash *hash, const s_fact *fact)
 {
-  const u8 type = 3;
+  const s8 type[] = "fact";
   assert(hash);
   assert(fact);
-  hash_update(hash, &type, sizeof(type));
+  hash_update(hash, type, sizeof(type));
   hash_update_tag(hash, fact->subject);
   hash_update_tag(hash, fact->predicate);
   hash_update_tag(hash, fact->object);
@@ -125,10 +133,18 @@ void hash_update_fact (t_hash *hash, const s_fact *fact)
 
 void hash_update_fn (t_hash *hash, const s_fn *fn)
 {
+  uw count = 0;
+  const s_fn *f;
   const s8 type[] = "fn";
   assert(hash);
   assert(fn);
   hash_update(hash, type, sizeof(type));
+  f = fn;
+  while (f) {
+    count++;
+    f = f->next_clause;
+  }
+  hash_update_uw(hash, count);
   while (fn) {
     hash_update_list(hash, fn->pattern);
     hash_update_list(hash, fn->algo);
@@ -164,9 +180,12 @@ void hash_update_integer (t_hash *hash, const s_integer *i)
 /* FIXME: circular lists */
 void hash_update_list (t_hash *hash, const s_list *list)
 {
+  uw count;
   const s_list *last;
   const s8 type[] = "list";
   hash_update(hash, type, sizeof(type));
+  count = list_length(list);
+  hash_update_uw(hash, count);
   if (list) {
     while (list) {
       hash_update_tag(hash, &list->tag);
@@ -224,6 +243,7 @@ void hash_update_tag (t_hash *hash, const s_tag *tag)
   hash_update_u64(hash, tag->type.type);
   switch (tag->type.type) {
   case TAG_VOID: break;
+  case TAG_ARRAY: hash_update_array(hash, &tag->data.array);   break;
   case TAG_BOOL: hash_update_bool(hash, tag->data.bool);       break;
   case TAG_CALL:
   case TAG_CALL_FN:
@@ -273,3 +293,4 @@ HASH_UPDATE_DEF(u8)
 HASH_UPDATE_DEF(u16)
 HASH_UPDATE_DEF(u32)
 HASH_UPDATE_DEF(u64)
+HASH_UPDATE_DEF(uw)
diff --git a/libc3/hash.h b/libc3/hash.h
index 6fd7251..c44a370 100644
--- a/libc3/hash.h
+++ b/libc3/hash.h
@@ -49,5 +49,6 @@ HASH_UPDATE_PROTOTYPE(u8);
 HASH_UPDATE_PROTOTYPE(u16);
 HASH_UPDATE_PROTOTYPE(u32);
 HASH_UPDATE_PROTOTYPE(u64);
+HASH_UPDATE_PROTOTYPE(uw);
 
 #endif /* HASH_H */
diff --git a/libc3/tag.c b/libc3/tag.c
index 8f3ccea..1eea36e 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -291,12 +291,12 @@ s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest)
        tag_type_to_string(b->type.type));
 }
 
-s_tag * tag_array (s_tag *tag, s_array *a)
+s_tag * tag_array (s_tag *tag, const s_array *a)
 {
   assert(tag);
   assert(a);
   tag_clean(tag);
-  return tag_init_array(a);
+  return tag_init_array(tag, a);
 }
 
 s_tag * tag_bool (s_tag *tag, bool b)
@@ -389,6 +389,7 @@ void tag_clean (s_tag *tag)
 {
   assert(tag);
   switch (tag->type.type) {
+  case TAG_ARRAY:      array_clean(&tag->data.array);     break;
   case TAG_CALL:
   case TAG_CALL_FN:
   case TAG_CALL_MACRO: call_clean(&tag->data.call);       break;
@@ -426,9 +427,13 @@ s_tag * tag_copy (const s_tag *src, s_tag *dest)
   assert(dest);
   switch (src->type.type) {
   case TAG_VAR:
-    error("tag_copy: TAG_VAR");
+    tag_init_var(dest);
+    break;
   case TAG_VOID:
     break;
+  case TAG_ARRAY:
+    array_copy(&src->data.array, &dest->data.array);
+    break;
   case TAG_CALL:
   case TAG_CALL_FN:
   case TAG_CALL_MACRO:
@@ -1468,7 +1473,7 @@ s_tag * tag_new_1 (const s8 *p)
   return tag_init_1(tag, p);
 }
 
-s_tag * tag_new_array (s_array *a)
+s_tag * tag_new_array (const s_array *a)
 {
   s_tag *dest;
   assert(a);
@@ -1848,6 +1853,7 @@ s8 * tag_type_to_string (e_tag_type type)
 {
   switch (type) {
   case TAG_VOID: return "void";
+  case TAG_ARRAY: return "array";
   case TAG_BOOL: return "bool";
   case TAG_CALL: return "call";
   case TAG_CALL_FN: return "call_fn";
diff --git a/libc3/tag.h b/libc3/tag.h
index 16379ec..ca2b3ce 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -33,7 +33,7 @@ extern s_tag g_tag_last;
 /* Stack allocation compatible functions */
 s_tag * tag_init (s_tag *tag);
 s_tag * tag_init_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_array (s_tag *tag, s_array *a);
+s_tag * tag_init_array (s_tag *tag, const s_array *a);
 s_tag * tag_init_bool (s_tag *tag, bool p);
 s_tag * tag_init_call (s_tag *tag, const s_call *call);
 s_tag * tag_init_character (s_tag *tag, character c);
@@ -66,7 +66,7 @@ void    tag_clean (s_tag *tag);
 /* Constructors, call tag_delete after use */
 s_tag * tag_new ();
 s_tag * tag_new_1 (const s8 *p);
-s_tag * tag_new_array (s_array *a);
+s_tag * tag_new_array (const s_array *a);
 s_tag * tag_new_bool (bool p);
 s_tag * tag_new_character (character c);
 s_tag * tag_new_copy (const s_tag *src);
@@ -102,7 +102,7 @@ s8 *    tag_type_to_string (e_tag_type type);
 
 /* Modifiers */
 s_tag * tag_1 (s_tag *tag, const s8 *p);
-s_tag * tag_array (s_tag *tag, s_array *a);
+s_tag * tag_array (s_tag *tag, const s_array *a);
 s_tag * tag_bool (s_tag *tag, bool p);
 s_tag * tag_cast_integer_to_s16 (s_tag *tag);
 s_tag * tag_cast_integer_to_s32 (s_tag *tag);