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);