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: