diff --git a/.ic3_history b/.ic3_history
index f69c6e6..5f0d4c2 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,13 +1,3 @@
-Map.map(%{a: 1, b: 2, c: 3}, fn (k, v) { {k, v} })
-to_list = fn (map = %{}) { Map.map(map, fn (k, v) { {k, v} })
-to_list(%{a: 1, b: b})
-to_list = fn (map) { Map.map(map, fn (k, v) { {k, v} })
-to_list(%{a: 1, b: b})
-to_list = fn (map) { Map.map(map, fn (k, v) { {k, v} } }
-to_list = fn (m) { Map.map(m, fn (k, v) { {k, v} } }
-to_list = fn (m) { Map.map(m, fn (k, v) { {k, v} }) }
-to_list = fn (map = %{}) { Map.map(map, fn (k, v) { {k, v} }) }
-to_list(%{a: 1, b: b})
to_list(%{a: 1, b: 2})
to_list = fn (map) { Map.map(map, fn (k, v) { {k, v} }) }
to_list(%{a: 1, b: 2})
@@ -97,3 +87,13 @@ type(quote 1 + 2)
123.123
1234567.0f
1.234f
+%GL.Point2D{}
+GL.Point2D
+type(GL.Point2D)
+quote %GL.Point2D{}
+GL.Point2D{
+GL.Point2D{}
+GL.Point2D{}}
+GL.Point2D{}
+GL.Point2D
+{}
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 49dc973..0020cd2 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -22,3 +22,4 @@ quote (void) 0
quote (Void) 0
type((Void) 0)
quote (Void) 0
+%GL.Point2D{}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index b12b10c..17f5158 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2622,6 +2622,7 @@ sw buf_parse_struct (s_buf *buf, s_struct *dest)
sw r;
sw result = 0;
s_buf_save save;
+ s_struct tmp = {0};
s_list *values = NULL;
s_list **values_end;
assert(buf);
@@ -2648,61 +2649,72 @@ sw buf_parse_struct (s_buf *buf, s_struct *dest)
result += r;
if ((r = buf_read_1(buf, "}")) < 0)
goto restore;
- result += r;
- if (r == 0) {
- while (1) {
- *keys_end = list_new(NULL);
- if ((r = buf_parse_map_key(buf, &(*keys_end)->tag)) <= 0)
- goto restore;
- result += r;
- keys_end = &(*keys_end)->next.data.list;
- if ((r = buf_parse_comments(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_ignore_spaces(buf)) < 0)
- goto restore;
- result += r;
- *values_end = list_new(NULL);
- if ((r = buf_parse_tag(buf, &(*values_end)->tag)) <= 0)
- goto restore;
- result += r;
- values_end = &(*values_end)->next.data.list;
- if ((r = buf_parse_comments(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_ignore_spaces(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_read_1(buf, "}")) < 0)
- goto restore;
- result += r;
- if (r > 0)
- break;
- if ((r = buf_read_1(buf, ",")) <= 0)
- goto restore;
- result += r;
- if ((r = buf_parse_comments(buf)) < 0)
- goto restore;
- result += r;
- if ((r = buf_ignore_spaces(buf)) < 0)
- goto restore;
- result += r;
- r = 0;
+ if (r > 0) {
+ result += r;
+ if (! struct_init(&tmp, module)) {
+ err_write_1("buf_parse_struct: struct_init ");
+ err_inspect_sym(&module);
+ err_puts(".");
+ r = -2;
+ goto clean;
}
+ goto ok;
}
- if (! struct_init_from_lists(dest, module, keys, values)) {
+ while (1) {
+ *keys_end = list_new(NULL);
+ if ((r = buf_parse_map_key(buf, &(*keys_end)->tag)) <= 0)
+ goto restore;
+ result += r;
+ keys_end = &(*keys_end)->next.data.list;
+ if ((r = buf_parse_comments(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ *values_end = list_new(NULL);
+ if ((r = buf_parse_tag(buf, &(*values_end)->tag)) <= 0)
+ goto restore;
+ result += r;
+ values_end = &(*values_end)->next.data.list;
+ if ((r = buf_parse_comments(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_read_1(buf, "}")) < 0)
+ goto restore;
+ result += r;
+ if (r > 0)
+ break;
+ if ((r = buf_read_1(buf, ",")) <= 0)
+ goto restore;
+ result += r;
+ if ((r = buf_parse_comments(buf)) < 0)
+ goto restore;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ goto restore;
+ result += r;
r = 0;
- goto restore;
}
+ if (! struct_init_from_lists(&tmp, module, keys, values)) {
+ err_write_1("buf_parse_struct: struct_init_from_lists ");
+ err_inspect_sym(&module);
+ err_puts(".");
+ r = -2;
+ goto clean;
+ }
+ ok:
+ *dest = tmp;
r = result;
- list_delete_all(keys);
- list_delete_all(values);
goto clean;
restore:
- list_delete_all(keys);
- list_delete_all(values);
buf_save_restore_rpos(buf, &save);
clean:
+ list_delete_all(keys);
+ list_delete_all(values);
buf_save_clean(buf, &save);
return r;
}
diff --git a/libc3/compare.c b/libc3/compare.c
index 613d93c..c7d62f2 100644
--- a/libc3/compare.c
+++ b/libc3/compare.c
@@ -787,30 +787,55 @@ s8 compare_tag (const s_tag *a, const s_tag *b) {
if (a->type > b->type)
return 1;
switch (a->type) {
- case TAG_VOID: return 0;
- case TAG_ARRAY: return compare_array(&a->data.array, &b->data.array);
- case TAG_BOOL: return compare_bool(a->data.bool, b->data.bool);
- case TAG_CALL: return compare_call(&a->data.call, &b->data.call);
- case TAG_CFN: return compare_cfn(&a->data.cfn, &b->data.cfn);
- case TAG_CHARACTER: return compare_character(a->data.character,
- b->data.character);
- case TAG_FACT: return compare_fact(&a->data.fact, &b->data.fact);
- case TAG_FN: return compare_fn(&a->data.fn, &b->data.fn);
- case TAG_IDENT: return compare_ident(&a->data.ident, &b->data.ident);
- case TAG_LIST: return compare_list(a->data.list, b->data.list);
- case TAG_MAP: return compare_map(&a->data.map, &b->data.map);
- case TAG_PTAG: return compare_ptag(a->data.ptag, b->data.ptag);
- case TAG_QUOTE: return compare_quote(&a->data.quote, &b->data.quote);
- case TAG_STR: return compare_str(&a->data.str, &b->data.str);
- case TAG_SYM: return compare_str(&a->data.sym->str,
- &b->data.sym->str);
- case TAG_TUPLE: return compare_tuple(&a->data.tuple, &b->data.tuple);
- case TAG_VAR: return compare_ptr(a, b);
- default:
+ case TAG_VOID: return 0;
+ case TAG_ARRAY: return compare_array(&a->data.array,
+ &b->data.array);
+ case TAG_BOOL: return compare_bool(a->data.bool, b->data.bool);
+ case TAG_CALL: return compare_call(&a->data.call,
+ &b->data.call);
+ case TAG_CFN: return compare_cfn(&a->data.cfn, &b->data.cfn);
+ case TAG_CHARACTER: return compare_character(a->data.character,
+ b->data.character);
+ case TAG_FACT: return compare_fact(&a->data.fact,
+ &b->data.fact);
+ case TAG_FN: return compare_fn(&a->data.fn, &b->data.fn);
+ case TAG_IDENT: return compare_ident(&a->data.ident,
+ &b->data.ident);
+ case TAG_LIST: return compare_list(a->data.list, b->data.list);
+ case TAG_MAP: return compare_map(&a->data.map, &b->data.map);
+ case TAG_PTAG: return compare_ptag(a->data.ptag, b->data.ptag);
+ case TAG_PTR: return compare_ptr(a->data.ptr.p, b->data.ptr.p);
+ case TAG_PTR_FREE: return compare_ptr(a->data.ptr_free.p,
+ b->data.ptr_free.p);
+ case TAG_QUOTE: return compare_quote(&a->data.quote,
+ &b->data.quote);
+ case TAG_STR: return compare_str(&a->data.str, &b->data.str);
+ case TAG_STRUCT: return compare_struct(&a->data.struct_,
+ &b->data.struct_);
+ case TAG_STRUCT_TYPE:return compare_struct_type(&a->data.struct_type,
+ &b->data.struct_type);
+ case TAG_SYM: return compare_str(&a->data.sym->str,
+ &b->data.sym->str);
+ case TAG_TUPLE: return compare_tuple(&a->data.tuple,
+ &b->data.tuple);
+ case TAG_VAR: return compare_ptr(a, b);
+ case TAG_F32:
+ case TAG_F64:
+ case TAG_INTEGER:
+ case TAG_S8:
+ case TAG_S16:
+ case TAG_S32:
+ case TAG_S64:
+ case TAG_SW:
+ case TAG_U8:
+ case TAG_U16:
+ case TAG_U32:
+ case TAG_U64:
+ case TAG_UW:
break;
}
- assert(! "compare_tag: error");
- errx(1, "compare_tag");
+ warnx("compare_tag: unknown tag type: %d", a->type);
+ assert(! "compare_tag: unknown tag type");
return 0;
}
diff --git a/libc3/compare.h b/libc3/compare.h
index 2504285..bb6db50 100644
--- a/libc3/compare.h
+++ b/libc3/compare.h
@@ -44,6 +44,8 @@ COMPARE_PROTOTYPE(s16);
COMPARE_PROTOTYPE(s32);
COMPARE_PROTOTYPE(s64);
s8 compare_str (const s_str *a, const s_str *b);
+s8 compare_struct (const s_struct *a, const s_struct *b);
+s8 compare_struct_type (const s_struct_type *a, const s_struct_type *b);
s8 compare_sym (const s_sym *a, const s_sym *b);
s8 compare_tag (const s_tag *a, const s_tag *b);
s8 compare_tuple (const s_tuple *a, const s_tuple *b);
diff --git a/libc3/env.c b/libc3/env.c
index ff2f617..9896fb2 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -835,8 +835,9 @@ s_env * env_init (s_env *env, int argc, s8 **argv)
return env;
}
-s_list ** env_get_struct_type_spec (s_env *env, const s_sym *module,
- s_list **dest)
+const s_list ** env_get_struct_type_spec (s_env *env,
+ const s_sym *module,
+ const s_list **dest)
{
s_facts_cursor cursor;
s_tag tag_defstruct;
@@ -924,8 +925,12 @@ void env_longjmp (s_env *env, jmp_buf *jmp_buf)
bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
{
s_str path;
+ s_struct_type *st;
+ const s_list *st_spec;
s_tag tag_module_name;
s_tag tag_load_time;
+ s_tag tag_st = {0};
+ s_tag tag_struct_type;
s_tag tag_time;
assert(env);
assert(module);
@@ -935,6 +940,7 @@ bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
module->str.ptr.ps8);
return false;
}
+ tag_init_time(&tag_time);
if (facts_load_file(facts, &path) < 0) {
warnx("env_module_load: %s: facts_load_file",
path.ptr.ps8);
@@ -943,10 +949,16 @@ bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
}
str_clean(&path);
tag_init_sym(&tag_module_name, module);
- tag_init_sym(&tag_load_time, sym_1("load_time"));
- tag_init_time(&tag_time);
+ tag_init_sym_1(&tag_load_time, "load_time");
facts_replace_tags(facts, &tag_module_name, &tag_load_time, &tag_time);
tag_clean(&tag_time);
+ if (env_get_struct_type_spec(env, module, &st_spec)) {
+ tag_init_sym_1(&tag_struct_type, "struct_type");
+ tag_st.type = TAG_STRUCT_TYPE;
+ st = &tag_st.data.struct_type;
+ struct_type_init(st, module, st_spec);
+ facts_replace_tags(facts, &tag_module_name, &tag_struct_type, &tag_st);
+ }
return true;
}
diff --git a/libc3/env.h b/libc3/env.h
index da6e8f9..74db809 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -64,9 +64,9 @@ bool env_eval_tag (s_env *env, const s_tag *tag,
bool env_eval_tuple (s_env *env, const s_tuple *tuple,
s_tag *dest);
bool env_eval_void (s_env *env, const void *_, s_tag *dest);
-s_list ** env_get_struct_type_spec (s_env *env,
- const s_sym *module,
- s_list **dest);
+const s_list ** env_get_struct_type_spec (s_env *env,
+ const s_sym *module,
+ const s_list **dest);
bool env_module_load (s_env *env, const s_sym *module,
s_facts *facts);
bool env_module_maybe_reload (s_env *env,
diff --git a/libc3/struct_type.c b/libc3/struct_type.c
index bc315a4..40735ab 100644
--- a/libc3/struct_type.c
+++ b/libc3/struct_type.c
@@ -127,18 +127,15 @@ s_struct_type * struct_type_init_from_env (s_struct_type *st,
const s_sym *module,
s_env *env)
{
- s_list *spec;
+ const s_list *spec;
assert(st);
assert(module);
assert(env);
if (! env_get_struct_type_spec(env, module, &spec) ||
! spec)
return NULL;
- if (! struct_type_init(st, module, spec)) {
- list_delete_all(spec);
+ if (! struct_type_init(st, module, spec))
return NULL;
- }
- list_delete_all(spec);
return st;
}
diff --git a/libc3/struct_type.h b/libc3/struct_type.h
index 91a566e..8cb05a1 100644
--- a/libc3/struct_type.h
+++ b/libc3/struct_type.h
@@ -31,9 +31,11 @@ s_struct_type * struct_type_init (s_struct_type *s, const s_sym *module,
const s_list *spec);
s_struct_type * struct_type_init_copy (s_struct_type *s,
const s_struct_type *src);
+/*
s_struct_type * struct_type_init_from_env (s_struct_type *st,
const s_sym *module,
s_env *env);
+*/
/* Heap-allocation functions, call struct_type_delete after use. */
void struct_type_delete (s_struct_type *s);
diff --git a/libc3/sym.c b/libc3/sym.c
index 1177291..fae25ea 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -1047,7 +1047,7 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
bool sym_type_size (const s_sym *type, uw *dest)
{
- s_struct_type st;
+ const s_struct_type *st;
if (type == sym_1("Array")) {
*dest = sizeof(s_array);
return true;
@@ -1176,9 +1176,9 @@ bool sym_type_size (const s_sym *type, uw *dest)
*dest = 0;
return true;
}
- if (struct_type_init_from_env(&st, type, &g_c3_env)) {
- *dest = st.size;
- struct_type_clean(&st);
+ st = struct_type_find(type);
+ if (st) {
+ *dest = st->size;
return true;
}
err_write_1("sym_type_size: unknown type: ");