diff --git a/libc3/env.c b/libc3/env.c
index baa7edf..6646d05 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -47,6 +47,7 @@
#include "struct_type.h"
#include "tag.h"
#include "tuple.h"
+#include "void.h"
s_env g_c3_env;
@@ -107,7 +108,6 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
{
u8 *data;
uw i;
- f_init_cast init_cast;
uw item_size;
s_tag *tag;
s_tag tag_eval;
@@ -119,8 +119,6 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
if (tmp.dimension) {
item_size = tmp.dimensions[tmp.dimension - 1].item_size;
if (! tmp.data && array->tags) {
- if (! sym_to_init_cast(tmp.type, &init_cast))
- return false;
tmp.data = tmp.data_free = calloc(tmp.dimensions[0].count,
tmp.dimensions[0].item_size);
if (! tmp.data) {
@@ -134,7 +132,7 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
while (i < tmp.count) {
if (! env_eval_tag(env, tag, &tag_eval))
goto ko;
- if (! init_cast(data, &tag_eval)) {
+ if (! void_init_cast(array->type, data, &tag_eval)) {
err_write_1("env_eval_array: cannot cast ");
err_inspect_tag(&tag_eval);
err_write_1(" to ");
@@ -670,10 +668,10 @@ bool env_eval_quote (s_env *env, const s_quote *quote, s_tag *dest)
bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
{
uw i;
- f_init_cast init_cast;
s_struct *t;
s_tag tag = {0};
s_tag tmp = {0};
+ const s_sym *type;
assert(env);
assert(s);
assert(dest);
@@ -690,11 +688,10 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
return false;
i = 0;
while (i < t->type.map.count) {
- if (! env_eval_tag(env, s->tag + i, &tag))
+ if (! tag_type(t->type.map.value + i, &type) ||
+ ! env_eval_tag(env, s->tag + i, &tag))
goto ko;
- if (! tag_type_to_init_cast(tag.type, &init_cast))
- goto ko_tag;
- if (tag.type != t->type.map.value[i].type && ! init_cast) {
+ if (! void_init_cast(type, (s8 *) t->data + t->type.offset[i], &tag)) {
warnx("env_eval_struct:"
" invalid type %s for key %s, expected %s.",
tag_type_to_string(tag.type),
@@ -702,8 +699,6 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
tag_type_to_string(t->type.map.value[i].type));
goto ko_tag;
}
- if (! init_cast((s8 *) t->data + t->type.offset[i], &tag))
- goto ko_tag;
i++;
}
*dest = tmp;
diff --git a/libc3/hash.c b/libc3/hash.c
index 3fc96be..7fa665c 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -19,6 +19,7 @@
#include "str.h"
#include "tag.h"
#include "tag_type.h"
+#include "void.h"
#define HASH_UPDATE_DEF(type) \
void hash_update_##type (t_hash *hash, const type *x) \
@@ -303,7 +304,6 @@ void hash_update_str (t_hash *hash, const s_str *str)
void hash_update_struct (t_hash *hash, const s_struct *s)
{
const void *data;
- f_hash_update hash_update_value;
uw i = 0;
const s_sym *sym;
s8 type[] = "struct";
@@ -314,14 +314,11 @@ void hash_update_struct (t_hash *hash, const s_struct *s)
hash_update(hash, &s->type.map.count, sizeof(s->type.map.count));
while (i < s->type.map.count) {
hash_update_tag(hash, s->type.map.key + i);
- if (! tag_type_to_hash_update(s->type.map.value[i].type,
- &hash_update_value))
+ if (! tag_type(s->type.map.value + i, &sym))
exit(1);
if (s->data)
data = (s8 *) s->data + s->type.offset[i];
else {
- if (! tag_type(s->type.map.value + i, &sym))
- exit(1);
if (s->tag) {
if (! tag_to_const_pointer(s->tag + i, sym, &data))
exit(1);
@@ -331,7 +328,7 @@ void hash_update_struct (t_hash *hash, const s_struct *s)
exit(1);
}
}
- hash_update_value(hash, data);
+ void_hash_update(sym, hash, data);
i++;
}
}
diff --git a/libc3/list.c b/libc3/list.c
index 96ddbae..2db912f 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -17,11 +17,11 @@
#include "buf.h"
#include "buf_inspect.h"
#include "buf_parse.h"
-#include "clean.h"
#include "list.h"
#include "sym.h"
#include "tag.h"
#include "tuple.h"
+#include "void.h"
void list_clean (s_list *list)
{
@@ -255,7 +255,6 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
{
s8 *data;
const void *data_list;
- f_init_copy init_copy;
const s_list *l;
uw len;
uw size;
@@ -291,23 +290,14 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
free(tmp.dimensions);
return NULL;
}
- if (! sym_to_init_copy(type, &init_copy)) {
- free(tmp.data);
- free(tmp.dimensions);
- return NULL;
- }
data = tmp.data;
l = list;
while (l) {
if (! tag_to_const_pointer(&l->tag, type, &data_list))
goto ko;
if (data_list) {
- if (init_copy) {
- if (! init_copy(data, data_list))
- goto ko;
- }
- else
- memcpy(data, data_list, size);
+ if (! void_init_copy(type, data, data_list))
+ goto ko;
}
data += size;
l = list_next(l);
@@ -318,7 +308,7 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
ko:
while (data > (s8 *) tmp.data) {
data -= size;
- clean(type, data);
+ void_clean(type, data);
}
free(tmp.data);
free(tmp.dimensions);
diff --git a/libc3/sequence.c b/libc3/sequence.c
index e5864de..2d02a0c 100644
--- a/libc3/sequence.c
+++ b/libc3/sequence.c
@@ -20,8 +20,8 @@ void sequence_clean (s_sequence *seq)
}
s_sequence * sequence_init (s_sequence *seq, f64 duration,
- const s8 *title, f_sequence_load load,
- f_sequence_render render)
+ const s8 *title, f_sequence load,
+ f_sequence render, f_sequence unload)
{
assert(seq);
seq->dt = 0.0;
@@ -30,6 +30,7 @@ s_sequence * sequence_init (s_sequence *seq, f64 duration,
seq->title = title;
seq->load = load;
seq->render = render;
+ seq->unload = unload;
tag_init_void(&seq->tag);
return seq;
}
diff --git a/libc3/sequence.h b/libc3/sequence.h
index f150359..1adf186 100644
--- a/libc3/sequence.h
+++ b/libc3/sequence.h
@@ -15,11 +15,11 @@
#include "types.h"
-/* Stack-allocation compatible functions, call sequence_clean after
- use. */
+/* Stack-allocation compatible functions, call sequence_clean
+ after use. */
void sequence_clean (s_sequence *seq);
s_sequence * sequence_init (s_sequence *sequence, f64 duration,
- const s8 *title, f_sequence_load load,
- f_sequence_render render);
+ const s8 *title, f_sequence load,
+ f_sequence render, f_sequence unload);
#endif /* LIBC3_SEQUENCE_H */
diff --git a/libc3/struct.c b/libc3/struct.c
index 05849ec..ae55f34 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -14,7 +14,6 @@
#include <err.h>
#include <stdlib.h>
#include <string.h>
-#include "clean.h"
#include "env.h"
#include "list.h"
#include "map.h"
@@ -23,6 +22,7 @@
#include "sym.h"
#include "tag.h"
#include "tag_type.h"
+#include "void.h"
s_struct * struct_allocate (s_struct *s)
{
@@ -50,7 +50,7 @@ void struct_clean (s_struct *s)
i = 0;
while (i < s->type.map.count) {
if (tag_type(s->type.map.value + i, &sym))
- clean(sym, (s8 *) s->data + s->type.offset[i]);
+ void_clean(sym, (s8 *) s->data + s->type.offset[i]);
i++;
}
if (s->free_data)
@@ -129,9 +129,7 @@ s_struct * struct_init_cast (s_struct *s, const s_tag *tag)
s_struct * struct_init_copy (s_struct *s, const s_struct *src)
{
- f_init_copy init_copy;
uw i;
- uw size;
const s_sym *sym;
s_struct tmp = {0};
assert(s);
@@ -143,23 +141,10 @@ s_struct * struct_init_copy (s_struct *s, const s_struct *src)
tmp.data = calloc(1, tmp.type.size);
i = 0;
while (i < tmp.type.map.count) {
- if (tag_type(tmp.type.map.value + i, &sym)) {
- if (! sym_to_init_copy(sym, &init_copy))
- goto ko;
- if (init_copy) {
- if (! init_copy((s8 *) tmp.data + tmp.type.offset[i],
- (s8 *) src->data + tmp.type.offset[i]))
- goto ko;
- }
- else {
- if (! tag_size(tmp.type.map.value + i, &size))
- goto ko;
- if (size)
- memcpy((s8 *) tmp.data + tmp.type.offset[i],
- (s8 *) src->data + tmp.type.offset[i],
- size);
- }
- }
+ if (! tag_type(tmp.type.map.value + i, &sym) ||
+ ! void_init_copy(sym, (s8 *) tmp.data + tmp.type.offset[i],
+ (s8 *) src->data + tmp.type.offset[i]))
+ goto ko;
i++;
}
}
@@ -301,9 +286,6 @@ s_struct * struct_set (s_struct *s, const s_sym *key,
void *data;
const void *data_src;
uw i;
- f_init_copy init_copy;
- uw size;
- e_tag_type type;
const s_sym *type_sym;
assert(s);
assert(s->type.map.count);
@@ -313,25 +295,15 @@ s_struct * struct_set (s_struct *s, const s_sym *key,
while (i < s->type.map.count) {
if (s->type.map.key[i].type == TAG_SYM &&
s->type.map.key[i].data.sym == key) {
- type = s->type.map.value[i].type;
- if (! tag_type_to_init_copy(type, &init_copy) ||
- ! tag_type(s->type.map.value + i, &type_sym))
+ if (! tag_type(s->type.map.value + i, &type_sym))
return NULL;
data = (s8 *) s->data + s->type.offset[i];
if (! tag_to_const_pointer(value, type_sym, &data_src))
return NULL;
- clean(type_sym, data);
- if (init_copy) {
- if (! init_copy(data, data_src))
- return NULL;
- return s;
- }
- else {
- if (! tag_size(s->type.map.value + i, &size))
- return NULL;
- if (size)
- memcpy((s8 *) data + s->type.offset[i], data_src, size);
- }
+ void_clean(type_sym, data);
+ if (! void_init_copy(type_sym, data, data_src))
+ return NULL;
+ return s;
}
i++;
}
diff --git a/libc3/sym.c b/libc3/sym.c
index 6a469cf..a3fa6e7 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -209,6 +209,7 @@ const s_sym * sym_new (const s_str *src)
return sym;
}
+/*
bool sym_to_buf_inspect (const s_sym *type, f_buf_inspect *dest)
{
if (type == sym_1("Array")) {
@@ -490,6 +491,8 @@ bool sym_to_buf_inspect_size (const s_sym *type, f_buf_inspect_size *dest)
assert(! "sym_to_buf_inspect_size: unknown type");
return false;
}
+*/
+
bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
ffi_type **dest)
{
@@ -617,6 +620,7 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
return false;
}
+/*
bool sym_to_init_cast (const s_sym *type, f_init_cast *dest)
{
if (type == sym_1("Array")) {
@@ -898,6 +902,7 @@ bool sym_to_init_copy (const s_sym *type, f_init_copy *dest)
assert(! "sym_to_init_copy: unknown type");
return false;
}
+*/
bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
{
diff --git a/libc3/tag.c b/libc3/tag.c
index be97bbe..a3921d1 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -985,14 +985,44 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
assert(tag);
assert(dest);
switch (tag->type) {
- case TAG_STRUCT:
- *dest = tag->data.struct_.type.module;
- return dest;
- default:
- break;
+ case TAG_VOID: *dest = sym_1("Void"); return dest;
+ case TAG_ARRAY: *dest = sym_1("Array"); return dest;
+ case TAG_BOOL: *dest = sym_1("Bool"); return dest;
+ case TAG_CALL: *dest = sym_1("Call"); return dest;
+ case TAG_CFN: *dest = sym_1("Cfn"); return dest;
+ case TAG_CHARACTER: *dest = sym_1("Character"); return dest;
+ case TAG_F32: *dest = sym_1("F32"); return dest;
+ case TAG_F64: *dest = sym_1("F64"); return dest;
+ case TAG_FACT: *dest = sym_1("Fact"); return dest;
+ case TAG_FN: *dest = sym_1("Fn"); return dest;
+ case TAG_IDENT: *dest = sym_1("Ident"); return dest;
+ case TAG_INTEGER: *dest = sym_1("Integer"); return dest;
+ case TAG_SW: *dest = sym_1("Sw"); return dest;
+ case TAG_S64: *dest = sym_1("S64"); return dest;
+ case TAG_S32: *dest = sym_1("S32"); return dest;
+ case TAG_S16: *dest = sym_1("S16"); return dest;
+ case TAG_S8: *dest = sym_1("S8"); return dest;
+ case TAG_U8: *dest = sym_1("U8"); return dest;
+ case TAG_U16: *dest = sym_1("U16"); return dest;
+ case TAG_U32: *dest = sym_1("U32"); return dest;
+ case TAG_U64: *dest = sym_1("U64"); return dest;
+ case TAG_UW: *dest = sym_1("Uw"); return dest;
+ case TAG_LIST: *dest = sym_1("List"); return dest;
+ case TAG_MAP: *dest = sym_1("Map"); return dest;
+ case TAG_PTAG: *dest = sym_1("Ptag"); return dest;
+ case TAG_PTR: *dest = sym_1("Ptr"); return dest;
+ case TAG_PTR_FREE: *dest = sym_1("PtrFree"); return dest;
+ case TAG_QUOTE: *dest = sym_1("Quote"); return dest;
+ case TAG_STR: *dest = sym_1("Str"); return dest;
+ case TAG_STRUCT: *dest = tag->data.struct_.type.module;
+ return dest;
+ case TAG_SYM: *dest = sym_1("Sym"); return dest;
+ case TAG_TUPLE: *dest = sym_1("Tuple"); return dest;
+ case TAG_VAR: *dest = sym_1("Var"); return dest;
}
- *dest = tag_type_to_sym(tag->type);
- return dest;
+ warnx("tag_type: unknown tag type: %d", tag->type);
+ assert(! "tag_type: unknown tag type");
+ return NULL;
}
bool tag_xor (const s_tag *a, const s_tag *b)
diff --git a/libc3/tag_type.c b/libc3/tag_type.c
index fc90f98..892114d 100644
--- a/libc3/tag_type.c
+++ b/libc3/tag_type.c
@@ -55,6 +55,7 @@ bool tag_type_size (e_tag_type type, uw *dest)
return false;
}
+/*
bool tag_type_to_buf_inspect (e_tag_type type, f_buf_inspect *dest)
{
switch (type) {
@@ -289,6 +290,7 @@ bool tag_type_to_env_eval (e_tag_type type, f_env_eval *dest)
assert(! "tag_type_to_env_eval: unknown tag type");
return false;
}
+*/
bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
{
@@ -332,6 +334,7 @@ bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
return false;
}
+/*
bool tag_type_to_hash_update (e_tag_type type, f_hash_update *p)
{
switch (type) {
@@ -469,6 +472,7 @@ const s8 * tag_type_to_string (e_tag_type type)
return NULL;
return sym->str.ptr.ps8;
}
+*/
const s_sym * tag_type_to_sym (e_tag_type tag_type)
{
diff --git a/libc3/void.c b/libc3/void.c
index 4c498df..c5c01d1 100644
--- a/libc3/void.c
+++ b/libc3/void.c
@@ -126,15 +126,159 @@ bool void_clean (const s_sym *type, void *data)
if (type == sym_1("Void")) {
return true;
}
+ /*
+ if (sym_is_array_type(type)) {
+ */
if (struct_type_exists(type)) {
s_struct s = {0};
struct_init_with_data(&s, type, false, data);
struct_clean(&s);
return true;
}
- err_write_1("sym_to_clean: unknown type: ");
+ err_write_1("void_clean: unknown type: ");
err_inspect_sym(&type);
err_write_1("\n");
- assert(! "sym_to_clean: unknown type");
+ assert(! "void_clean: unknown type");
+ return false;
+}
+
+bool void_init_copy (const s_sym *type, void *v, const void *src)
+{
+ if (type == sym_1("Array")) {
+ array_init_copy;
+ return true;
+ }
+ if (type == sym_1("Bool")) {
+ bool_init_copy;
+ return true;
+ }
+ if (type == sym_1("Call")) {
+ call_init_copy;
+ return true;
+ }
+ if (type == sym_1("Cfn")) {
+ cfn_init_copy;
+ return true;
+ }
+ if (type == sym_1("Character")) {
+ character_init_copy;
+ return true;
+ }
+ if (type == sym_1("F32")) {
+ f32_init_copy;
+ return true;
+ }
+ if (type == sym_1("F64")) {
+ f64_init_copy;
+ return true;
+ }
+ if (type == sym_1("Fact")) {
+ fact_init_copy;
+ return true;
+ }
+ if (type == sym_1("Fn")) {
+ fn_init_copy;
+ return true;
+ }
+ if (type == sym_1("Ident")) {
+ ident_init_copy;
+ return true;
+ }
+ if (type == sym_1("Integer")) {
+ integer_init_copy;
+ return true;
+ }
+ if (type == sym_1("List")) {
+ list_init_copy;
+ return true;
+ }
+ if (type == sym_1("Ptag")) {
+ ptag_init_copy;
+ return true;
+ }
+ if (type == sym_1("Ptr")) {
+ ptr_init_copy;
+ return true;
+ }
+ if (type == sym_1("PtrFree")) {
+ ptr_free_init_copy;
+ return true;
+ }
+ if (type == sym_1("Quote")) {
+ quote_init_copy;
+ return true;
+ }
+ if (type == sym_1("S8")) {
+ s8_init_copy;
+ return true;
+ }
+ if (type == sym_1("S16")) {
+ s16_init_copy;
+ return true;
+ }
+ if (type == sym_1("S32")) {
+ s32_init_copy;
+ return true;
+ }
+ if (type == sym_1("S64")) {
+ s64_init_copy;
+ return true;
+ }
+ if (type == sym_1("Str")) {
+ str_init_copy;
+ return true;
+ }
+ if (type == sym_1("Struct")) {
+ struct_init_copy;
+ return true;
+ }
+ if (type == sym_1("Sw")) {
+ sw_init_copy;
+ return true;
+ }
+ if (type == sym_1("Sym")) {
+ sym_init_copy;
+ return true;
+ }
+ if (type == sym_1("Tuple")) {
+ tuple_init_copy;
+ return true;
+ }
+ if (type == sym_1("U8")) {
+ u8_init_copy;
+ return true;
+ }
+ if (type == sym_1("U16")) {
+ u16_init_copy;
+ return true;
+ }
+ if (type == sym_1("U32")) {
+ u32_init_copy;
+ return true;
+ }
+ if (type == sym_1("U64")) {
+ u64_init_copy;
+ return true;
+ }
+ if (type == sym_1("Uw")) {
+ uw_init_copy;
+ return true;
+ }
+ if (type == sym_1("Var")) {
+ *dest = NULL;
+ return true;
+ }
+ if (type == sym_1("Void")) {
+ *dest = NULL;
+ return true;
+ }
+ if (struct_type_exists(type)) {
+ struct_init_copy;
+ return true;
+ }
+ err_write_1("void_init_copy: unknown type: ");
+ err_inspect_sym(&type);
+ err_write_1("\n");
+ assert(! "void_init_copy: unknown type");
return false;
}
diff --git a/libc3/void.h b/libc3/void.h
index 6be7bd5..142f033 100644
--- a/libc3/void.h
+++ b/libc3/void.h
@@ -24,6 +24,8 @@
sw void_buf_inspect (const s_sym *type, s_buf *buf, const void *v);
sw void_buf_inspect_size (const s_sym *type, const void *v);
bool void_clean (const s_sym *type, void *v);
+void void_hash_update (const s_sym *type, t_hash *hash,
+ const void *s);
void * void_init_cast (const s_sym *type, void *v, const s_tag *src);
void * void_init_copy (const s_sym *type, void *v, const void *src);