diff --git a/.ic3_history b/.ic3_history
index c04bdbf..f2b12a4 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,9 +1,3 @@
-Plop.sq(4)
-defmodule Plop do def a = 1 end
-Plop.a
-(Sw) 123\
-(Sw) 123
-(Sw) 123/2
(Sw) 123 / 2
defmodule Plop do def a = 1 end
Plop.a
@@ -97,3 +91,9 @@ quote [{:a, 1}, {:b, 2}]
abc.def
%{a: 1}
%{a: 1}.a
+test = fn (list, args) { List.map(list, fn (e) { access(args, e)})}
+test([a, b, c], %{a: 1, b: 2, c: 3})
+test([:a, :b, :c], %{a: 1, b: 2, c: 3})
+a = %{a: 1}
+b = %{b: 2}
+a.a + b.b
diff --git a/ic3/.ic3_history b/ic3/.ic3_history
index 1416cd4..f2b12a4 100644
--- a/ic3/.ic3_history
+++ b/ic3/.ic3_history
@@ -1,11 +1,3 @@
- def sq = fn (x) { x + x }
-end
-Plop.sq(4)
-defmodule Plop do def a = 1 end
-Plop.a
-(Sw) 123\
-(Sw) 123
-(Sw) 123/2
(Sw) 123 / 2
defmodule Plop do def a = 1 end
Plop.a
@@ -95,4 +87,13 @@ quote [a: 1, b: 2]
quote [{:a, 1}, {:b, 2}]
%C3.Operator{}
%GL.Vertex{}
-%C3.Operator{}
+123.456
+abc.def
+%{a: 1}
+%{a: 1}.a
+test = fn (list, args) { List.map(list, fn (e) { access(args, e)})}
+test([a, b, c], %{a: 1, b: 2, c: 3})
+test([:a, :b, :c], %{a: 1, b: 2, c: 3})
+a = %{a: 1}
+b = %{b: 2}
+a.a + b.b
diff --git a/libc3/env.c b/libc3/env.c
index 7321a9b..c32d951 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -605,7 +605,11 @@ bool env_eval_call_fn_args (s_env *env, const s_fn *fn,
args_final = args;
}
while (clause) {
- frame_init(&frame, env->frame);
+ if (! frame_init(&frame, env->frame)) {
+ list_delete_all(env->search_modules);
+ env->search_modules = search_modules;
+ return false;
+ }
env->frame = &frame;
if (env_eval_equal_list(env, fn->macro || fn->special_operator,
clause->pattern, args_final, &tmp))
diff --git a/libc3/facts.c b/libc3/facts.c
index 9e61ad4..8ba4eb2 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -321,6 +321,7 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
" version: 1}\n")) <= 0) {
err_write_1("facts_load: invalid or missing header: ");
err_puts(path->ptr.pchar);
+ assert(! "facts_load: invalid or missing header");
return -1;
}
result += r;
@@ -342,6 +343,7 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
err_inspect_u64(&line);
err_write_1(": ");
err_puts(path->ptr.pchar);
+ assert(! "facts_load: invalid fact");
goto ko;
}
result += r;
@@ -351,6 +353,7 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
err_inspect_u64(&line);
err_write_1(": ");
err_puts(path->ptr.pchar);
+ assert(! "facts_load: missing newline");
goto ko;
}
result += r;
@@ -360,6 +363,7 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
err_inspect_u64(&line);
err_write_1(": ");
err_puts(path->ptr.pchar);
+ assert(! "facts_load: invalid fact");
goto ko;
}
fact_r(&fact_eval, &fact_eval_r);
@@ -371,6 +375,7 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
err_inspect_u64(&line);
err_write_1(": ");
err_puts(path->ptr.pchar);
+ assert(! "facts_load: failed to replace fact");
goto ko;
}
}
@@ -382,6 +387,7 @@ sw facts_load (s_facts *facts, s_buf *buf, const s_str *path)
err_inspect_u64(&line);
err_write_1(": ");
err_puts(path->ptr.pchar);
+ assert(! "facts_load: failed to add fact");
goto ko;
}
}
diff --git a/libc3/facts_cursor.c b/libc3/facts_cursor.c
index 40a5551..f7b691c 100644
--- a/libc3/facts_cursor.c
+++ b/libc3/facts_cursor.c
@@ -16,6 +16,7 @@
#include "facts_cursor.h"
#include "skiplist__fact.h"
#include "skiplist_node__fact.h"
+#include "sym.h"
#include "tag.h"
#include "var.h"
@@ -125,10 +126,12 @@ const s_fact ** facts_cursor_next (s_facts_cursor *cursor,
const s_fact **dest)
{
const s_fact *fact;
+ const s_sym *type;
assert(cursor);
if (! facts_cursor_lock(cursor))
return NULL;
if (cursor->node) {
+ next:
cursor->node = SKIPLIST_NODE_NEXT__fact(cursor->node, 0);
if (cursor->node &&
cursor->index->compare(&cursor->end, cursor->node->fact) < 0)
@@ -148,16 +151,31 @@ const s_fact ** facts_cursor_next (s_facts_cursor *cursor,
fact = cursor->node->fact;
if (cursor->var_subject) {
tag_var(cursor->var_subject, cursor->var_subject_type);
+ if (! tag_type(fact->subject, &type))
+ goto ko;
+ if (cursor->var_subject_type != &g_sym_Tag &&
+ cursor->var_subject_type != type)
+ goto next;
if (! var_set(cursor->var_subject, fact->subject))
goto ko;
}
if (cursor->var_predicate) {
tag_var(cursor->var_predicate, cursor->var_predicate_type);
+ if (! tag_type(fact->predicate, &type))
+ goto ko;
+ if (cursor->var_predicate_type != &g_sym_Tag &&
+ cursor->var_predicate_type != type)
+ goto next;
if (! var_set(cursor->var_predicate, fact->predicate))
goto ko;
}
if (cursor->var_object) {
tag_var(cursor->var_object, cursor->var_object_type);
+ if (! tag_type(fact->object, &type))
+ goto ko;
+ if (cursor->var_object_type != &g_sym_Tag &&
+ cursor->var_object_type != type)
+ goto next;
if (! var_set(cursor->var_object, fact->object))
goto ko;
}
diff --git a/libc3/frame.c b/libc3/frame.c
index adda70c..4f73b30 100644
--- a/libc3/frame.c
+++ b/libc3/frame.c
@@ -48,13 +48,25 @@ s_frame * frame_delete (s_frame *frame)
void frame_delete_all (s_frame *frame)
{
- while (frame)
- frame = frame_delete(frame);
+ s_frame *f;
+ f = frame;
+ while (f)
+ f = frame_delete(f);
}
const s_tag * frame_get (const s_frame *frame, const s_sym *sym)
{
- return binding_get(frame->bindings, sym);
+ const s_frame *f;
+ const s_tag *result;
+ assert(sym);
+ f = frame;
+ while (f) {
+ result = binding_get(frame->bindings, sym);
+ if (result)
+ return result;
+ f = f->next;
+ }
+ return NULL;
}
s_frame * frame_init (s_frame *frame, s_frame *next)
@@ -72,5 +84,9 @@ s_frame * frame_new (s_frame *next)
frame = alloc(sizeof(s_frame));
if (! frame)
return NULL;
- return frame_init(frame, next);
+ if (! frame_init(frame, next)) {
+ free(frame);
+ return NULL;
+ }
+ return frame;
}
diff --git a/libc3/var.c b/libc3/var.c
index e2bf728..da4d0a8 100644
--- a/libc3/var.c
+++ b/libc3/var.c
@@ -86,6 +86,7 @@ s_tag * var_set (s_tag *var, const s_tag *value)
err_inspect_sym(&var_type);
err_write_1(" != ");
err_inspect_sym(&value_type);
+ err_write_1("\n");
assert(! "var_set: type mismatch");
return NULL;
}