diff --git a/.ikc3_history b/.ikc3_history
index e281f80..97d336e 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,7 +1,3 @@
-Sym.type_size(Str)
-Sym.type_size(HTTP.Response)
-Struct.offset(%HTTP.Response{}, :message)
-Sym.type_size(Str)
Struct.offset(%HTTP.Response{}, :code)
Struct.offset(%HTTP.Response{}, :message)
Struct.offset(%HTTP.Response{}, :response)
@@ -97,3 +93,7 @@ if true do
1
else
quote if true do if true do 1 else 2 end else if true do 3 else 4 end end
+%Fact{}
+Fact.subject(%Fact{})
+Facts.env_facts
+Fact.subject(%Fact{})
diff --git a/ikc3/.ikc3_history b/ikc3/.ikc3_history
index bd6745e..6312071 100644
--- a/ikc3/.ikc3_history
+++ b/ikc3/.ikc3_history
@@ -1,30 +1,3 @@
--256 * 256 / 2
--256 * 256 / 2 + 1
-type(-32767)
-type(-256 * 256 / 2 + 1)
--32767
-type(-32767)
-(S16) -32767
-i = type(-32767)
--32768 * 65536
--32768 * 65536 + 1
--2147483648 * 65536 * 65536 + 1
-q
-%KC3.Operator{}
-%KC3.Operator{sym: :-}
-op = %KC3.Operator{sym: :-}
-op.sym
-op = %{id: 1, sym: :-}
-op.id
-type(op.id)
-type(op.sym)
-(Str) op.sym
-[fd: (S32) -1]
-load("https://git.kmx.io/kc3-lang/kc3/
-)
-load("lib/kc3/0.1/s32.facts")
-(S32) 1
-(S32) -1
[fd: (S32) -1]
defmodule Socket do defstruct [fd: (S32) -1]; end
defmodule Socket do
@@ -97,4 +70,34 @@ quote """a #{:a}"""
quote "a #{:a}"
quote "a"
%Time{}
-
+Facts.env_facts()
+(Facts) Facts.env_facts()
+Facts.with_tags(Facts.env_facts(), ?, ?, ?)
+cursor = Facts.with_tags(Facts.env_facts(), ?, ?, ?)
+tuple = {?, ?, ?}
+cursor = Facts.with_tuple(Facts.env_facts(), tuple)
+a = ?
+b = ?
+c = ?
+s = ?
+p = ?
+o = ?
+cursor = Facts.with_tags(Facts.env_facts(), s, p, o)
+ptr = Facts.Cursor.next(cursor)
+s = ?
+p = ?
+o = ?
+cursor = Facts.with_tags(Facts.env_facts(), s, p, o)
+ptr = Facts.Cursor.next(cursor)
+Fact.from_ptr(ptr)
+tuple = {?, ?, ?}
+cursor = Facts.with_tuple(Facts.env_facts(), tuple)
+ptr = Facts.Cursor.next(cursor)
+tuple = {?, ?, ?}
+cursor = Facts.with_tuple(Facts.env_facts(), tuple)
+while (ptr = Facts.Cursor.next(cursor)) do
+ f = Fact.from_ptr(ptr)
+ puts((Tag) f.subject)
+ puts((Tag) f.predicate)
+ puts((Tag) f.object)
+end
diff --git a/lib/kc3/0.1/fact.kc3 b/lib/kc3/0.1/fact.kc3
new file mode 100644
index 0000000..4270b85
--- /dev/null
+++ b/lib/kc3/0.1/fact.kc3
@@ -0,0 +1,22 @@
+defmodule Fact do
+
+ defstruct [subject: (Ptr) 0,
+ predicate: (Ptr) 0,
+ object: (Ptr) 0,
+ id: (Uw) 0]
+
+ def cast = cfn Tag "tag_init_cast_struct" (Result, Sym, Tag)
+
+ def from_ptr = cfn Tag "kc3_fact_from_ptr" (Result, Ptr)
+
+ def object = cfn Tag "kc3_fact_object" (Fact)
+
+ def predicate = cfn Tag "kc3_fact_predicate" (Fact)
+
+ def puts = fn (fact) {
+ puts("{#{Fact.subject(fact)}, #{Fact.predicate(fact)}, #{Fact.object(fact)}}")
+ }
+
+ def subject = cfn Tag "kc3_fact_subject" (Fact)
+
+end
diff --git a/lib/kc3/0.1/facts.kc3 b/lib/kc3/0.1/facts.kc3
new file mode 100644
index 0000000..c298679
--- /dev/null
+++ b/lib/kc3/0.1/facts.kc3
@@ -0,0 +1,27 @@
+defmodule Facts do
+
+ defstruct [tags: %Set.Tag{},
+ facts: %Set.Fact{},
+ index_spo: (Ptr) 0,
+ index_pos: (Ptr) 0,
+ index_osp: (Ptr) 0,
+ log: (Ptr) 0,
+ next_id: (Uw) 0,
+ rwlock: (Ptr) 0,
+ rwlock_count: (Sw) 0,
+ rwlock_thread: (Ptr) 0,
+ transaction: (Ptr) 0]
+
+ def cast = cfn Tag "tag_init_cast_struct" (Result, Sym, Tag)
+
+ # 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_tuple(facts, tuple) -> cursor
+ def with_tuple = cfn Facts.Cursor "facts_with_tuple" (Facts, Result, Tuple)
+
+end
diff --git a/lib/kc3/0.1/facts/cursor.kc3 b/lib/kc3/0.1/facts/cursor.kc3
new file mode 100644
index 0000000..fa7c1f9
--- /dev/null
+++ b/lib/kc3/0.1/facts/cursor.kc3
@@ -0,0 +1,18 @@
+defmodule Facts.Cursor do
+
+ defstruct [facts: (Ptr) 0,
+ index: (Ptr) 0,
+ node: (Ptr) 0,
+ start: %Fact{},
+ end: %Fact{},
+ var_subject: (Ptr) 0,
+ var_subject_type: Void,
+ var_predicate: (Ptr) 0,
+ var_predicate_type: Void,
+ var_object: (Ptr) 0,
+ var_object_type: Void,
+ mutex: (Ptr) 0]
+
+ def next = cfn Tag "kc3_facts_cursor_next" (Result, Facts.Cursor)
+
+end
diff --git a/lib/kc3/0.1/set.kc3 b/lib/kc3/0.1/set.kc3
new file mode 100644
index 0000000..0d89125
--- /dev/null
+++ b/lib/kc3/0.1/set.kc3
@@ -0,0 +1,8 @@
+defmodule Set do
+
+ defstruct [collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0,
+ max: (Uw) 0]
+
+end
diff --git a/lib/kc3/0.1/set/fact.kc3 b/lib/kc3/0.1/set/fact.kc3
new file mode 100644
index 0000000..519f863
--- /dev/null
+++ b/lib/kc3/0.1/set/fact.kc3
@@ -0,0 +1,8 @@
+defmodule Set.Fact do
+
+ defstruct [collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0,
+ max: (Uw) 0]
+
+end
diff --git a/lib/kc3/0.1/set/item/fact.kc3 b/lib/kc3/0.1/set/item/fact.kc3
new file mode 100644
index 0000000..593d18d
--- /dev/null
+++ b/lib/kc3/0.1/set/item/fact.kc3
@@ -0,0 +1,8 @@
+defmodule Set.Item.Fact do
+
+ defstruct [data: %Fact{},
+ hash: (Uw) 0,
+ next: (Ptr) 0,
+ usage: (Uw) 0]
+
+end
diff --git a/lib/kc3/0.1/set/item/tag.kc3 b/lib/kc3/0.1/set/item/tag.kc3
new file mode 100644
index 0000000..c3797c6
--- /dev/null
+++ b/lib/kc3/0.1/set/item/tag.kc3
@@ -0,0 +1,8 @@
+defmodule Set.Item.Tag do
+
+ defstruct [data: ?,
+ hash: (Uw) 0,
+ next: (Ptr) 0,
+ usage: (Uw) 0]
+
+end
diff --git a/lib/kc3/0.1/set/tag.kc3 b/lib/kc3/0.1/set/tag.kc3
new file mode 100644
index 0000000..c2d7eb3
--- /dev/null
+++ b/lib/kc3/0.1/set/tag.kc3
@@ -0,0 +1,8 @@
+defmodule Set.Tag do
+
+ defstruct [collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0,
+ max: (Uw) 0]
+
+end
diff --git a/lib/kc3/0.1/tag.kc3 b/lib/kc3/0.1/tag.kc3
new file mode 100644
index 0000000..9329f76
--- /dev/null
+++ b/lib/kc3/0.1/tag.kc3
@@ -0,0 +1,5 @@
+defmodule Tag do
+
+ def cast = cfn Tag "tag_init_cast" (Result, Sym, Tag)
+
+end
diff --git a/libkc3/buf_inspect.c b/libkc3/buf_inspect.c
index dc9ed6f..87c6f82 100644
--- a/libkc3/buf_inspect.c
+++ b/libkc3/buf_inspect.c
@@ -3337,18 +3337,24 @@ sw buf_inspect_sym (s_buf *buf, const s_sym * const *sym)
sw buf_inspect_sym_size (s_pretty *pretty, const s_sym * const *sym)
{
- const sw colon_size = 1;
+ sw r;
+ sw size;
const s_sym *x;
+ assert(pretty);
assert(sym);
x = *sym;
assert(x);
if (x->str.size == 0)
- return 3;
+ return buf_write_1_size(pretty, ":\"\"");
if (sym_has_reserved_characters(x))
return buf_inspect_sym_reserved_size(pretty, x);
if (sym_is_module(x) || sym_is_array_type(x))
- return x->str.size;
- return x->str.size + colon_size;
+ return buf_write_str_size(pretty, &x->str);
+ size = x->str.size + 1;
+ if ((r = buf_write_1_size(pretty, ":")) < 0 ||
+ (r = buf_write_str_size(pretty, &x->str)) < 0)
+ return r;
+ return size;
}
sw buf_inspect_sym_reserved (s_buf *buf, const s_sym *x)
diff --git a/libkc3/call.c b/libkc3/call.c
index b0e574f..afef36c 100644
--- a/libkc3/call.c
+++ b/libkc3/call.c
@@ -124,8 +124,10 @@ s_call * call_init_copy (s_call *call, const s_call *src)
(const s_list * const *) &src->arguments))
return NULL;
// FIXME: copy cfn and fn ?
- tmp.cfn = src->cfn;
- tmp.fn = src->fn;
+ if (src->cfn)
+ tmp.cfn = cfn_new_copy(src->cfn);
+ if (src->fn)
+ tmp.fn = fn_new_copy(src->fn);
*call = tmp;
return call;
}
diff --git a/libkc3/facts_with.c b/libkc3/facts_with.c
index 42616e7..790e3b9 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 "sym.h"
#include "tag.h"
s_facts_with_cursor * facts_with (s_facts *facts,
@@ -70,13 +71,13 @@ s_facts_cursor * facts_with_0 (s_facts *facts,
facts_cursor_init(facts, cursor, facts->index_spo, NULL, NULL);
cursor->var_subject = var_subject;
cursor->var_subject_type =
- var_subject ? var_subject->data.var.type : NULL;
+ var_subject ? var_subject->data.var.type : &g_sym_Void;
cursor->var_predicate = var_predicate;
cursor->var_predicate_type =
- var_predicate ? var_predicate->data.var.type : NULL;
+ var_predicate ? var_predicate->data.var.type : &g_sym_Void;
cursor->var_object = var_object;
cursor->var_object_type =
- var_object ? var_object->data.var.type : NULL;
+ var_object ? var_object->data.var.type : &g_sym_Void;
return cursor;
}
@@ -113,13 +114,13 @@ s_facts_cursor * facts_with_1_2 (s_facts *facts,
facts_cursor_init(facts, cursor, tree, &start, &end);
cursor->var_subject = var_subject;
cursor->var_subject_type =
- var_subject ? var_subject->data.var.type : NULL;
+ var_subject ? var_subject->data.var.type : &g_sym_Void;
cursor->var_predicate = var_predicate;
cursor->var_predicate_type =
- var_predicate ? var_predicate->data.var.type : NULL;
+ var_predicate ? var_predicate->data.var.type : &g_sym_Void;
cursor->var_object = var_object;
cursor->var_object_type =
- var_object ? var_object->data.var.type : NULL;
+ var_object ? var_object->data.var.type : &g_sym_Void;
return cursor;
}
@@ -176,3 +177,22 @@ s_facts_cursor * facts_with_tags (s_facts *facts,
return facts_with_1_2(facts, cursor, subject, predicate, object,
var_subject, var_predicate, var_object);
}
+
+s_facts_cursor * facts_with_tuple (s_facts *facts,
+ s_facts_cursor *cursor,
+ s_tuple *fact)
+{
+ assert(facts);
+ assert(cursor);
+ assert(fact);
+ if (fact->count != 3) {
+ err_write_1("facts_with_tuple: Tuple count != 3: ");
+ err_inspect_tuple(fact);
+ err_write_1("\n");
+ assert(! "facts_with_tuple: Tuple count != 3");
+ return NULL;
+ }
+ return facts_with_tags(facts, cursor, fact->tag, fact->tag + 1,
+ fact->tag + 2);
+}
+
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index acf658e..e08c1e4 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -21,6 +21,7 @@
#include "buf_parse.h"
#include "call.h"
#include "env.h"
+#include "facts_cursor.h"
#include "kc3_main.h"
#include "list.h"
#include "map.h"
@@ -138,6 +139,11 @@ void ** kc3_dlopen (const s_str *path, void **dest)
return dest;
}
+s_facts * kc3_env_facts (void)
+{
+ return &g_kc3_env.facts;
+}
+
sw kc3_errno (void)
{
return errno;
@@ -148,6 +154,52 @@ void kc3_exit (sw code)
exit((int) code);
}
+const s_tag * kc3_fact_object (s_fact *fact)
+{
+ if (! fact->object) {
+ err_puts("kc3_fact_object: NULL object");
+ assert(! "kc3_fact_object: NULL object");
+ return NULL;
+ }
+ return fact->object;
+}
+
+const s_tag * kc3_fact_predicate (s_fact *fact)
+{
+ if (! fact->predicate) {
+ err_puts("kc3_fact_predicate: NULL predicate");
+ assert(! "kc3_fact_predicate: NULL predicate");
+ return NULL;
+ }
+ return fact->predicate;
+}
+
+const s_tag * kc3_fact_subject (s_fact *fact)
+{
+ if (! fact->subject) {
+ err_puts("kc3_fact_subject: NULL subject");
+ assert(! "kc3_fact_subject: NULL subject");
+ return NULL;
+ }
+ return fact->subject;
+}
+
+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);
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index 2cafe45..2e29c8a 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -30,6 +30,12 @@ s_env * kc3_init (s_env *env, int *argc, char ***argv);
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);
uw * kc3_facts_next_id (uw *dest);
s_str * kc3_getenv (const s_str *name, s_str *dest);
void kc3_license (void);
@@ -37,25 +43,26 @@ const s_sym ** kc3_module (const s_sym **dest);
sw kc3_puts (const s_tag *tag);
/* Operators. */
-s_tag * kc3_access (const s_tag *tag, const s_sym * const *sym,
- s_tag *dest);
-s_tag * kc3_buf_parse_tag (s_buf *buf, s_tag *dest);
-s_tag * kc3_def (const s_call *call, s_tag *dest);
-s_tag * kc3_defmodule (const s_sym **name, const s_block *block,
- s_tag *dest);
-s_tag * kc3_defoperator (const s_sym **name, const s_sym **sym,
- const s_tag *symbol_value,
- u8 operator_precedence,
- const s_sym **operator_associativity,
+s_tag * kc3_access (const s_tag *tag, const s_sym * const *sym,
+ s_tag *dest);
+s_tag * kc3_buf_parse_tag (s_buf *buf, s_tag *dest);
+s_tag * kc3_def (const s_call *call, s_tag *dest);
+s_tag * kc3_defmodule (const s_sym **name, const s_block *block,
s_tag *dest);
-s_tag * kc3_defstruct (const s_list * const *spec, s_tag *dest);
-void ** kc3_dlopen (const s_str *path, void **dest);
-sw kc3_errno (void);
-void kc3_exit (sw code);
-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);
-s_str * kc3_strerror (sw err_no, s_str *dest);
+s_tag * kc3_defoperator (const s_sym **name, const s_sym **sym,
+ const s_tag *symbol_value,
+ u8 operator_precedence,
+ const s_sym **operator_associativity,
+ s_tag *dest);
+s_tag * kc3_defstruct (const s_list * const *spec, s_tag *dest);
+void ** kc3_dlopen (const s_str *path, void **dest);
+s_facts * kc3_env_facts (void);
+sw kc3_errno (void);
+void kc3_exit (sw code);
+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);
+s_str * kc3_strerror (sw err_no, s_str *dest);
/* Special operators. */
s_tag * kc3_if_then_else (const s_tag *cond, const s_tag *then,
diff --git a/libkc3/list_init.c b/libkc3/list_init.c
index 980680e..d5b2414 100644
--- a/libkc3/list_init.c
+++ b/libkc3/list_init.c
@@ -449,6 +449,18 @@ s_list * list_init_struct (s_list *list, const s_sym *module,
return list;
}
+s_list * list_init_struct_copy (s_list *list, const s_struct *src,
+ s_list *next)
+{
+ s_list tmp = {0};
+ assert(list);
+ list_init(&tmp, next);
+ if (! tag_init_struct_copy(&tmp.tag, src))
+ return NULL;
+ *list = tmp;
+ return list;
+}
+
s_list * list_init_struct_with_data (s_list *list, const s_sym *module,
void *data, bool free_data,
s_list *next)
@@ -1117,6 +1129,19 @@ s_list * list_new_struct (const s_sym *module, s_list *next)
return list;
}
+s_list * list_new_struct_copy (const s_struct *src, s_list *next)
+{
+ s_list *list;
+ list = list_new(next);
+ if (! list)
+ return NULL;
+ if (! tag_init_struct_copy(&list->tag, src)) {
+ free(list);
+ return NULL;
+ }
+ return list;
+}
+
s_list * list_new_struct_with_data (const s_sym *module, void *data,
bool free_data, s_list *next)
{
diff --git a/libkc3/list_init.h b/libkc3/list_init.h
index f7eb9bf..fb94a63 100644
--- a/libkc3/list_init.h
+++ b/libkc3/list_init.h
@@ -70,6 +70,8 @@ s_list * list_init_str_concatenate_list (s_list *list,
s_list * list_init_str_empty (s_list *list, s_list *next);
s_list * list_init_struct (s_list *list, const s_sym *module,
s_list *next);
+s_list * list_init_struct_copy (s_list *list, const s_struct *src,
+ s_list *next);
s_list * list_init_struct_with_data (s_list *list, const s_sym *module,
void *data, bool free_data,
s_list *next);
@@ -142,6 +144,7 @@ s_list * list_new_str_concatenate_list (const s_list **src,
s_list *next);
s_list * list_new_str_empty (s_list *next);
s_list * list_new_struct (const s_sym *module, s_list *next);
+s_list * list_new_struct_copy (const s_struct *src, s_list *next);
s_list * list_new_struct_with_data (const s_sym *module, void *data,
bool free_data, s_list *next);
s_list * list_new_struct_type (const s_sym *module, const s_list *spec,
@@ -208,6 +211,7 @@ s_list * list_str_concatenate (s_list *list, const s_str *a,
s_list * list_str_concatenate_list (s_list *list, const s_list **src);
s_list * list_str_empty (s_list *list);
s_list * list_struct (s_list *list, const s_sym *module);
+s_list * list_struct_copy (s_list *list, const s_struct *src);
s_list * list_struct_with_data (s_list *list, const s_sym *module,
void *data, bool free_data);
s_list * list_struct_type (s_list *list, const s_sym *module,
diff --git a/libkc3/sym.c b/libkc3/sym.c
index 18e3bb4..8af0505 100644
--- a/libkc3/sym.c
+++ b/libkc3/sym.c
@@ -836,6 +836,14 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_pointer;
return true;
}
+ if (sym == &g_sym_Time) {
+ *dest = &ffi_type_pointer;
+ return true;
+ }
+ if (sym == &g_sym_Tuple) {
+ *dest = &ffi_type_pointer;
+ return true;
+ }
if (sym == &g_sym_U8) {
*dest = &ffi_type_uint8;
return true;
diff --git a/libkc3/tag.c b/libkc3/tag.c
index 79ac174..6f6f108 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -538,6 +538,55 @@ s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
return NULL;
}
+s_tag * tag_init_cast (s_tag *tag, const s_sym * const *type,
+ s_tag *src)
+{
+ assert(tag);
+ assert(type);
+ assert(*type);
+ assert(src);
+ switch (src->type) {
+ case TAG_PTR:
+ if (*type != &g_sym_Tag)
+ break;
+ return tag_init_copy(tag, src->data.ptr.p);
+ default:
+ break;
+ }
+ err_puts("tag_init_cast: invalid cast");
+ assert(! "tag_init_cast: invalid cast");
+ return NULL;
+}
+
+s_tag * tag_init_cast_struct (s_tag *tag, const s_sym * const *type,
+ s_tag *src)
+{
+ assert(tag);
+ assert(type);
+ assert(*type);
+ assert(src);
+ switch (src->type) {
+ case TAG_PTR:
+ if (! src->data.ptr.p)
+ return tag_init_void(tag);
+ return tag_init_struct_with_data(tag, *type, src->data.ptr.p,
+ false);
+ case TAG_PTR_FREE:
+ if (! src->data.ptr_free.p)
+ return tag_init_void(tag);
+ return tag_init_struct_with_data(tag, *type, src->data.ptr_free.p,
+ false);
+ case TAG_STRUCT:
+ if (*type == src->data.struct_.type->module)
+ return tag_init_struct_copy(tag, &src->data.struct_);
+ default:
+ break;
+ }
+ err_puts("tag_init_cast_struct: invalid cast");
+ assert(! "tag_init_cast_struct: invalid cast");
+ return NULL;
+}
+
s_tag * tag_integer_reduce (s_tag *tag)
{
s_integer *i;
@@ -1135,7 +1184,7 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
goto invalid_cast;
case TAG_PTR:
if (type == &g_sym_Ptr) {
- *dest = &tag->data.ptr.p;
+ *dest = &tag->data.ptr;
return true;
}
*dest = tag->data.ptr.p;
@@ -1143,7 +1192,7 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
case TAG_PTR_FREE:
if (type == &g_sym_Ptr ||
type == &g_sym_PtrFree) {
- *dest = &tag->data.ptr_free.p;
+ *dest = &tag->data.ptr_free;
return true;
}
*dest = tag->data.ptr.p;
@@ -1175,6 +1224,11 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
*dest = &tag->data.struct_;
return true;
}
+ if (type == &g_sym_Ptr) {
+ *dest = &tag->data.struct_.data;
+ assert(*dest);
+ return true;
+ }
if (type == tag->data.struct_.type->module) {
*dest = tag->data.struct_.data;
assert(*dest);
diff --git a/libkc3/tag.h b/libkc3/tag.h
index 13abd07..f61507a 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -34,6 +34,8 @@ void tag_clean (s_tag *tag);
s_tag * tag_init (s_tag *tag);
s_tag * tag_init_1 (s_tag *tag, const char *p);
s_tag * tag_init_call_cast (s_tag *tag, const s_sym *type);
+s_tag * tag_init_facts_cast (s_tag *tag, const s_sym * const *type,
+ s_tag *src);
/* Heap-allocation functions, call tag_delete after use. */
void tag_delete (s_tag *tag);
diff --git a/libkc3/tag_init.c b/libkc3/tag_init.c
index 577c2b5..d0a95ee 100644
--- a/libkc3/tag_init.c
+++ b/libkc3/tag_init.c
@@ -438,6 +438,17 @@ s_tag * tag_init_struct (s_tag *tag, const s_sym *module)
return tag;
}
+s_tag * tag_init_struct_copy (s_tag *tag, const s_struct *src)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_STRUCT;
+ if (! struct_init_copy(&tmp.data.struct_, src))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
void *data, bool free_data)
{
@@ -1104,6 +1115,20 @@ s_tag * tag_new_struct (const s_sym *module)
return tag;
}
+s_tag * tag_new_struct_copy (const s_struct *src)
+{
+ s_tag *tag;
+ tag = alloc(sizeof(s_tag));
+ if (! tag)
+ return NULL;
+ tag->type = TAG_STRUCT;
+ if (! struct_init_copy(&tag->data.struct_, src)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
s_tag * tag_new_struct_with_data (const s_sym *module, void *data,
bool free_data)
{
@@ -1754,6 +1779,18 @@ s_tag * tag_struct (s_tag *tag, const s_sym *module)
return tag;
}
+s_tag * tag_struct_copy (s_tag *tag, const s_struct *src)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_STRUCT;
+ if (! struct_init_copy(&tmp.data.struct_, src))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
void *data, bool free_data)
{
diff --git a/libkc3/tag_init.h b/libkc3/tag_init.h
index 38c7c39..a086916 100644
--- a/libkc3/tag_init.h
+++ b/libkc3/tag_init.h
@@ -56,6 +56,7 @@ s_tag * tag_init_str_concatenate (s_tag *tag, const s_str *a,
s_tag * tag_init_str_concatenate_list (s_tag *tag, const s_list **src);
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_copy (s_tag *tag, const s_struct *src);
s_tag * tag_init_struct_with_data (s_tag *tag, const s_sym *module,
void *data, bool free_data);
s_tag * tag_init_struct_type (s_tag *tag, const s_sym *module,
@@ -120,6 +121,7 @@ s_tag * tag_new_str_concatenate (const s_str *a, const s_str *b);
s_tag * tag_new_str_concatenate_list (const s_list **src);
s_tag * tag_new_str_empty (void);
s_tag * tag_new_struct (const s_sym *module);
+s_tag * tag_new_struct_copy (const s_struct *src);
s_tag * tag_new_struct_with_data (const s_sym *module, void *data,
bool free_data);
s_tag * tag_new_struct_type (const s_sym *module, const s_list *spec);
@@ -182,6 +184,7 @@ s_tag * tag_str_concatenate (s_tag *tag, const s_str *a,
s_tag * tag_str_concatenate_list (s_tag *tag, const s_list **src);
s_tag * tag_str_empty (s_tag *tag);
s_tag * tag_struct (s_tag *tag, const s_sym *module);
+s_tag * tag_struct_copy (s_tag *tag, const s_struct *src);
s_tag * tag_struct_with_data (s_tag *tag, const s_sym *module,
void *data, bool free_data);
s_tag * tag_struct_type (s_tag *tag, const s_sym *module,
diff --git a/libkc3/tag_init.rb b/libkc3/tag_init.rb
index 0c44e65..ccf62a9 100644
--- a/libkc3/tag_init.rb
+++ b/libkc3/tag_init.rb
@@ -380,6 +380,8 @@ class TagInitList
TagInit.new("str", "empty", "TAG_STR", :init_mode_init, []),
TagInit.new("struct", "TAG_STRUCT", :init_mode_init,
[Arg.new("const s_sym *", "module")]),
+ TagInit.new("struct", "copy", "TAG_STRUCT", :init_mode_init,
+ [Arg.new("const s_struct *", "src")]),
TagInit.new("struct", "with_data", "TAG_STRUCT", :init_mode_init,
[Arg.new("const s_sym *", "module"),
Arg.new("void *", "data"),
diff --git a/test/ikc3/facts.kc3 b/test/ikc3/facts.kc3
new file mode 100644
index 0000000..9184df5
--- /dev/null
+++ b/test/ikc3/facts.kc3
@@ -0,0 +1,16 @@
+quote %Fact{}
+%Fact{}
+quote %Set.Tag{}
+%Set.Tag{}
+quote %Set.Fact{}
+%Set.Fact{}
+quote %Facts{}
+%Facts{}
+quote Facts.env_facts()
+Facts.env_facts()
+quote cursor = Facts.with_tags(Facts.env_facts(), KC3, :is_a, :module)
+cursor = Facts.with_tags(Facts.env_facts(), KC3, :is_a, :module)
+quote ptr = Facts.Cursor.next(cursor)
+ptr = Facts.Cursor.next(cursor)
+quote f = (Fact) ptr
+f = (Fact) ptr
diff --git a/test/ikc3/facts.out.expected b/test/ikc3/facts.out.expected
new file mode 100644
index 0000000..0265534
--- /dev/null
+++ b/test/ikc3/facts.out.expected
@@ -0,0 +1,43 @@
+%Fact{}
+%Fact{subject: (Ptr) 0x0,
+ predicate: (Ptr) 0x0,
+ object: (Ptr) 0x0,
+ id: (Uw) 0}
+%Set.Tag{}
+%Set.Tag{collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0x0,
+ max: (Uw) 0}
+%Set.Fact{}
+%Set.Fact{collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0x0,
+ max: (Uw) 0}
+%Facts{}
+%Facts{tags: %Set.Tag{collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0x0,
+ max: (Uw) 0},
+ facts: %Set.Fact{collisions: (Uw) 0,
+ count: (Uw) 0,
+ items: (Ptr) 0x0,
+ max: (Uw) 0},
+ index_spo: (Ptr) 0x0,
+ index_pos: (Ptr) 0x0,
+ index_osp: (Ptr) 0x0,
+ log: (Ptr) 0x0,
+ next_id: (Uw) 0,
+ rwlock: (Ptr) 0x0,
+ rwlock_count: (Sw) 0,
+ rwlock_thread: (Ptr) 0x0,
+ transaction: (Ptr) 0x0}
+Facts.env_facts()
+(Ptr) 0x56bcf40e2d8
+cursor = Facts.with_tags(Facts.env_facts(), KC3, :is_a, :module)
+%Facts.Cursor{facts: (Ptr) 0x56bcf40e2d8,
+ index: (Ptr) 0x56b5d04b700,
+ node: (Ptr) 0x56af5ea3120,
+ start: %Fact{subject: (Ptr) 0x0,
+ predicate: (Ptr) 0x0,
+ object: (Ptr) 0x0}}
+
diff --git a/test/ikc3/facts.ret.expected b/test/ikc3/facts.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/facts.ret.expected
@@ -0,0 +1 @@
+0