diff --git a/.ic3_history b/.ic3_history
index b61ddd4..5d39a23 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,5 +1,3 @@
-end
-do end
defmodule Plop do end
quote Plop
quote_cfn Plop
@@ -97,3 +95,5 @@ List.reverse
List.reverse([1, 2, 3])
List.reverse
List.reverse([1, 2])
+def a = 1
+a
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 7e61012..625e501 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,11 +1,3 @@
-def fib = fn (x) { if x < 0 0 else fib(x - 2) + fib(x - 1) end }
-def fib = fn (x) { if x < 0 then 0 else fib(x - 2) + fib(x - 1) end }
-def fib = fn { (0) { 1 } (1) { 1 } (x) { if x < 0 then 0 else fib(x - 2) + fib(x - 1) end }}
-do end
-end
-do end
-end
-do end
defmodule Plop do end
quote Plop
quote_cfn Plop
@@ -97,3 +89,11 @@ if true then true end
if 42 then true end
if 0 then true end
if 0 then true else false end
+def reverse = fn (x) { List.reverse(x) }
+reverse
+C3.reverse
+reverse([1, 2])
+C3.reverse
+reverse
+def reverse = fn (x) { List.reverse(x) }
+reverse
diff --git a/lib/c3/0.1/list.c3 b/lib/c3/0.1/list.c3
index 6d992c8..8160469 100644
--- a/lib/c3/0.1/list.c3
+++ b/lib/c3/0.1/list.c3
@@ -2,7 +2,7 @@ defmodule List do
def cast = cfn List "list_init_cast" (Result, Sym, Tag)
- def map = fn {
+ def map = List.fn {
([], _) do
[]
end
@@ -11,7 +11,7 @@ defmodule List do
end
}
- def reverse = fn {
+ def reverse = List.fn {
(x) { reverse(x, []) }
([], acc) { acc }
([a | b], acc) { reverse(b, [a | acc]) }
diff --git a/libc3/cfn.c b/libc3/cfn.c
index 8c3e00f..066cc00 100644
--- a/libc3/cfn.c
+++ b/libc3/cfn.c
@@ -203,8 +203,8 @@ s_cfn * cfn_init_copy (s_cfn *cfn, const s_cfn *src)
assert(cfn);
tmp.name = src->name;
tmp.arg_result = src->arg_result;
- if (! list_init_copy(&tmp.arg_types,
- (const s_list * const *) &src->arg_types))
+ if (src->arg_types &&
+ ! (tmp.arg_types = list_new_copy(src->arg_types)))
return NULL;
tmp.arity = src->arity;
tmp.cif = src->cif;
diff --git a/libc3/env.c b/libc3/env.c
index ea75661..92e5255 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -852,14 +852,6 @@ bool env_eval_equal_tuple (s_env *env, bool macro, const s_tuple *a,
bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest)
{
- /*
- uw i;
- s_fn_clause *src_clause;
- s_list *src_pattern;
- s_fn tmp = {0};
- s_fn_clause **tmp_clause;
- s_list **tmp_pattern;
- */
s_tag tmp = {0};
assert(env);
assert(fn);
@@ -871,48 +863,6 @@ bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest)
tmp.data.fn.module = env->current_defmodule;
*dest = tmp;
return true;
- /*
- tmp_clause = &tmp.clauses;
- src_clause = fn->clauses;
- while (src_clause) {
- *tmp_clause = fn_clause_new(NULL);
- if (! *tmp_clause)
- goto ko;
- (*tmp_clause)->arity = src_clause->arity;
- tmp_pattern = &(*tmp_clause)->pattern;
- src_pattern = src_clause->pattern;
- while (src_pattern) {
- *tmp_pattern = list_new(NULL);
- if (! *tmp_pattern)
- goto ko;
- if (! env_eval_fn_tag(env, &src_pattern->tag,
- &(*tmp_pattern)->tag))
- goto ko;
- tmp_pattern = &(*tmp_pattern)->next.data.list;
- src_pattern = list_next(src_pattern);
- }
- if (! block_init(&(*tmp_clause)->algo, src_clause->algo.count))
- goto ko;
- i = 0;
- while (i < src_clause->algo.count) {
- if (! env_eval_fn_tag(env, src_clause->algo.tag + i,
- (*tmp_clause)->algo.tag + i))
- goto ko;
- i++;
- }
- (*tmp_clause)->algo.short_form = src_clause->algo.short_form;
- tmp_clause = &(*tmp_clause)->next_clause;
- src_clause = src_clause->next_clause;
- }
- tmp.macro = fn->macro;
- tmp.special_operator = fn->special_operator;
- dest->type = TAG_FN;
- dest->data.fn = tmp;
- return true;
- ko:
- fn_clean(&tmp);
- return false;
- */
}
// Like tag_init_copy excepted that the idents get resolved.
@@ -2062,7 +2012,7 @@ bool env_module_is_loading_set (s_env *env, const s_sym *module,
bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
{
- s_str path;
+ s_str path = {0};
s_struct_type *st;
s_list *st_spec;
s_tag tag_module_name;
@@ -2082,13 +2032,14 @@ bool env_module_load (s_env *env, const s_sym *module, s_facts *facts)
tag_init_time(&tag_time);
if (! env_load(env, &path)) {
err_write_1("env_module_load: ");
- err_write_1(module->str.ptr.pchar);
+ err_inspect_sym(&module);
err_puts(": env_load");
str_clean(&path);
goto ko;
}
}
else {
+ str_clean(&path);
if (! module_path(module, &env->module_path, FACTS_EXT, &path)) {
err_write_1("env_module_load: ");
err_write_1(module->str.ptr.pchar);
@@ -2137,13 +2088,14 @@ bool env_module_maybe_reload (s_env *env, const s_sym *module,
s_tag tag_load_time = {0};
s_tag tag_mtime;
module_load_time(module, facts, &tag_load_time);
- if (! module_path(module, &env->module_path, C3_EXT, &path) &&
- ! module_path(module, &env->module_path, FACTS_EXT, &path)) {
+ if ((! module_path(module, &env->module_path, C3_EXT, &path) ||
+ ! file_access(&path, &g_sym_r)) &&
+ (! module_path(module, &env->module_path, FACTS_EXT, &path) ||
+ ! file_access(&path, &g_sym_r))) {
return false;
}
//io_inspect_str(&path);
- if (! file_access(&path, &g_sym_r) ||
- ! file_mtime(&path, &tag_mtime)) {
+ if (! file_mtime(&path, &tag_mtime)) {
str_clean(&path);
return false;
}
diff --git a/libc3/facts.c b/libc3/facts.c
index 3b5e766..4377f57 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -573,8 +573,13 @@ s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag)
assert(facts);
assert(tag);
item = set_add__tag(&facts->tags, tag);
- if (! item)
+ if (! item) {
+ err_write_1("facts_ref_tag: set_add__tag: ");
+ err_inspect_tag(tag);
+ err_write_1("\n");
+ assert(! "facts_ref_tag: set_add__tag");
return NULL;
+ }
item->usage++;
return &item->data;
}
diff --git a/libc3/fn.c b/libc3/fn.c
index d4f51b9..0cf110c 100644
--- a/libc3/fn.c
+++ b/libc3/fn.c
@@ -109,8 +109,10 @@ s_fn * fn_init_cast (s_fn *fn, const s_sym *type, const s_tag *tag)
s_fn * fn_init_copy (s_fn *fn, const s_fn *src)
{
s_fn tmp = {0};
+ assert(fn);
+ assert(src);
tmp.module = src->module;
- fn_clause_copy(src->clauses, &tmp.clauses);
+ tmp.clauses = fn_clause_new_copy(src->clauses);
tmp.macro = src->macro;
tmp.special_operator = src->special_operator;
*fn = tmp;
diff --git a/libc3/fn_clause.c b/libc3/fn_clause.c
index 2b60500..b67a3d0 100644
--- a/libc3/fn_clause.c
+++ b/libc3/fn_clause.c
@@ -25,22 +25,6 @@ void fn_clause_clean (s_fn_clause *fn_clause)
block_clean(&fn_clause->algo);
}
-s_fn_clause * fn_clause_copy (const s_fn_clause *src, s_fn_clause **dest)
-{
- s_fn_clause *tmp = NULL;
- s_fn_clause **tail = &tmp;
- while (src) {
- *tail = fn_clause_new(NULL);
- (*tail)->arity = src->arity;
- list_init_copy(&(*tail)->pattern, (const s_list **) &src->pattern);
- block_init_copy(&(*tail)->algo, &src->algo);
- src = src->next_clause;
- tail = &(*tail)->next_clause;
- }
- *dest = tmp;
- return tmp;
-}
-
s_fn_clause * fn_clause_delete (s_fn_clause *fn_clause)
{
s_fn_clause *next_clause;
@@ -74,3 +58,20 @@ s_fn_clause * fn_clause_new (s_fn_clause *next_clause)
return NULL;
return fn_clause_init(fn_clause, next_clause);
}
+
+s_fn_clause * fn_clause_new_copy (const s_fn_clause *src)
+{
+ s_fn_clause *tmp;
+ s_fn_clause **tail;
+ tmp = NULL;
+ tail = &tmp;
+ while (src) {
+ *tail = fn_clause_new(NULL);
+ (*tail)->arity = src->arity;
+ (*tail)->pattern = list_new_copy(src->pattern);
+ block_init_copy(&(*tail)->algo, &src->algo);
+ tail = &(*tail)->next_clause;
+ src = src->next_clause;
+ }
+ return tmp;
+}
diff --git a/libc3/fn_clause.h b/libc3/fn_clause.h
index b1b42b5..43a015c 100644
--- a/libc3/fn_clause.h
+++ b/libc3/fn_clause.h
@@ -27,12 +27,10 @@ s_fn_clause * fn_clause_init (s_fn_clause *clause, s_fn_clause *next_clause);
/* constructors */
s_fn_clause * fn_clause_new (s_fn_clause *next_clause);
+s_fn_clause * fn_clause_new_copy (const s_fn_clause *src);
/* destructors */
s_fn_clause * fn_clause_delete (s_fn_clause *clause);
void fn_clause_delete_all (s_fn_clause *clause);
-/* modifiers */
-s_fn_clause * fn_clause_copy (const s_fn_clause *src, s_fn_clause **dest);
-
#endif /* LIBC3_FN_H */
diff --git a/libc3/hash.c b/libc3/hash.c
index 32f0788..8e92390 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -499,8 +499,8 @@ bool hash_update_tag (t_hash *hash, const s_tag *tag)
case TAG_UNQUOTE:
return hash_update_unquote(hash, &tag->data.unquote);
case TAG_UW: return hash_update_uw(hash, &tag->data.uw);
- case TAG_VAR: return hash_update_var(hash, NULL);
- case TAG_VOID: return hash_update_void(hash, NULL);
+ case TAG_VAR: return hash_update_var(hash, tag);
+ case TAG_VOID: return hash_update_void(hash, tag);
}
err_puts("hash_update_tag: unknown tag type");
assert(! "hash_update_tag: unknown tag type");
diff --git a/libc3/list.c b/libc3/list.c
index 5ecbef8..2e5256d 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -100,40 +100,18 @@ s_list ** list_init_cast (s_list **list, const s_sym *type,
return NULL;
}
-/* FIXME: does not work on circular lists */
s_list ** list_init_copy (s_list **list, const s_list * const *src)
{
- s_list **i;
- s_list *next;
- const s_list *s;
- s_list *tmp;
+ s_list *tmp = NULL;
assert(src);
assert(list);
- i = &tmp;
- *i = NULL;
- s = *src;
- while (s) {
- *i = list_new(NULL);
- if (! tag_init_copy(&(*i)->tag, &s->tag))
- goto ko;
- if ((next = list_next(s))) {
- s = next;
- i = &(*i)->next.data.list;
- }
- else {
- if (! tag_init_copy(&(*i)->next, &s->next))
- goto ko;
- break;
- }
- }
+ if (*src && ! (tmp = list_new_copy(*src)))
+ return NULL;
*list = tmp;
return list;
- ko:
- list_delete_all(tmp);
- return NULL;
}
-s_list * list_init_copy_tag (s_list *list, const s_tag *tag, s_list *next)
+s_list * list_init_tag_copy (s_list *list, const s_tag *tag, s_list *next)
{
assert(list);
assert(tag);
@@ -217,12 +195,41 @@ s_list * list_new_1 (const char *p)
}
return list;
}
+/* FIXME: does not work on circular lists */
+s_list * list_new_copy (const s_list *src)
+{
+ s_list **i;
+ s_list *next;
+ const s_list *s;
+ s_list *list;
+ list = NULL;
+ i = &list;
+ s = src;
+ while (s) {
+ *i = list_new(NULL);
+ if (! tag_init_copy(&(*i)->tag, &s->tag))
+ goto ko;
+ if ((next = list_next(s))) {
+ s = next;
+ i = &(*i)->next.data.list;
+ }
+ else {
+ if (! tag_init_copy(&(*i)->next, &s->next))
+ goto ko;
+ break;
+ }
+ }
+ return list;
+ ko:
+ list_delete_all(list);
+ return NULL;
+}
-s_list * list_new_copy (const s_tag *x, s_list *next)
+s_list * list_new_list (s_list *x, s_list *next)
{
s_list *dest;
if ((dest = list_new(next))) {
- if (! tag_init_copy(&dest->tag, x)) {
+ if (! tag_init_list(&dest->tag, x)) {
free(dest);
return NULL;
}
@@ -230,11 +237,11 @@ s_list * list_new_copy (const s_tag *x, s_list *next)
return dest;
}
-s_list * list_new_list (s_list *x, s_list *next)
+s_list * list_new_tag_copy (const s_tag *x, s_list *next)
{
s_list *dest;
if ((dest = list_new(next))) {
- if (! tag_init_list(&dest->tag, x)) {
+ if (! tag_init_copy(&dest->tag, x)) {
free(dest);
return NULL;
}
diff --git a/libc3/list.h b/libc3/list.h
index d01c361..eda757e 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -31,9 +31,9 @@ s_list * list_init_1 (s_list *list, const char *p, s_list *next);
s_list ** list_init_cast (s_list **list, const s_sym *type,
const s_tag *tag);
s_list ** list_init_copy (s_list **list, const s_list * const *src);
-s_list * list_init_copy_tag (s_list *list, const s_tag *tag,
- s_list *next);
s_list * list_init_eval (s_list *list, const char *p);
+s_list * list_init_tag_copy (s_list *list, const s_tag *tag,
+ s_list *next);
/* Heap-allocation functions, call list_delete after use */
s_list * list_delete (s_list *list);
@@ -41,11 +41,12 @@ void list_delete_all (s_list *list);
void list_f_clean (s_list **list);
s_list * list_new (s_list *next);
s_list * list_new_1 (const char *p);
+s_list * list_new_copy (const s_list *src);
s_list * list_new_f64 (f64 x, s_list *next);
-s_list * list_new_copy (const s_tag *tag, s_list *next);
s_list * list_new_list (s_list *list, s_list *next);
s_list * list_new_map (uw count, s_list *next);
s_list * list_new_str_1 (char *free, const char *p, s_list *next);
+s_list * list_new_tag_copy (const s_tag *tag, s_list *next);
/* Observers */
s_list ** list_cast (const s_tag *tag, s_list **list);
diff --git a/libc3/map.c b/libc3/map.c
index b025024..7c20df6 100644
--- a/libc3/map.c
+++ b/libc3/map.c
@@ -189,8 +189,8 @@ s_list ** map_map (const s_map *map, const s_fn *fn, s_list **result)
t = &tmp;
*t = NULL;
while (i < map->count) {
- args = list_new_copy(map->key + i,
- list_new_copy(map->value + i, NULL));
+ args = list_new_tag_copy(map->key + i,
+ list_new_tag_copy(map->value + i, NULL));
*t = list_new(NULL);
if (! eval_fn_call(fn, args, &(*t)->tag)) {
list_delete_all(args);
diff --git a/libc3/module.c b/libc3/module.c
index a1b978b..98de5b5 100644
--- a/libc3/module.c
+++ b/libc3/module.c
@@ -119,6 +119,7 @@ s_str * module_path (const s_sym *module, const s_str *prefix,
s_buf out;
sw out_size;
sw r;
+ s_str *result;
assert(dest);
assert(module);
buf_init_str(&in, false, (s_str *) &module->str);
@@ -144,7 +145,12 @@ s_str * module_path (const s_sym *module, const s_str *prefix,
}
if ((r = buf_write_1(&out, ext)) < 0)
goto error;
- return buf_to_str(&out, dest);
+ result = buf_to_str(&out, dest);
+ if (result) {
+ err_inspect_str(dest);
+ err_write_1("\n");
+ }
+ return result;
error:
buf_clean(&out);
err_puts("module_path: error");
diff --git a/libc3/set.c.in b/libc3/set.c.in
index 119409f..4a0036a 100644
--- a/libc3/set.c.in
+++ b/libc3/set.c.in
@@ -24,8 +24,11 @@ set_add___NAME$ (s_set___NAME$ *set, const _TYPE$ *data)
uw hash;
assert(set);
assert(data);
- if (! _NAME$_hash_uw(data, &hash))
+ if (! _NAME$_hash_uw(data, &hash)) {
+ err_puts("set_add___NAME$: _NAME$_hash_uw");
+ assert(! "set_add___NAME$: _NAME$_hash_uw");
return NULL;
+ }
return set_add_h___NAME$(set, data, hash);
}
@@ -52,7 +55,11 @@ set_add_h___NAME$ (s_set___NAME$ *set, const _TYPE$ *data, uw hash)
h = hash % set->max;
if ((i = set->items[h]))
return set_add_collision___NAME$(set, data, hash, i);
- i = set_item_new___NAME$(data, hash, NULL);
+ if (! (i = set_item_new___NAME$(data, hash, NULL))) {
+ err_puts("set_add_h___NAME$: set_item_new___NAME$");
+ assert(! "set_add_h___NAME$: set_item_new___NAME$");
+ return NULL;
+ }
set->items[h] = i;
set->count++;
return i;
diff --git a/libc3/set__fact.c b/libc3/set__fact.c
index e0d681a..9440141 100644
--- a/libc3/set__fact.c
+++ b/libc3/set__fact.c
@@ -24,8 +24,11 @@ set_add__fact (s_set__fact *set, const s_fact *data)
uw hash;
assert(set);
assert(data);
- if (! fact_hash_uw(data, &hash))
+ if (! fact_hash_uw(data, &hash)) {
+ err_puts("set_add__fact: fact_hash_uw");
+ assert(! "set_add__fact: fact_hash_uw");
return NULL;
+ }
return set_add_h__fact(set, data, hash);
}
@@ -52,7 +55,11 @@ set_add_h__fact (s_set__fact *set, const s_fact *data, uw hash)
h = hash % set->max;
if ((i = set->items[h]))
return set_add_collision__fact(set, data, hash, i);
- i = set_item_new__fact(data, hash, NULL);
+ if (! (i = set_item_new__fact(data, hash, NULL))) {
+ err_puts("set_add_h__fact: set_item_new__fact");
+ assert(! "set_add_h__fact: set_item_new__fact");
+ return NULL;
+ }
set->items[h] = i;
set->count++;
return i;
diff --git a/libc3/set__tag.c b/libc3/set__tag.c
index 6159c95..f676131 100644
--- a/libc3/set__tag.c
+++ b/libc3/set__tag.c
@@ -24,8 +24,11 @@ set_add__tag (s_set__tag *set, const s_tag *data)
uw hash;
assert(set);
assert(data);
- if (! tag_hash_uw(data, &hash))
+ if (! tag_hash_uw(data, &hash)) {
+ err_puts("set_add__tag: tag_hash_uw");
+ assert(! "set_add__tag: tag_hash_uw");
return NULL;
+ }
return set_add_h__tag(set, data, hash);
}
@@ -52,7 +55,11 @@ set_add_h__tag (s_set__tag *set, const s_tag *data, uw hash)
h = hash % set->max;
if ((i = set->items[h]))
return set_add_collision__tag(set, data, hash, i);
- i = set_item_new__tag(data, hash, NULL);
+ if (! (i = set_item_new__tag(data, hash, NULL))) {
+ err_puts("set_add_h__tag: set_item_new__tag");
+ assert(! "set_add_h__tag: set_item_new__tag");
+ return NULL;
+ }
set->items[h] = i;
set->count++;
return i;
diff --git a/libc3/tag.c b/libc3/tag.c
index f1233ac..56f870a 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -277,8 +277,13 @@ uw * tag_hash_uw (const s_tag *tag, uw *dest)
t_hash hash;
assert(tag);
hash_init(&hash);
- if (! hash_update_tag(&hash, tag))
+ if (! hash_update_tag(&hash, tag)) {
+ err_write_1("tag_hash_uw: hash_update_tag: ");
+ err_inspect_tag(tag);
+ err_write_1("\n");
+ assert(! "tag_hash_uw: hash_update_tag");
return NULL;
+ }
*dest = hash_to_uw(&hash);
return dest;
}