diff --git a/libc3/env.c b/libc3/env.c
index 42525cc..da5eeac 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -115,7 +115,6 @@ bool env_call_get (s_env *env, s_call *call)
facts_cursor_clean(&cursor);
return false;
}
- tag_clean(&tag_var);
}
facts_cursor_clean(&cursor);
if (! facts_find_fact_by_tags(&env->facts, &tag_ident, &tag_is_a,
@@ -323,21 +322,18 @@ s_tag * env_defoperator (s_env *env, const s_sym **name,
const s_sym * env_defstruct (s_env *env, const s_list *spec)
{
- s_struct_type *st;
s_tag tag_module_name;
- s_tag tag_st = {0};
+ s_tag tag_st;
s_tag tag_struct_type;
tag_init_sym(&tag_module_name, env->current_defmodule);
+ tag_init_struct_type(&tag_st, env->current_defmodule, spec);
tag_init_sym(&tag_struct_type, &g_sym_struct_type);
- tag_st.type = TAG_STRUCT_TYPE;
- st = &tag_st.data.struct_type;
- if (! struct_type_init(st, env->current_defmodule, spec))
- return NULL;
if (! facts_replace_tags(&env->facts, &tag_module_name,
&tag_struct_type, &tag_st)) {
- struct_type_clean(st);
- return NULL;
+ tag_clean(&tag_st);
+ return NULL;
}
+ tag_clean(&tag_st);
return env->current_defmodule;
}
@@ -1759,6 +1755,7 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
s_tag tag_symbol;
s_tag tag_symbol_value;
s_tag tag_var;
+ s_tag tmp;
module = ident->module;
if (! module) {
if (! sym_search_modules(ident->sym, &module) ||
@@ -1794,6 +1791,7 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
facts_with_cursor_clean(&cursor);
return NULL;
}
+ tag_init_copy(&tmp, &tag_var);
facts_with_cursor_clean(&cursor);
if (! facts_with(&env->facts, &cursor, (t_facts_spec) {
&tag_ident, &tag_is_a, &tag_macro, NULL, NULL }))
@@ -1803,10 +1801,10 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
return NULL;
}
if (fact) {
- if (tag_var.type == TAG_CFN)
- tag_var.data.cfn.macro = true;
- else if (tag_var.type == TAG_FN)
- tag_var.data.fn.macro = true;
+ if (tmp.type == TAG_CFN)
+ tmp.data.cfn.macro = true;
+ else if (tmp.type == TAG_FN)
+ tmp.data.fn.macro = true;
}
facts_with_cursor_clean(&cursor);
if (! facts_with(&env->facts, &cursor, (t_facts_spec) {
@@ -1817,13 +1815,13 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
return NULL;
}
if (fact) {
- if (tag_var.type == TAG_CFN)
- tag_var.data.cfn.special_operator = true;
- else if (tag_var.type == TAG_FN)
- tag_var.data.fn.special_operator = true;
+ if (tmp.type == TAG_CFN)
+ tmp.data.cfn.special_operator = true;
+ else if (tmp.type == TAG_FN)
+ tmp.data.fn.special_operator = true;
}
facts_with_cursor_clean(&cursor);
- *dest = tag_var;
+ *dest = tmp;
return dest;
}
@@ -2179,8 +2177,8 @@ bool env_module_load (s_env *env, const s_sym *module)
return false;
}
-s_tag * env_module_load_time (s_env *env, const s_sym *module,
- s_tag *dest)
+const s_tag ** env_module_load_time (s_env *env, const s_sym *module,
+ const s_tag **dest)
{
s_facts_with_cursor cursor;
const s_fact *fact;
@@ -2198,16 +2196,16 @@ s_tag * env_module_load_time (s_env *env, const s_sym *module,
facts_with_cursor_clean(&cursor);
return NULL;
}
- *dest = tag_time_var;
+ *dest = fact->object;
facts_with_cursor_clean(&cursor);
return dest;
}
bool env_module_maybe_reload (s_env *env, const s_sym *module)
{
+ const s_tag *load_time = {0};
s_str path;
bool r = false;
- s_tag tag_load_time = {0};
s_tag tag_mtime;
if (module_path(module, &env->module_path, C3_EXT, &path)) {
if (file_access(&path, &g_sym_r))
@@ -2223,17 +2221,18 @@ bool env_module_maybe_reload (s_env *env, const s_sym *module)
}
if (! r)
return true;
- if (! env_module_load_time(env, module, &tag_load_time))
+ if (! env_module_load_time(env, module, &load_time)) {
+ str_clean(&path);
return env_module_load(env, module);
+ }
if (! file_mtime(&path, &tag_mtime)) {
str_clean(&path);
return false;
}
str_clean(&path);
- if (compare_tag(&tag_load_time, &tag_mtime) < 0)
+ if (compare_tag(load_time, &tag_mtime) < 0)
r = env_module_load(env, module);
tag_clean(&tag_mtime);
- tag_clean(&tag_load_time);
return r;
}
diff --git a/libc3/env.h b/libc3/env.h
index 84eebf4..3bd50b8 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -31,8 +31,8 @@ bool * env_module_has_ident (s_env *env, const s_sym *module,
const s_ident *ident, bool *dest);
bool * env_module_has_symbol (s_env *env, const s_sym *module,
const s_sym *sym, bool *dest);
-s_tag * env_module_load_time (s_env *env, const s_sym *module,
- s_tag *dest);
+const s_tag ** env_module_load_time (s_env *env, const s_sym *module,
+ const s_tag **dest);
s_list ** env_module_search_modules (s_env *env,
const s_sym *module,
s_list **dest);
diff --git a/libc3/facts_cursor.c b/libc3/facts_cursor.c
index 2a8e56f..40a5551 100644
--- a/libc3/facts_cursor.c
+++ b/libc3/facts_cursor.c
@@ -22,6 +22,12 @@
void facts_cursor_clean (s_facts_cursor *cursor)
{
assert(cursor);
+ if (cursor->var_subject)
+ tag_var(cursor->var_subject, cursor->var_subject_type);
+ if (cursor->var_predicate)
+ tag_var(cursor->var_predicate, cursor->var_predicate_type);
+ if (cursor->var_object)
+ tag_var(cursor->var_object, cursor->var_object_type);
facts_cursor_lock_clean(cursor);
}
diff --git a/libc3/list_init.c b/libc3/list_init.c
index b0ca300..81ffc85 100644
--- a/libc3/list_init.c
+++ b/libc3/list_init.c
@@ -414,6 +414,18 @@ s_list * list_init_struct_with_data (s_list *list, const s_sym *module,
return list;
}
+s_list * list_init_struct_type (s_list *list, const s_sym *module,
+ const s_list *spec, s_list *next)
+{
+ s_list tmp;
+ assert(list);
+ list_init(&tmp, next);
+ if (! tag_init_struct_type(&tmp.tag, module, spec))
+ return NULL;
+ *list = tmp;
+ return list;
+}
+
s_list * list_init_sw (s_list *list, sw i, s_list *next)
{
s_list tmp;
@@ -995,6 +1007,20 @@ s_list * list_new_struct_with_data (const s_sym *module,
return list;
}
+s_list * list_new_struct_type (const s_sym *module, const s_list *spec,
+ s_list *next)
+{
+ s_list *list;
+ list = list_new(next);
+ if (! list)
+ return NULL;
+ if (! tag_init_struct_type(&list->tag, module, spec)) {
+ free(list);
+ return NULL;
+ }
+ return list;
+}
+
s_list * list_new_sw (sw i, s_list *next)
{
s_list *list;
diff --git a/libc3/list_init.h b/libc3/list_init.h
index 1b1d5a3..e4d9ecc 100644
--- a/libc3/list_init.h
+++ b/libc3/list_init.h
@@ -55,6 +55,8 @@ s_list * list_init_struct (s_list *list, const s_sym *module,
s_list * list_init_struct_with_data (s_list *list, const s_sym *module,
bool free_data, void *data,
s_list *next);
+s_list * list_init_struct_type (s_list *list, const s_sym *module,
+ const s_list *spec, s_list *next);
s_list * list_init_sw (s_list *list, sw i, s_list *next);
s_list * list_init_sym (s_list *list, const s_sym *sym, s_list *next);
s_list * list_init_tuple (s_list *list, uw count, s_list *next);
@@ -114,6 +116,8 @@ s_list * list_new_struct (const s_sym *module, s_list *next);
s_list * list_new_struct_with_data (const s_sym *module,
bool free_data, void *data,
s_list *next);
+s_list * list_new_struct_type (const s_sym *module, const s_list *spec,
+ s_list *next);
s_list * list_new_sw (sw i, s_list *next);
s_list * list_new_sym (const s_sym *sym, s_list *next);
s_list * list_new_tuple (uw count, s_list *next);
@@ -168,6 +172,8 @@ s_list * list_str_empty (s_list *list);
s_list * list_struct (s_list *list, const s_sym *module);
s_list * list_struct_with_data (s_list *list, const s_sym *module,
bool free_data, void *data);
+s_list * list_struct_type (s_list *list, const s_sym *module,
+ const s_list *spec);
s_list * list_sw (s_list *list, sw i);
s_list * list_sym (s_list *list, const s_sym *sym);
s_list * list_tuple (s_list *list, uw count);
diff --git a/libc3/module.c b/libc3/module.c
index 5d0bbd0..b4a1606 100644
--- a/libc3/module.c
+++ b/libc3/module.c
@@ -51,7 +51,8 @@ bool module_load (const s_sym *module)
return env_module_load(&g_c3_env, module);
}
-s_tag * module_load_time (const s_sym *module, s_tag *dest)
+const s_tag ** module_load_time (const s_sym *module,
+ const s_tag **dest)
{
return env_module_load_time(&g_c3_env, module, dest);
}
diff --git a/libc3/module.h b/libc3/module.h
index a1083b4..0f87db8 100644
--- a/libc3/module.h
+++ b/libc3/module.h
@@ -28,19 +28,20 @@ bool module_load (const s_sym *module);
bool module_maybe_reload (const s_sym *module);
/* Observers */
-bool * module_has_ident (const s_sym *module,
- const s_ident *ident,
- bool *dest);
-bool * module_has_symbol (const s_sym *module,
- const s_sym *sym,
+bool * module_has_ident (const s_sym *module,
+ const s_ident *ident,
bool *dest);
-bool * module_is_loading (const s_sym *module, bool *dest);
-s_tag * module_load_time (const s_sym *module, s_tag *dest);
-s_str * module_path (const s_sym *module, const s_str *prefix,
- const char *ext, s_str *dest);
-sw module_path_size (const s_sym *module,
- const s_str *prefix,
- const char *ext);
-const s_sym * module_to_sym (const s_sym *module);
+bool * module_has_symbol (const s_sym *module,
+ const s_sym *sym,
+ bool *dest);
+bool * module_is_loading (const s_sym *module, bool *dest);
+const s_tag ** module_load_time (const s_sym *module,
+ const s_tag **dest);
+s_str * module_path (const s_sym *module, const s_str *prefix,
+ const char *ext, s_str *dest);
+sw module_path_size (const s_sym *module,
+ const s_str *prefix,
+ const char *ext);
+const s_sym * module_to_sym (const s_sym *module);
#endif /* LIBC3_MODULE_H */
diff --git a/libc3/struct.c b/libc3/struct.c
index 832d254..37503ae 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -29,10 +29,10 @@ s_struct * struct_allocate (s_struct *s)
assert(s);
assert(! s->data);
tmp = *s;
- tmp.free_data = true;
tmp.data = alloc(tmp.type->size);
if (! tmp.data)
return NULL;
+ tmp.free_data = true;
*s = tmp;
return s;
}
@@ -46,7 +46,7 @@ void struct_clean (s_struct *s)
if (s->data) {
if (s->type->clean)
s->type->clean(s->data);
- else if (s->type->must_clean) {
+ if (s->type->must_clean) {
i = 0;
while (i < s->type->map.count) {
if (tag_type(s->type->map.value + i, &sym))
diff --git a/libc3/tag_init.c b/libc3/tag_init.c
index 8fc74e6..f5a7965 100644
--- a/libc3/tag_init.c
+++ b/libc3/tag_init.c
@@ -22,6 +22,7 @@
#include "ratio.h"
#include "str.h"
#include "struct.h"
+#include "struct_type.h"
#include "tag.h"
#include "tag_init.h"
#include "time.h"
@@ -405,6 +406,18 @@ s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
return tag;
}
+s_tag * tag_init_struct_type (s_tag *tag, const s_sym *module,
+ const s_list *spec)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_STRUCT_TYPE;
+ if (! struct_type_init(&tmp.data.struct_type, module, spec))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_init_sw (s_tag *tag, sw i)
{
s_tag tmp = {0};
@@ -985,6 +998,20 @@ s_tag * tag_new_struct_with_data (const s_sym *module, bool free_data,
return tag;
}
+s_tag * tag_new_struct_type (const s_sym *module, const s_list *spec)
+{
+ s_tag *tag;
+ tag = alloc(sizeof(s_tag));
+ if (! tag)
+ return NULL;
+ tag->type = TAG_STRUCT_TYPE;
+ if (! struct_type_init(&tag->data.struct_type, module, spec)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
s_tag * tag_new_sw (sw i)
{
s_tag *tag;
@@ -1539,6 +1566,19 @@ s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
return tag;
}
+s_tag * tag_struct_type (s_tag *tag, const s_sym *module,
+ const s_list *spec)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_STRUCT_TYPE;
+ if (! struct_type_init(&tmp.data.struct_type, module, spec))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_sw (s_tag *tag, sw i)
{
s_tag tmp = {0};
diff --git a/libc3/tag_init.h b/libc3/tag_init.h
index 4c1e36d..43bcbcb 100644
--- a/libc3/tag_init.h
+++ b/libc3/tag_init.h
@@ -43,6 +43,8 @@ s_tag * tag_init_str_empty (s_tag *tag);
s_tag * tag_init_struct (s_tag *tag, const s_sym *module);
s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
bool free_data, void *data);
+s_tag * tag_init_struct_type (s_tag *tag, const s_sym *module,
+ const s_list *spec);
s_tag * tag_init_sw (s_tag *tag, sw i);
s_tag * tag_init_sym (s_tag *tag, const s_sym *sym);
s_tag * tag_init_tuple (s_tag *tag, uw count);
@@ -96,6 +98,7 @@ s_tag * tag_new_str_empty (void);
s_tag * tag_new_struct (const s_sym *module);
s_tag * tag_new_struct_with_data (const s_sym *module, bool free_data,
void *data);
+s_tag * tag_new_struct_type (const s_sym *module, const s_list *spec);
s_tag * tag_new_sw (sw i);
s_tag * tag_new_sym (const s_sym *sym);
s_tag * tag_new_tuple (uw count);
@@ -149,6 +152,8 @@ s_tag * tag_str_empty (s_tag *tag);
s_tag * tag_struct (s_tag *tag, const s_sym *module);
s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
bool free_data, void *data);
+s_tag * tag_struct_type (s_tag *tag, const s_sym *module,
+ const s_list *spec);
s_tag * tag_sw (s_tag *tag, sw i);
s_tag * tag_sym (s_tag *tag, const s_sym *sym);
s_tag * tag_tuple (s_tag *tag, uw count);
diff --git a/libc3/tag_init.rb b/libc3/tag_init.rb
index b83ed33..1ff44b4 100644
--- a/libc3/tag_init.rb
+++ b/libc3/tag_init.rb
@@ -378,6 +378,9 @@ class TagInitList
[Arg.new("const s_sym *", "module"),
Arg.new("bool", "free_data"),
Arg.new("void *", "data")]),
+ TagInit.new("struct_type", "TAG_STRUCT_TYPE", :init_mode_init,
+ [Arg.new("const s_sym *", "module"),
+ Arg.new("const s_list *", "spec")]),
TagInit.new("sw", "TAG_SW", :init_mode_direct,
[Arg.new("sw", "i")]),
TagInit.new("sym", "TAG_SYM", :init_mode_direct,
@@ -532,6 +535,7 @@ tag_init_c.content = <<EOF
#include "ratio.h"
#include "str.h"
#include "struct.h"
+#include "struct_type.h"
#include "tag.h"
#include "tag_init.h"
#include "time.h"