diff --git a/.ikc3_history b/.ikc3_history
index fdac7e3..41cdc21 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,4 +1,3 @@
-HTTP.mime_type("pplop.txt")
HTTP.mime_type("txt")
File.ext("Plop.html")
HTTP.mime_type(File.ext("Plop.html"))
@@ -97,3 +96,5 @@ sym
Facts.with(db, [[KC3, :operator, op = ?], [op, :sym, sym = ?]], fn (fact) { puts("#{op} #{sym}") })
Facts.with(Facts.env_db(), [[KC3, :operator, op = ?], [op, :sym, sym = ?]], fn (fact) { puts("#{op} #{sym}") })
Facts.with(Facts.env_db(), [[KC3, :operator, op = ?], [op, :sym, sym = ?]], fn (fact) { puts("#{inspect(op)} #{inspect(sym)}") })
+[[KC3, :operator, op = ?], [op, :sym, sym = ?]]
+
diff --git a/lib/kc3/0.1/facts.kc3 b/lib/kc3/0.1/facts.kc3
index a2e5599..d7b563b 100644
--- a/lib/kc3/0.1/facts.kc3
+++ b/lib/kc3/0.1/facts.kc3
@@ -32,8 +32,7 @@ defmodule Facts do
Tag, Tag, Fn, Result)
# with(facts, [[?, ?, ?]], fn (fact) {result}) -> result
- def with = cfn Tag "kc3_facts_with" (Facts, List, Fn,
- Result)
+ def with = cfn Tag "kc3_facts_with" (Facts, List, Fn, Result)
# with_tags(facts, subject, predicate, object,
# fn (fact) {result}) -> result
diff --git a/libkc3/compare.c b/libkc3/compare.c
index 8956a3e..772c28f 100644
--- a/libkc3/compare.c
+++ b/libkc3/compare.c
@@ -163,6 +163,7 @@ COMPARE_DEF(f32)
COMPARE_DEF(f64)
COMPARE_DEF(f128)
+
s8 compare_fact (const s_fact *a, const s_fact *b)
{
s8 r;
@@ -172,11 +173,11 @@ s8 compare_fact (const s_fact *a, const s_fact *b)
return -1;
if (!b)
return 1;
- if ((r = compare_tag(a->subject, b->subject)))
+ if ((r = compare_tag_deref(a->subject, b->subject)))
return r;
- if ((r = compare_tag(a->predicate, b->predicate)))
+ if ((r = compare_tag_deref(a->predicate, b->predicate)))
return r;
- r = compare_tag(a->object, b->object);
+ r = compare_tag_deref(a->object, b->object);
return r;
}
@@ -230,11 +231,11 @@ s8 compare_fact_pos (const s_fact *a, const s_fact *b)
return -1;
if (!b)
return 1;
- if ((r = compare_tag(a->predicate, b->predicate)))
+ if ((r = compare_tag_deref(a->predicate, b->predicate)))
return r;
- if ((r = compare_tag(a->object, b->object)))
+ if ((r = compare_tag_deref(a->object, b->object)))
return r;
- r = compare_tag(a->subject, b->subject);
+ r = compare_tag_deref(a->subject, b->subject);
return r;
}
@@ -247,11 +248,11 @@ s8 compare_fact_osp (const s_fact *a, const s_fact *b)
return -1;
if (!b)
return 1;
- if ((r = compare_tag(a->object, b->object)))
+ if ((r = compare_tag_deref(a->object, b->object)))
return r;
- if ((r = compare_tag(a->subject, b->subject)))
+ if ((r = compare_tag_deref(a->subject, b->subject)))
return r;
- r = compare_tag(a->predicate, b->predicate);
+ r = compare_tag_deref(a->predicate, b->predicate);
return r;
}
@@ -594,11 +595,11 @@ s8 compare_tag (const s_tag *a, const s_tag *b) {
s_integer tmp2 = {0};
if (a == b)
return 0;
- if (!a ||
+ if (! a ||
a == TAG_FIRST ||
b == TAG_LAST)
return -1;
- if (!b ||
+ if (! b ||
a == TAG_LAST ||
b == TAG_FIRST)
return 1;
@@ -1482,6 +1483,19 @@ s8 compare_tag_number (const s_tag *a, const s_tag *b)
abort();
return 0;
}
+
+s8 compare_tag_deref (const s_tag *a, const s_tag *b)
+{
+ const s_tag *a_deref;
+ const s_tag *b_deref;
+ a_deref = a;
+ if (a_deref && a_deref->type == TAG_VAR)
+ a_deref = a_deref->data.var.ptr;
+ b_deref = b;
+ if (b_deref && b_deref->type == TAG_VAR)
+ b_deref = b_deref->data.var.ptr;
+ return compare_tag(a_deref, b_deref);
+}
s8 compare_time (const s_time *a, const s_time *b)
{
diff --git a/libkc3/compare.h b/libkc3/compare.h
index 12b8fc5..5c9f2b9 100644
--- a/libkc3/compare.h
+++ b/libkc3/compare.h
@@ -60,6 +60,7 @@ 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_tag_deref (const s_tag *a, const s_tag *b);
s8 compare_time (const s_time *a, const s_time *b);
s8 compare_tuple (const s_tuple *a, const s_tuple *b);
COMPARE_PROTOTYPE(u8);
diff --git a/libkc3/env.c b/libkc3/env.c
index 981df98..6e773c0 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -2153,15 +2153,13 @@ s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
if (! struct_allocate(&arguments->tag.data.struct_))
return NULL;
fact_w = arguments->tag.data.struct_.data;
- if (! env_facts_with_list(env, facts, &cursor, *spec))
+ if (! facts_with_list(facts, &cursor, *spec))
return NULL;
while (1) {
if (! facts_with_cursor_next(&cursor, &fact))
goto clean;
- if (! fact) {
- err_puts("env_facts_with: ok");
- goto ok;
- }
+ if (! fact)
+ break;
tag_clean(&tmp);
fact_w_init_fact(fact_w, fact);
if (! env_eval_call_fn_args(env, callback, arguments, &tmp)) {
@@ -2171,7 +2169,6 @@ s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
fact_w_clean(fact_w);
fact_w_init(fact_w);
}
- ok:
list_delete_all(arguments);
*dest = tmp;
return dest;
@@ -2184,74 +2181,6 @@ s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
return NULL;
}
-s_facts_with_cursor * env_facts_with_list (s_env *env, s_facts *facts,
- s_facts_with_cursor *cursor,
- s_list *spec)
-{
- s_ident *ident;
- s_list *spec_i;
- s_list *spec_j;
- s_list *tmp;
- s_list **tmp_tail;
- s_list **tmp_tail_j;
- p_facts_spec facts_spec = NULL;
- s_tag *var;
- assert(facts);
- assert(cursor);
- assert(spec);
- tmp = NULL;
- tmp_tail = &tmp;
- spec_i = spec;
- while (spec_i) {
- if (spec_i->tag.type != TAG_LIST)
- goto ko;
- *tmp_tail = list_new(NULL);
- (*tmp_tail)->tag.type = TAG_LIST;
- tmp_tail_j = &(*tmp_tail)->tag.data.list;
- spec_j = spec_i->tag.data.list;
- while (spec_j) {
- *tmp_tail_j = list_new(NULL);
- if (spec_j->tag.type == TAG_IDENT &&
- (ident = &spec_j->tag.data.ident) &&
- ! frame_get(env->frame, ident->sym)) {
- if (! (var = frame_binding_new(env->frame, ident->sym)))
- goto ko;
- tag_init_copy(&(*tmp_tail_j)->tag, var);
- }
- else if (! env_eval_tag(env, &spec_j->tag, &(*tmp_tail_j)->tag))
- goto ko;
- tmp_tail_j = &(*tmp_tail_j)->next.data.list;
- spec_j = list_next(spec_j);
- }
- tmp_tail = &(*tmp_tail)->next.data.list;
- spec_i = list_next(spec_i);
- }
- if (false) {
- err_write_1("env_facts_with_list: spec = ");
- err_inspect_list((const s_list * const *) &tmp);
- err_write_1("\n");
- }
- if (! (facts_spec = facts_spec_new_list(tmp))) {
- err_puts("env_facts_with_list: facts_spec_new_list");
- assert(! "env_facts_with_list: facts_spec_new_list");
- goto ko;
- }
- if (false) {
- err_write_1("env_facts_with_list: spec = ");
- err_inspect_facts_spec(facts_spec);
- err_write_1("\n");
- }
- if (! facts_with(facts, cursor, facts_spec))
- goto ko;
- free(facts_spec);
- list_delete_all(tmp);
- return cursor;
- ko:
- free(facts_spec);
- list_delete_all(tmp);
- return NULL;
-}
-
s_tag * env_facts_with_tags (s_env *env, s_facts *facts, s_tag *subject,
s_tag *predicate, s_tag *object,
s_fn *callback, s_tag *dest)
diff --git a/libkc3/env.h b/libkc3/env.h
index 4132744..1dc3dff 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -73,10 +73,6 @@ s_tag * env_facts_first_with_tags (s_env *env, s_facts *facts,
s_tag * env_facts_with (s_env *env, s_facts *facts,
s_list **spec, s_fn *callback,
s_tag *dest);
-s_facts_with_cursor *
- env_facts_with_list (s_env *env, s_facts *facts,
- s_facts_with_cursor *cursor,
- s_list *spec);
s_tag * env_facts_with_tags (s_env *env, s_facts *facts,
s_tag *subject, s_tag *predicate,
s_tag *object, s_fn *callback,
diff --git a/libkc3/facts_with.c b/libkc3/facts_with.c
index 76a48a7..9568a6b 100644
--- a/libkc3/facts_with.c
+++ b/libkc3/facts_with.c
@@ -18,6 +18,7 @@
#include "facts_cursor.h"
#include "facts_spec.h"
#include "facts_with.h"
+#include "list.h"
#include "sym.h"
#include "tag.h"
#include "var.h"
@@ -131,6 +132,33 @@ s_facts_cursor * facts_with_3 (s_facts *facts,
return facts_cursor_init(facts, cursor, facts->index_spo, &fact, &fact);
}
+s_facts_with_cursor * facts_with_list (s_facts *facts,
+ s_facts_with_cursor *cursor,
+ s_list *spec)
+{
+ p_facts_spec facts_spec = NULL;
+ assert(facts);
+ assert(cursor);
+ assert(spec);
+ if (! (facts_spec = facts_spec_new_list(spec))) {
+ err_puts("facts_with_list: facts_spec_new_list");
+ assert(! "facts_with_list: facts_spec_new_list");
+ goto ko;
+ }
+ if (false) {
+ err_write_1("facts_with_list: spec = ");
+ err_inspect_facts_spec(facts_spec);
+ err_write_1("\n");
+ }
+ if (! facts_with(facts, cursor, facts_spec))
+ goto ko;
+ free(facts_spec);
+ return cursor;
+ ko:
+ free(facts_spec);
+ return NULL;
+}
+
s_facts_cursor * facts_with_tags (s_facts *facts,
s_facts_cursor *cursor,
s_tag *subject,
diff --git a/libkc3/facts_with.h b/libkc3/facts_with.h
index 904b3a4..72be309 100644
--- a/libkc3/facts_with.h
+++ b/libkc3/facts_with.h
@@ -19,31 +19,35 @@ s_facts_with_cursor * facts_with (s_facts *facts,
s_facts_with_cursor *cursor,
p_facts_spec spec);
-s_facts_cursor * facts_with_0 (s_facts *facts,
- s_facts_cursor *cursor,
- s_var *var_subject,
- s_var *var_predicate,
- s_var *var_object);
-
-s_facts_cursor * facts_with_1_2 (s_facts *facts,
- s_facts_cursor *cursor,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
- s_var *var_subject,
- s_var *var_predicate,
- s_var *var_object);
-
-s_facts_cursor * facts_with_3 (s_facts *facts,
- s_facts_cursor *cursor,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object);
-
-s_facts_cursor * facts_with_tags (s_facts *facts,
- s_facts_cursor *cursor,
- s_tag *subject,
- s_tag *predicate,
- s_tag *object);
+s_facts_cursor * facts_with_0 (s_facts *facts,
+ s_facts_cursor *cursor,
+ s_var *var_subject,
+ s_var *var_predicate,
+ s_var *var_object);
+
+s_facts_cursor * facts_with_1_2 (s_facts *facts,
+ s_facts_cursor *cursor,
+ const s_tag *subject,
+ const s_tag *predicate,
+ const s_tag *object,
+ s_var *var_subject,
+ s_var *var_predicate,
+ s_var *var_object);
+
+s_facts_cursor * facts_with_3 (s_facts *facts,
+ s_facts_cursor *cursor,
+ const s_tag *subject,
+ const s_tag *predicate,
+ const s_tag *object);
+
+s_facts_with_cursor * facts_with_list (s_facts *facts,
+ s_facts_with_cursor *cursor,
+ s_list *spec);
+
+s_facts_cursor * facts_with_tags (s_facts *facts,
+ s_facts_cursor *cursor,
+ s_tag *subject,
+ s_tag *predicate,
+ s_tag *object);
#endif /* LIBKC3_FACTS_WITH_H */
diff --git a/test/ikc3/facts_with.kc3 b/test/ikc3/facts_with.kc3
new file mode 100644
index 0000000..cf9d0a3
--- /dev/null
+++ b/test/ikc3/facts_with.kc3
@@ -0,0 +1,2 @@
+quote Facts.with(Facts.env_db(), [[KC3, :operator, op = ?], [op, :sym, sym = ?]], fn (fact) { puts("#{inspect(op)} #{inspect(sym)}"); 1 })
+Facts.with(Facts.env_db(), [[KC3, :operator, op = ?], [op, :sym, sym = ?]], fn (fact) { puts("#{inspect(op)} #{inspect(sym)}"); 1 })
diff --git a/test/ikc3/facts_with.out.expected b/test/ikc3/facts_with.out.expected
new file mode 100644
index 0000000..32ea5ef
--- /dev/null
+++ b/test/ikc3/facts_with.out.expected
@@ -0,0 +1,33 @@
+Facts.with(Facts.env_db(), [[KC3, :operator, op = ?], [op, :sym, sym = ?]], fn (fact) { puts("#{inspect(op)} #{inspect(sym)}") ; 1 })
+operator_add :+
+operator_addi :+i
+operator_and :&&
+operator_assign :<-
+operator_assign_2 :←
+operator_band :&
+operator_bnot :~
+operator_bor :bor
+operator_brackets :"[]"
+operator_bxor :^
+operator_defstruct :defstruct
+operator_div :/
+operator_eq :==
+operator_equal :=
+operator_gt :>
+operator_gte :>=
+operator_lt :<
+operator_lte :<=
+operator_mod :mod
+operator_mul :*
+operator_neg :-
+operator_not :!
+operator_not_eq :!=
+operator_or :||
+operator_paren :"()"
+operator_pin :^
+operator_require :require
+operator_semicolumn :";"
+operator_shift_left :<<
+operator_shift_right :>>
+operator_sub :-
+1
diff --git a/test/ikc3/facts_with.ret.expected b/test/ikc3/facts_with.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/facts_with.ret.expected
@@ -0,0 +1 @@
+0
diff --git a/test/ikc3/facts_with_tags.kc3 b/test/ikc3/facts_with_tags.kc3
index 7fd66ff..41d7c78 100644
--- a/test/ikc3/facts_with_tags.kc3
+++ b/test/ikc3/facts_with_tags.kc3
@@ -1,26 +1,18 @@
-quote Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) {
- puts(fact.object)
- 1
-})
-Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) {
- puts(fact.object)
- 1
-})
-quote Facts.with_tags(Facts.env_facts(), KC3, :operator, op = ?, fn (fact) {
+quote Facts.with_tags(Facts.env_db(), KC3, :operator, op = ?, fn (fact) {
puts(op)
2
})
-Facts.with_tags(Facts.env_facts(), KC3, :operator, op = ?, fn (fact) {
+Facts.with_tags(Facts.env_db(), KC3, :operator, op = ?, fn (fact) {
puts(op)
2
})
quote op = ? ; void
op = ? ; void
-quote Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) {
+quote Facts.with_tags(Facts.env_db(), KC3, :operator, op, fn (fact) {
puts(op)
3
})
-Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) {
+Facts.with_tags(Facts.env_db(), KC3, :operator, op, fn (fact) {
puts(op)
3
})
@@ -28,11 +20,11 @@ quote type(op)
type(op)
quote op = quote KC3.operator_eq
op = quote KC3.operator_eq
-quote Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) {
+quote Facts.with_tags(Facts.env_db(), KC3, :operator, op, fn (fact) {
puts(op)
4
})
-Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) {
+Facts.with_tags(Facts.env_db(), KC3, :operator, op, fn (fact) {
puts(op)
4
})
diff --git a/test/ikc3/facts_with_tags.out.expected b/test/ikc3/facts_with_tags.out.expected
index 164cffa..e5fa583 100644
--- a/test/ikc3/facts_with_tags.out.expected
+++ b/test/ikc3/facts_with_tags.out.expected
@@ -1,37 +1,4 @@
-Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); 1 })
-operator_add
-operator_addi
-operator_and
-operator_assign
-operator_assign_2
-operator_band
-operator_bnot
-operator_bor
-operator_brackets
-operator_bxor
-operator_defstruct
-operator_div
-operator_eq
-operator_equal
-operator_gt
-operator_gte
-operator_lt
-operator_lte
-operator_mod
-operator_mul
-operator_neg
-operator_not
-operator_not_eq
-operator_or
-operator_paren
-operator_pin
-operator_require
-operator_semicolumn
-operator_shift_left
-operator_shift_right
-operator_sub
-1
-Facts.with_tags(Facts.env_facts(), KC3, :operator, op = ?, fn (fact) { puts(op); 2 })
+Facts.with_tags(Facts.env_db(), KC3, :operator, op = ?, fn (fact) { puts(op); 2 })
operator_add
operator_addi
operator_and
@@ -66,7 +33,7 @@ operator_sub
2
op = ? ; void
void
-Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) { puts(op); 3 })
+Facts.with_tags(Facts.env_db(), KC3, :operator, op, fn (fact) { puts(op); 3 })
operator_add
operator_addi
operator_and
@@ -103,6 +70,6 @@ type(op)
Var
op = quote operator_eq
operator_eq
-Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) { puts(op); 4 })
+Facts.with_tags(Facts.env_db(), KC3, :operator, op, fn (fact) { puts(op); 4 })
operator_eq
4
diff --git a/test/ikc3/facts_with_tuple.kc3 b/test/ikc3/facts_with_tuple.kc3
index 3bad1f7..51b8e35 100644
--- a/test/ikc3/facts_with_tuple.kc3
+++ b/test/ikc3/facts_with_tuple.kc3
@@ -1,8 +1,8 @@
-quote Facts.with_tuple(Facts.env_facts(), {KC3, :operator, ?}, fn (fact) {
+quote Facts.with_tuple(Facts.env_db(), {KC3, :operator, op = ?}, fn (fact) {
puts(fact.object)
void
})
-Facts.with_tuple(Facts.env_facts(), {KC3, :operator, ?}, fn (fact) {
+Facts.with_tuple(Facts.env_db(), {KC3, :operator, op = ?}, fn (fact) {
puts(fact.object)
void
})
diff --git a/test/ikc3/facts_with_tuple.out.expected b/test/ikc3/facts_with_tuple.out.expected
index 9d73fd5..7454c09 100644
--- a/test/ikc3/facts_with_tuple.out.expected
+++ b/test/ikc3/facts_with_tuple.out.expected
@@ -1,4 +1,4 @@
-Facts.with_tuple(Facts.env_facts(), {KC3, :operator, ?}, fn (fact) { puts(fact.object); void })
+Facts.with_tuple(Facts.env_db(), {KC3, :operator, op = ?}, fn (fact) { puts(fact.object); void })
operator_add
operator_addi
operator_and