diff --git a/.ikc3_history b/.ikc3_history
index a5fac91..fa20a8e 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -97,3 +97,4 @@ req = %HTTP.Request{headers: [{"Content-Type", "text/html"}]}
#{req}
"#{req}"
req = %HTTP.Request{headers: ["Content-Type" => "text/html"]}
+
diff --git a/ikc3/.ikc3_history b/ikc3/.ikc3_history
index 6312071..1778370 100644
--- a/ikc3/.ikc3_history
+++ b/ikc3/.ikc3_history
@@ -1,9 +1,3 @@
-[fd: (S32) -1]
-defmodule Socket do defstruct [fd: (S32) -1]; end
-defmodule Socket do
-dlopen("lib/kc3/0.1/http.so")
-def connect = cfn Socket.Buf "socket_buf_init_connect" (Result, Str, Str)
-end
22
server = Socket.listen("192.168.1.50
2
@@ -101,3 +95,6 @@ while (ptr = Facts.Cursor.next(cursor)) do
puts((Tag) f.predicate)
puts((Tag) f.object)
end
+Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact) })
+Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact); void })
+
diff --git a/lib/kc3/0.1/fact.kc3 b/lib/kc3/0.1/fact.kc3
index 4270b85..43d52b6 100644
--- a/lib/kc3/0.1/fact.kc3
+++ b/lib/kc3/0.1/fact.kc3
@@ -9,14 +9,14 @@ defmodule Fact do
def from_ptr = cfn Tag "kc3_fact_from_ptr" (Result, Ptr)
- def object = cfn Tag "kc3_fact_object" (Fact)
+ def object = cfn Tag "kc3_fact_object" (Fact, Result)
- def predicate = cfn Tag "kc3_fact_predicate" (Fact)
+ def predicate = cfn Tag "kc3_fact_predicate" (Fact, Result)
def puts = fn (fact) {
puts("{#{Fact.subject(fact)}, #{Fact.predicate(fact)}, #{Fact.object(fact)}}")
}
- def subject = cfn Tag "kc3_fact_subject" (Fact)
+ def subject = cfn Tag "kc3_fact_subject" (Fact, Result)
end
diff --git a/lib/kc3/0.1/fact_w.kc3 b/lib/kc3/0.1/fact_w.kc3
new file mode 100644
index 0000000..1ee8b48
--- /dev/null
+++ b/lib/kc3/0.1/fact_w.kc3
@@ -0,0 +1,8 @@
+defmodule FactW do
+
+ defstruct [subject: ?,
+ predicate: ?,
+ object: ?,
+ id: (Uw) 0]
+
+end
diff --git a/lib/kc3/0.1/facts.kc3 b/lib/kc3/0.1/facts.kc3
index c298679..d3bc699 100644
--- a/lib/kc3/0.1/facts.kc3
+++ b/lib/kc3/0.1/facts.kc3
@@ -17,11 +17,12 @@ defmodule Facts do
# env_facts() -> facts
def env_facts = cfn Ptr "kc3_env_facts" ()
- # with_tags(facts, subject, predicate, object) -> cursor
- def with_tags = cfn Facts.Cursor "facts_with_tags" (Facts, Result, Tag,
- Tag, Tag)
+ # with_tags(facts, subject, predicate, object,
+ # fn (fact) {result}) -> result
+ def with_tags = cfn Tag "kc3_facts_with_tags" (Facts, Tag, Tag, Tag,
+ Fn, Result)
- # with_tuple(facts, tuple) -> cursor
- def with_tuple = cfn Facts.Cursor "facts_with_tuple" (Facts, Result, Tuple)
+ # with_tuple(facts, tuple, fn (fact) {result}) -> result
+ #def with_tuple = cfn Tag "kc3_facts_with_tuple" (Facts, Tuple, Fn, Result)
end
diff --git a/libkc3/buf_inspect.c b/libkc3/buf_inspect.c
index 2de9462..2e6cb14 100644
--- a/libkc3/buf_inspect.c
+++ b/libkc3/buf_inspect.c
@@ -3150,6 +3150,8 @@ sw buf_inspect_struct (s_buf *buf, const s_struct *s)
if (s->data) {
if (! tag_type(s->type->map.value + i, &type))
goto clean;
+ if (type == &g_sym_Var)
+ type = s->type->map.value[i].data.var.type;
assert(s->type->offset[i] < s->type->size);
if ((r = data_buf_inspect(type, buf, (char *) s->data +
s->type->offset[i])) < 0)
diff --git a/libkc3/data.c b/libkc3/data.c
index 5a24b0c..9b18b2b 100644
--- a/libkc3/data.c
+++ b/libkc3/data.c
@@ -69,6 +69,8 @@ sw data_buf_inspect (const s_sym *type, s_buf *buf, const void *data)
return buf_inspect_sw(buf, data);
if (type == &g_sym_Sym)
return buf_inspect_sym(buf, data);
+ if (type == &g_sym_Tag)
+ return buf_inspect_tag(buf, data);
if (type == &g_sym_Tuple)
return buf_inspect_tuple(buf, data);
if (type == &g_sym_U8)
diff --git a/libkc3/env.c b/libkc3/env.c
index c5fa1c2..469160a 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -32,6 +32,7 @@
#include "env.h"
#include "error.h"
#include "error_handler.h"
+#include "fact.h"
#include "facts.h"
#include "facts_cursor.h"
#include "facts_transaction.h"
@@ -2013,6 +2014,48 @@ s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
return dest;
}
+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)
+{
+ s_list *arguments;
+ s_facts_cursor cursor = {0};
+ const s_fact *fact = NULL;
+ s_fact_w *fact_w = NULL;
+ s_tag tmp = {0};
+ if (! (arguments = list_new_struct(&g_sym_FactW, NULL)))
+ return NULL;
+ if (! struct_allocate(&arguments->tag.data.struct_))
+ return NULL;
+ fact_w = arguments->tag.data.struct_.data;
+ if (! facts_with_tags(facts, &cursor, subject, predicate, object))
+ return NULL;
+ while (1) {
+ if (! facts_cursor_next(&cursor, &fact))
+ goto clean;
+ if (! fact) {
+ goto ok;
+ }
+ tag_clean(&tmp);
+ fact_w_init_fact(fact_w, fact);
+ if (! env_eval_call_fn_args(env, callback, arguments, &tmp)) {
+ fact_w_clean(fact_w);
+ goto clean;
+ }
+ fact_w_clean(fact_w);
+ fact_w_init(fact_w);
+ }
+ ok:
+ list_delete_all(arguments);
+ *dest = tmp;
+ return dest;
+ clean:
+ tag_clean(&tmp);
+ fact_w_clean(fact_w);
+ list_delete_all(arguments);
+ return NULL;
+}
+
const s_tag * env_frames_get (const s_env *env, const s_sym *name)
{
const s_tag *tag;
diff --git a/libkc3/env.h b/libkc3/env.h
index 0ad1be9..4e3e3f3 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -179,6 +179,10 @@ bool env_eval_tuple (s_env *env, const s_tuple *tuple,
bool env_eval_void (s_env *env, const void *_, s_tag *dest);
s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
s_fact_w *dest);
+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);
s_tag * env_ident_get (s_env *env, const s_ident *ident,
s_tag *dest);
bool * env_ident_is_special_operator (s_env *env,
diff --git a/libkc3/fact.c b/libkc3/fact.c
index dd6d9fc..a129f4b 100644
--- a/libkc3/fact.c
+++ b/libkc3/fact.c
@@ -94,3 +94,56 @@ s_fact_w * fact_w_eval (const s_fact_w *fact, s_fact_w *dest)
{
return env_fact_w_eval(&g_kc3_env, fact, dest);
}
+
+s_fact_w * fact_w_init (s_fact_w *fact)
+{
+ s_fact_w tmp = {0};
+ assert(fact);
+ *fact = tmp;
+ return fact;
+}
+
+s_fact_w * fact_w_init_cast (s_fact_w *fact, const s_sym * const *type,
+ const s_tag *tag)
+{
+ assert(fact);
+ assert(type);
+ assert(*type);
+ assert(tag);
+ switch (tag->type) {
+ case TAG_FACT:
+ return fact_w_init_fact(fact, &tag->data.fact);
+ default:
+ break;
+ }
+ err_write_1("fact_w_init_cast: cannot cast from ");
+ err_write_1(tag_type_to_string(tag->type));
+ err_write_1(" to ");
+ if (*type == &g_sym_FactW)
+ err_puts("FactW");
+ else {
+ err_inspect_sym(type);
+ err_puts(" aka FactW");
+ }
+ assert(! "fact_w_init_cast: cannot cast");
+ return NULL;
+}
+
+s_fact_w * fact_w_init_fact (s_fact_w *fact, const s_fact *src)
+{
+ s_fact_w tmp = {0};
+ if (! tag_init_copy(&tmp.subject, src->subject))
+ return NULL;
+ if (! tag_init_copy(&tmp.predicate, src->predicate)) {
+ tag_clean(&tmp.subject);
+ return NULL;
+ }
+ if (! tag_init_copy(&tmp.object, src->object)) {
+ tag_clean(&tmp.predicate);
+ tag_clean(&tmp.subject);
+ return NULL;
+ }
+ *fact = tmp;
+ return fact;
+}
+
diff --git a/libkc3/fact.h b/libkc3/fact.h
index 807296b..6c47b9d 100644
--- a/libkc3/fact.h
+++ b/libkc3/fact.h
@@ -16,13 +16,15 @@
#include "types.h"
/* Stack-allocation compatible functions */
-#define fact_clean(fact) do {} while(0)
-s_fact * fact_init (s_fact *fact, const s_tag *subject,
- const s_tag *predicate, const s_tag *object);
-s_fact * fact_init_cast (s_fact *fact, const s_sym * const *type,
- const s_tag *tag);
-s_fact * fact_init_copy (s_fact *fact, const s_fact *src);
-void fact_w_clean (s_fact_w *fact);
+#define fact_clean(fact) do {} while(0)
+s_fact * fact_init (s_fact *fact, const s_tag *subject,
+ const s_tag *predicate, const s_tag *object);
+s_fact * fact_init_cast (s_fact *fact, const s_sym * const *type,
+ const s_tag *tag);
+s_fact * fact_init_copy (s_fact *fact, const s_fact *src);
+s_fact_w * fact_w_init (s_fact_w *fact);
+s_fact_w * fact_w_init_fact (s_fact_w *fact, const s_fact *src);
+void fact_w_clean (s_fact_w *fact);
/* Observers */
uw * fact_hash_uw (const s_fact *fact, uw *dest);
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index 6b85a7a..966ac45 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -157,34 +157,25 @@ void kc3_exit (sw code)
exit((int) code);
}
-const s_tag * kc3_fact_object (s_fact *fact)
+s_tag * kc3_fact_object (s_fact *fact, s_tag *dest)
{
- if (! fact->object) {
- err_puts("kc3_fact_object: NULL object");
- assert(! "kc3_fact_object: NULL object");
- return NULL;
- }
- return fact->object;
+ if (! fact->object)
+ return tag_init_void(dest);
+ return tag_init_copy(dest, fact->object);
}
-const s_tag * kc3_fact_predicate (s_fact *fact)
+s_tag * kc3_fact_predicate (s_fact *fact, s_tag *dest)
{
- if (! fact->predicate) {
- err_puts("kc3_fact_predicate: NULL predicate");
- assert(! "kc3_fact_predicate: NULL predicate");
- return NULL;
- }
- return fact->predicate;
+ if (! fact->predicate)
+ return tag_init_void(dest);
+ return tag_init_copy(dest, fact->predicate);
}
-const s_tag * kc3_fact_subject (s_fact *fact)
+s_tag * kc3_fact_subject (s_fact *fact, s_tag *dest)
{
- if (! fact->subject) {
- err_puts("kc3_fact_subject: NULL subject");
- assert(! "kc3_fact_subject: NULL subject");
- return NULL;
- }
- return fact->subject;
+ if (! fact->subject)
+ return tag_init_void(dest);
+ return tag_init_copy(dest, fact->subject);
}
s_tag * kc3_fact_from_ptr (s_tag *tag, u_ptr_w *ptr)
@@ -192,17 +183,6 @@ s_tag * kc3_fact_from_ptr (s_tag *tag, u_ptr_w *ptr)
return tag_init_struct_with_data(tag, &g_sym_Fact, ptr->p, false);
}
-s_tag * kc3_facts_cursor_next (s_tag *tag, s_facts_cursor *cursor)
-{
- const s_fact *fact = NULL;
- if (! facts_cursor_next(cursor, &fact))
- return NULL;
- if (! fact)
- return tag_init_void(tag);
- return tag_init_struct_with_data(tag, &g_sym_Fact, (void *) fact,
- false);
-}
-
uw * kc3_facts_next_id (uw *dest)
{
assert(dest);
@@ -210,6 +190,14 @@ uw * kc3_facts_next_id (uw *dest)
return dest;
}
+s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate, s_tag *object,
+ s_fn *callback, s_tag *dest)
+{
+ return env_facts_with_tags(&g_kc3_env, facts, subject, predicate,
+ object, callback, dest);
+}
+
s_tag * kc3_quote_cfn (const s_sym **sym, s_tag *dest)
{
assert(sym);
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index 51c8fa0..c5d1777 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -31,11 +31,9 @@ void kc3_clean (s_env *env);
/* Observers. */
s_tag * kc3_fact_from_ptr (s_tag *tag, u_ptr_w *ptr);
-const s_tag * kc3_fact_object (s_fact *fact);
-const s_tag * kc3_fact_predicate (s_fact *fact);
-const s_tag * kc3_fact_subject (s_fact *fact);
-s_tag * kc3_facts_cursor_next (s_tag *tag,
- s_facts_cursor *cursor);
+s_tag * kc3_fact_object (s_fact *fact, s_tag *dest);
+s_tag * kc3_fact_predicate (s_fact *fact, s_tag *dest);
+s_tag * kc3_fact_subject (s_fact *fact, s_tag *dest);
uw * kc3_facts_next_id (uw *dest);
s_str * kc3_getenv (const s_str *name, s_str *dest);
void kc3_license (void);
@@ -59,6 +57,9 @@ void ** kc3_dlopen (const s_str *path, void **dest);
s_facts * kc3_env_facts (void);
sw kc3_errno (void);
void kc3_exit (sw code);
+s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate, s_tag *object,
+ s_fn *callback, s_tag *dest);
bool kc3_load (const s_str *path);
s_tag * kc3_pin (const s_tag *a, s_tag *dest);
bool kc3_require (const s_sym * const *module);
diff --git a/libkc3/sym.c b/libkc3/sym.c
index 8af0505..e40858d 100644
--- a/libkc3/sym.c
+++ b/libkc3/sym.c
@@ -42,6 +42,7 @@ const s_sym g_sym_F32 = {{{NULL}, 3, {"F32"}}};
const s_sym g_sym_F64 = {{{NULL}, 3, {"F64"}}};
const s_sym g_sym_F128 = {{{NULL}, 3, {"F128"}}};
const s_sym g_sym_Fact = {{{NULL}, 4, {"Fact"}}};
+const s_sym g_sym_FactW = {{{NULL}, 5, {"FactW"}}};
const s_sym g_sym_Fn = {{{NULL}, 2, {"Fn"}}};
const s_sym g_sym_Ident = {{{NULL}, 5, {"Ident"}}};
const s_sym g_sym_Integer = {{{NULL}, 7, {"Integer"}}};
@@ -356,6 +357,7 @@ void sym_init_g_sym (void)
sym_register(&g_sym_F64, NULL);
sym_register(&g_sym_F128, NULL);
sym_register(&g_sym_Fact, NULL);
+ sym_register(&g_sym_FactW, NULL);
sym_register(&g_sym_Fn, NULL);
sym_register(&g_sym_Ident, NULL);
sym_register(&g_sym_Integer, NULL);
diff --git a/libkc3/sym.h b/libkc3/sym.h
index d938762..a3504dd 100644
--- a/libkc3/sym.h
+++ b/libkc3/sym.h
@@ -46,6 +46,7 @@ extern const s_sym g_sym_F32;
extern const s_sym g_sym_F64;
extern const s_sym g_sym_F128;
extern const s_sym g_sym_Fact;
+extern const s_sym g_sym_FactW;
extern const s_sym g_sym_Fn;
extern const s_sym g_sym_Ident;
extern const s_sym g_sym_Integer;