diff --git a/.ikc3_history b/.ikc3_history
index 14d5db1..bc800e4 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,80 +1,3 @@
-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
-Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact) })
-Facts.with_tags(Facts.env_facts(), ?, ?, ?, fn (fact) { puts(fact); void })
-Facts.with_tags(Facts.env_facts(), KC3, ?, ?, fn (fact) { puts(fact); void })
-Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact); void })
-Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[KC3, :operator, ?]], fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[KC3, ?, ?]], fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[KC3, :load_time, ?]], fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[?, :load_time, ?]], fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[KC3, :operator, ?]], fn (fact) { puts(fact.object); void })
-quote operator_eq(a, b)
-Facts.with(Facts.env_facts(), [[KC3, :symbol_value, ?]], fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[?, :symbol_value, ?]], fn (fact) { puts("#{fact.subject} = #{fact.object}"); void })
-Facts.with(Facts.env_facts(), [[?, :symbol_value, ?]], fn (fact) { puts(fact.subject); puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[?, :symbol_value, object = ?], [object, ], fn (fact) { puts(fact.subject); puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[KC3, :operator, ?]], fn (fact) { puts(fact.object); void })
-quote if true do if false do %KC3.Operator{} end end
-if true do if true do %KC3.Operator{} end end
-1 + 100000000000000000000000000000
-1 +i 1
-1 / 2
-1/2
-1.0 / 2
-1.0 / 2 + 1/2
-1.0 / 2 + 0.5
-Facts.with(Facts.env_facts(), [[KC3, :operator, ?]], fn (fact) { puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[?, :operator, ?]], fn (fact) { puts(fact.subject); puts(fact.object); void })
-Facts.with(Facts.env_facts(), [[plop, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(value); void })
-Facts.with(Facts.env_facts(), quote [[plop, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(value); void })
-a = ?
-b = ?
-c = ?
-Facts.with_tags(Facts.env_facts(), a, b, c, fn (fact) { puts(a); puts(b); puts(c); void })
-a = ?
-b = ?
-c = ?
-Facts.with_tags(Facts.env_facts(), a, b, c, fn (fact) { puts(a); puts(b); puts(c); void })
-a = ?
-b = ?
-c = ?
-Facts.with_tags(Facts.env_facts(), a, b, c, fn (fact) { puts(a); puts(b); puts(c); void })
-a = ?
-b = ?
-c = ?
-Facts.with_tags(Facts.env_facts(), a, b, c, fn (fact) { puts(a); puts(b); puts(c); void })
-a
-a <- 1
-type(a)
-(Ptr) a
-a = ?
-type(a)
-(Ptr) a
-a = ?
-b = ?
-c = ?
-Facts.with_tags(Facts.env_facts(), a, b, c, fn (fact) { puts(a); puts(b); puts(c); void })
-a <- 1
-a = ?
-a <- 1
a = ?
a <- 1
a
@@ -97,3 +20,80 @@ a = ?
b = ?
c = ?
Facts.with_tags(Facts.env_facts(), a, b, c, fn (fact) { puts(a); puts(b); puts(c); void })
+Facts.with(Facts.env_facts(), quote [[plop, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(value); void })
+Facts.with(Facts.env_facts(), [[plop = ?, :operator, op = ?], [op, :symbol_value, value = ?]], fn (fact) { puts(value); void })
+Facts.with(Facts.env_facts(), quote [[plop, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(value); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(value); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op]], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), [[KC3, :operator, op]], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op]], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), quote [KC3, :operator, op], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op = ?]], fn (fact) { puts(op); void })
+op = ?; Facts.with(Facts.env_facts(), [[KC3, :operator, op]], fn (fact) { puts(op); void })
+op = ? ; Facts.with(Facts.env_facts(), [[KC3, :operator, op]], fn (fact) { puts(op); void })
+op = ?
+Facts.with(Facts.env_facts(), [[KC3, :operator, op]], fn (fact) { puts(op); void })
+op = ?
+Facts.with(Facts.env_facts(), [[KC3, :operator, op]], fn (fact) { puts(op); void })
+Facts.with_tags(Facts.env_facts(), KC3, :operator, op, fn (fact) { puts(op); void })
+1 + 10000000000000000000000000
+
+1 + 1
+quote 1 + 1
+List.map([1, 2, 3], fn (x) { x * 2 })
+a = ?
+b = ?
+c = ?
+Facts.with_tags(Facts.env_facts(), KC3, :operator, a, fn (fact) { puts(a); void })
+quote if true do if true do %KC3.Operator{} end end
+quote if true do if true do unquote(%KC3.Operator{}) end end
+Facts.with(Facts.env_facts(), [[KC3, :operator, op], [op, :symbol_value, value], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [op, :symbol_value, value], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(op); void })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, ^ op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+op = ?
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, ^ op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+op = ?
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, ^ op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+op = ?
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, ^ op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+op = ?
+op <- 1
+op
+op <- ?
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, ^ op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, unquote(op)], [unquote(op), :symbol_value, value]], fn (fact) { puts(op); 1 })
+op = ?
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, unquote(op)], [unquote(op), :symbol_value, value]], fn (fact) { puts(op); 1 })
+op
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op = ?], [op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op], [^ op, :symbol_value, value]], fn (fact) { puts(op); 1 })
+Facts.with(Facts.env_facts(), quote [[KC3, :operator, op]], fn (fact) { puts(op); 1 })
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); 1 })
+?
+a = ?
+?
+a
+a = ?
+a
+a = ?
+a
+a <- 1
+a
+(U8) (Ptr) a
+(Tag) (Ptr) a
+(Ptr) a
+(Tag) (Ptr) a
+a = ?
+a
+(Ptr) a
+a = ?
+a
+a <- 1
+a
+(Ptr) 0x1801350e830
+(Tag) (Ptr) 0x1801350e830
diff --git a/libkc3/buf_inspect.c b/libkc3/buf_inspect.c
index 2e6cb14..a36cb3d 100644
--- a/libkc3/buf_inspect.c
+++ b/libkc3/buf_inspect.c
@@ -3745,12 +3745,20 @@ sw buf_inspect_var (s_buf *buf, const s_tag *tag)
assert(tag);
assert(tag->type == TAG_VAR);
assert(tag->data.var.type);
- if (tag->data.var.type == &g_sym_Tag)
- return buf_write_1(buf, "?");
- if ((r = buf_inspect_paren_sym(buf, tag->data.var.type)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1(buf, " ?")) < 0)
+ if (tag->data.var.type == &g_sym_Tag) {
+ if ((r = buf_write_1(buf, "?0x")) < 0)
+ return r;
+ }
+ else {
+ if ((r = buf_inspect_paren_sym(buf, tag->data.var.type)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1(buf, " ?0x")) < 0)
+ return r;
+ result += r;
+ }
+ if ((r = buf_inspect_uw_hexadecimal
+ (buf, (uw *) &tag->data.var.ptr)) < 0)
return r;
result += r;
return result;
@@ -3760,12 +3768,25 @@ sw buf_inspect_var_size (s_pretty *pretty, const s_tag *tag)
{
sw r;
sw result = 0;
- if (tag->data.var.type == &g_sym_Tag)
- return buf_write_1_size(pretty, "?");
- if ((r = buf_inspect_paren_sym_size(pretty, tag->data.var.type)) < 0)
- return r;
- result += r;
- if ((r = buf_write_1_size(pretty, " ?")) < 0)
+ assert(pretty);
+ assert(tag);
+ assert(tag->type == TAG_VAR);
+ assert(tag->data.var.type);
+ if (tag->data.var.type == &g_sym_Tag) {
+ if ((r = buf_write_1_size(pretty, "?")) < 0)
+ return r;
+ }
+ else {
+ if ((r = buf_inspect_paren_sym_size(pretty,
+ tag->data.var.type)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_1_size(pretty, " ?")) < 0)
+ return r;
+ result += r;
+ }
+ if ((r = buf_inspect_uw_hexadecimal_size
+ (pretty, (uw *) &tag->data.var.ptr)) < 0)
return r;
result += r;
return result;
diff --git a/libkc3/env.c b/libkc3/env.c
index e5a242d..78d2e84 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -1982,14 +1982,10 @@ bool env_eval_var (s_env *env, const s_tag *tag, s_tag *dest)
if (tag->type != TAG_VAR)
return false;
var = &tag->data.var;
- if (var->ptr && var->ptr->type != TAG_VAR) {
- if (! tag_init_copy(dest, var->ptr))
- return false;
- return true;
- }
+ if (var->ptr && var->ptr->type != TAG_VAR)
+ return tag_init_copy(dest, var->ptr) ? true : false;
tmp.type = TAG_VAR;
- if (! var->ptr ||
- var->ptr == tag)
+ if (! var->ptr)
tmp.data.var.ptr = dest;
else
tmp.data.var.ptr = var->ptr;
@@ -2078,6 +2074,8 @@ s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
*dest = tmp;
return dest;
clean:
+ err_puts("env_facts_with: error");
+ assert(! "env_facts_with: error");
tag_clean(&tmp);
fact_w_clean(fact_w);
list_delete_all(arguments);
@@ -2094,7 +2092,7 @@ s_facts_with_cursor * env_facts_with_list (s_env *env, s_facts *facts,
s_list *tmp;
s_list **tmp_tail;
s_list **tmp_tail_j;
- p_facts_spec facts_spec;
+ p_facts_spec facts_spec = NULL;
s_tag *var;
assert(facts);
assert(cursor);
@@ -2111,34 +2109,43 @@ s_facts_with_cursor * env_facts_with_list (s_env *env, s_facts *facts,
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;
- if (! (var = binding_get_w(env->frame->bindings, ident->sym))) {
- if (! (var = frame_binding_new(env->frame, ident->sym)))
- goto ko;
- tag_init_var(var, &g_sym_Tag);
- }
+ 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;
+ 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 (true) {
+ 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 (true) {
+ 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;
}
@@ -2154,9 +2161,8 @@ s_tag * env_facts_with_tags (s_env *env, s_facts *facts, s_tag *subject,
s_tag tmp = {0};
if (! (arguments = list_new_struct(&g_sym_FactW, NULL)))
return NULL;
- if (! (arguments->tag.data.struct_.data = alloc(sizeof(s_fact_w))))
+ if (! struct_allocate(&arguments->tag.data.struct_))
return NULL;
- arguments->tag.data.struct_.free_data = true;
fact_w = arguments->tag.data.struct_.data;
if (! facts_with_tags(facts, &cursor, subject, predicate, object))
return NULL;
diff --git a/libkc3/frame.c b/libkc3/frame.c
index d29d9b9..37a3d87 100644
--- a/libkc3/frame.c
+++ b/libkc3/frame.c
@@ -15,6 +15,7 @@
#include "binding.h"
#include "frame.h"
#include "list.h"
+#include "sym.h"
#include "tag.h"
s_tag * frame_binding_new (s_frame *frame, const s_sym *name)
@@ -24,11 +25,12 @@ s_tag * frame_binding_new (s_frame *frame, const s_sym *name)
if (! b)
return NULL;
frame->bindings = b;
+ tag_init_var(&b->value, &g_sym_Tag);
return &b->value;
}
s_frame * frame_binding_new_copy (s_frame *frame, const s_sym *name,
- const s_tag *value)
+ s_tag *value)
{
s_tag *tag;
frame_binding_new(frame, name);
@@ -38,8 +40,10 @@ s_frame * frame_binding_new_copy (s_frame *frame, const s_sym *name,
assert(! "frame_binding_new_copy: binding new");
return NULL;
}
- if (value->type == TAG_VAR)
+ if (value->type == TAG_VAR) {
tag_init_var(tag, value->data.var.type);
+ value->data.var.ptr = tag->data.var.ptr;
+ }
else if (! tag_init_copy(tag, value)) {
err_puts("frame_binding_new_copy: tag_init_copy");
assert(! "frame_binding_new_copy: tag_init_copy");
@@ -167,7 +171,7 @@ s_frame * frame_new (s_frame *next)
}
s_frame * frame_replace (s_frame *frame, const s_sym *sym,
- const s_tag *value)
+ s_tag *value)
{
s_frame *f;
s_tag *result;
@@ -177,8 +181,10 @@ s_frame * frame_replace (s_frame *frame, const s_sym *sym,
result = binding_get_w(f->bindings, sym);
if (result) {
tag_clean(result);
- if (value->type == TAG_VAR)
+ if (value->type == TAG_VAR) {
tag_init_var(result, value->data.var.type);
+ value->data.var.ptr = result->data.var.ptr;
+ }
else
tag_init_copy(result, value);
return frame;
diff --git a/libkc3/frame.h b/libkc3/frame.h
index fddd721..503eabf 100644
--- a/libkc3/frame.h
+++ b/libkc3/frame.h
@@ -32,12 +32,12 @@ const s_tag * frame_get (const s_frame *frame, const s_sym *sym);
/* Operators. */
s_tag * frame_binding_new (s_frame *frame, const s_sym *name);
s_frame * frame_binding_new_copy (s_frame *frame, const s_sym *name,
- const s_tag *value);
+ s_tag *value);
s_frame * frame_binding_delete (s_frame *frame, const s_sym *name);
s_frame * frame_binding_replace (s_frame *frame, const s_sym *name,
const s_tag *value);
s_tag * frame_get_w (s_frame *frame, const s_sym *sym);
s_frame * frame_replace (s_frame *frame, const s_sym *sym,
- const s_tag *value);
+ s_tag *value);
#endif /* LIBKC3_FRAME_H */
diff --git a/libkc3/io.c b/libkc3/io.c
index af67315..3745a1e 100644
--- a/libkc3/io.c
+++ b/libkc3/io.c
@@ -190,6 +190,7 @@ DEF_ERR_IO_INSPECT(call, const s_call *)
DEF_ERR_IO_INSPECT(character, const character *)
DEF_ERR_IO_INSPECT(f32, const f32 *)
DEF_ERR_IO_INSPECT(fact, const s_fact *)
+DEF_ERR_IO_INSPECT(facts_spec, const p_facts_spec)
DEF_ERR_IO_INSPECT(fn_pattern, const s_list *)
DEF_ERR_IO_INSPECT(ident, const s_ident *)
DEF_ERR_IO_INSPECT(list, const s_list * const *)
diff --git a/test/json/inspect.kc3 b/test/json/inspect.kc3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/json/inspect.kc3