diff --git a/.ikc3_history b/.ikc3_history
index fa20a8e..ece84e2 100644
--- a/.ikc3_history
+++ b/.ikc3_history
@@ -1,3 +1,27 @@
+server = Socket.listen("192.168.2.50", "58000")
+server_client = Socket.Buf.accept(server)
+req = HTTP.Request.buf_parse(server_client.buf_rw.r)
+%HTTP.Response{}
+Struct.offset(%HTTP.Response{}, :message)
+Sym.type_size(Str)
+Struct.offset(%HTTP.Response{}, :message)
+res = %HTTP.Response{}
+res.message
+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)
+Struct.offset(%HTTP.Response{}, :protocol)
+Struct.offset(%HTTP.Response{}, :code)
+Struct.offset(%HTTP.Response{}, :message)
+Struct.offset(%HTTP.Response{}, :headers)
+Struct.offset(%HTTP.Response{}, :body)
+Struct.offset(%HTTP.Response{}, :message)
+Struct.offset(%HTTP.Response{}, :protocol)
+Struct.offset(%HTTP.Response{}, :code)
Struct.offset(%HTTP.Response{}, :message)
Struct.offset(%HTTP.Response{}, :headers)
Struct.offset(%HTTP.Response{}, :body)
@@ -19,82 +43,58 @@ Struct.offset(%HTTP.Response{}, :body)
quote "a#{a}"
"a#{a}"
"a#{:a}"
+quote "a#{a}"
+quote "a#{:a}"
+quote "a"
+quote "a #{:a}"
+"a #{:a}"
+"""a #{:a}"""
+"""a #{":a"}"""
+quote """a #{":a"}"""
+"""a #{":a"}"""
+quote "a#{a}"
quote "a#{:a}"
-quote "a#{%KC3.Operator{}}"
-quote "a#{%KC3.Operator{sym: :-}}"
-type(18446744073709551615)
-18446744073709551615
-type(4294967296)
-type( -2147483648)
-type(4294967296)
-type(-9223372036854775808)
-File.exists?("env")
-File.exists?("env4")
-File.exists?("lib/kc3/0.1/file.kc3")
-File.stat("env")
-File.stat("env").st_mode
-def is_directory? = fn (path) { List.has(File.stat(path).st_mode, :directory) }
-File.stat("libkc3").st_mode
-List.has
-def is_directory? = fn (path) { List.has(File.stat(path).st_mode, :directory) }
-List.has
-List.has?
-is_directory?("env")
-def is_directory? = fn (path) { List.has?(File.stat(path).st_mode, :directory) }
-is_directory?("env")
-is_directory?("libkc3")
-def is_directory? = fn (path) { List.has?(File.stat(path).st_mode, :directory) }
-File.is_directory?("env")
-File.is_directory?("libkc3")
-File.is_directory?("plop1234")
-File.is_directory?("env")
-File.list(lib)
-File.list("lib")
-File.list("lib/kc3")
-File.list("lib/kc3/0.1")
-Str.starts_with?("abc", "a")
-Str.starts_with?("abc", "b")
-Str.ends_with?("abc", "b")
-Str.ends_with?("abc", "c")
-Str.ends_with?("abc/", "/")
-File.read("env")
-HTTP.mime_type_load("test/httpd/mime.types")
-HTTP.mime_type("txt")
-HTTP.mime_type("html")
-HTTP.mime_type("zorglub")
-HTTP.mime_type_load("test/httpd/mime.types")
-HTTP.mime_type("zorglub")
-HTTP.mime_type_def(:zorglub, :application/zorglub)
-HTTP.mime_type("zorglub")
-Str.rindex("abc.def", ".")
-Str.rindex_character("abc.def", '.')
-File.ext("abc.def")
-require HTTPd
-HTTP.Event.version
-HTTP.Event.version()
-%KC3.Operator{}
-quote %{a: %{b: "b", c: "c"}, d: "d"}
-%KC3.Operator{}
-%{op1: %KC3.Operator{}, op2: %KC3.Operator{}}
-quote do do do 1 2 3 end end end
-quote do do do 1; 2; 3 end end end
-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{})
-%Socket.Buf{}
-quote quote quote %Socket.Buf{}
-quote quote quote %Socket.Buf{sockfd: (S32) 1}
-"#{%Socket.Buf{}}"
-%HTTP.Request{}
-"#{%HTTP.Request{}}"
-"#{%HTTP.Request{headers: [{"Content-Type", "text/html"}]}}"
-req = %HTTP.Request{headers: [{"Content-Type", "text/html"}]}
-#{req}
-"#{req}"
-req = %HTTP.Request{headers: ["Content-Type" => "text/html"]}
+quote """a#{:a}"""
+quote """a#{"a"}"""
+quote """a#{:a}"""
+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
+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 })
diff --git a/ikc3/.ikc3_history b/ikc3/.ikc3_history
index 1778370..4ccc89a 100644
--- a/ikc3/.ikc3_history
+++ b/ikc3/.ikc3_history
@@ -1,5 +1,3 @@
-22
-server = Socket.listen("192.168.1.50
2
server = Socket.listen("192.168.2.50", "58000")
server_client = Socket.Buf.accept(server)
@@ -97,4 +95,5 @@ while (ptr = Facts.Cursor.next(cursor)) do
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, :operator, ?, fn (fact) { puts(fact); void })
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
diff --git a/libkc3/map.c b/libkc3/map.c
index 475d1c8..19a4e5b 100644
--- a/libkc3/map.c
+++ b/libkc3/map.c
@@ -108,6 +108,21 @@ const s_sym ** map_get_type (const s_map *map, const s_tag *key,
return NULL;
}
+const s_sym ** map_get_var_type (const s_map *map, const s_tag *key,
+ const s_sym **dest)
+{
+ uw i = 0;
+ while (i < map->count) {
+ if (compare_tag(key, map->key + i) == 0)
+ return tag_var_type(map->value + i, dest);
+ i++;
+ }
+ err_write_1("map_get_type: ");
+ err_inspect_tag(key);
+ err_puts(": key not found");
+ return NULL;
+}
+
s_map * map_init (s_map *map, uw count)
{
s_map tmp = {0};
diff --git a/libkc3/map.h b/libkc3/map.h
index a1bc363..f2f9996 100644
--- a/libkc3/map.h
+++ b/libkc3/map.h
@@ -41,6 +41,8 @@ s_map * map_cast (const s_tag *tag, s_map *map);
s_tag * map_get (const s_map *map, const s_tag *key, s_tag *dest);
const s_sym ** map_get_type (const s_map *map, const s_tag *key,
const s_sym **dest);
+const s_sym ** map_get_var_type (const s_map *map, const s_tag *key,
+ const s_sym **dest);
s_map * map_update (const s_map *map, const s_tag *key,
const s_tag *value, s_map *dest);
s_map * map_update_list (const s_map *map, const s_list *alist,
diff --git a/libkc3/struct.c b/libkc3/struct.c
index 55006f6..559b1ac 100644
--- a/libkc3/struct.c
+++ b/libkc3/struct.c
@@ -70,19 +70,21 @@ s_tag * struct_access_sym (const s_struct *s, const s_sym *key, s_tag *dest)
const s_sym *type;
s_tag tmp = {0};
void *tmp_data;
- if (! struct_get_type(s, key, &type))
- return NULL;
+ if (! struct_get_var_type(s, key, &type))
+ return NULL;
data = struct_get(s, key);
if (! data)
return NULL;
- if (! sym_to_tag_type(type, &tmp.type))
- return NULL;
- if (! struct_type_find(type, &st))
- return NULL;
- if (st) {
- tmp.data.struct_.type = st;
- if (! struct_allocate(&tmp.data.struct_))
+ if (type != &g_sym_Tag) {
+ if (! sym_to_tag_type(type, &tmp.type))
return NULL;
+ if (! struct_type_find(type, &st))
+ return NULL;
+ if (st) {
+ tmp.data.struct_.type = st;
+ if (! struct_allocate(&tmp.data.struct_))
+ return NULL;
+ }
}
if (! tag_to_pointer(&tmp, type, &tmp_data))
return NULL;
@@ -199,6 +201,14 @@ u8 struct_get_u8 (const s_struct *s, const s_sym *key)
return *(u8 *) struct_get(s, key);
}
+const s_sym ** struct_get_var_type (const s_struct *s, const s_sym *key,
+ const s_sym **dest)
+{
+ s_tag tag_key;
+ tag_init_sym(&tag_key, key);
+ return map_get_var_type(&s->type->map, &tag_key, dest);
+}
+
s_struct * struct_init (s_struct *s, const s_sym *module)
{
s_struct tmp = {0};
diff --git a/libkc3/struct.h b/libkc3/struct.h
index f61ffb3..b13bd47 100644
--- a/libkc3/struct.h
+++ b/libkc3/struct.h
@@ -59,6 +59,8 @@ const s_sym ** struct_get_type (const s_struct *s, const s_sym *key,
const s_sym ** struct_get_sym (const s_struct *s, const s_sym *key);
const s_tag * struct_get_tag (const s_struct *s, const s_sym *key);
u8 struct_get_u8 (const s_struct *s, const s_sym *key);
+const s_sym ** struct_get_var_type (const s_struct *s, const s_sym *key,
+ const s_sym **dest);
uw * struct_offset (const s_struct *s,
const s_sym * const *key,
uw *dest);
diff --git a/libkc3/tag.c b/libkc3/tag.c
index b07a303..21e1534 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -1362,6 +1362,10 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
bool tag_to_pointer (s_tag *tag, const s_sym *type, void **dest)
{
e_tag_type tag_type;
+ if (type == &g_sym_Tag) {
+ *dest = tag;
+ return true;
+ }
if (! sym_to_tag_type(type, &tag_type))
return false;
if (tag->type != tag_type) {
@@ -1495,6 +1499,17 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
return NULL;
}
+const s_sym ** tag_var_type (const s_tag *tag, const s_sym **dest)
+{
+ assert(tag);
+ assert(dest);
+ if (tag->type == TAG_VAR) {
+ *dest = tag->data.var.type;
+ return dest;
+ }
+ return tag_type(tag, dest);
+}
+
bool tag_xor (const s_tag *a, const s_tag *b)
{
s_tag f;
diff --git a/libkc3/tag.h b/libkc3/tag.h
index f61507a..c18fcd7 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -59,6 +59,7 @@ const s_tag * tag_resolve_cow (const s_tag *tag);
uw * tag_size (const s_tag *tag, uw *dest);
ffi_type tag_to_ffi_type(const s_tag *tag);
const s_sym ** tag_type (const s_tag *tag, const s_sym **type);
+const s_sym ** tag_var_type (const s_tag *tag, const s_sym **type);
/* Operators. */
s_tag * tag_1 (s_tag *tag, const char *p);
diff --git a/test/ikc3/facts_with_tags.kc3 b/test/ikc3/facts_with_tags.kc3
new file mode 100644
index 0000000..9ebc9cd
--- /dev/null
+++ b/test/ikc3/facts_with_tags.kc3
@@ -0,0 +1,8 @@
+quote Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) {
+ puts(fact.object)
+ void
+})
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) {
+ puts(fact.object)
+ void
+})
diff --git a/test/ikc3/facts_with_tags.out.expected b/test/ikc3/facts_with_tags.out.expected
new file mode 100644
index 0000000..269d066
--- /dev/null
+++ b/test/ikc3/facts_with_tags.out.expected
@@ -0,0 +1,30 @@
+Facts.with_tags(Facts.env_facts(), KC3, :operator, ?, fn (fact) { puts(fact.object); void })
+operator_eq
+operator_gt
+operator_lt
+operator_or
+operator_add
+operator_and
+operator_bor
+operator_div
+operator_gte
+operator_lte
+operator_mod
+operator_mul
+operator_neg
+operator_not
+operator_pin
+operator_sub
+operator_addi
+operator_band
+operator_bnot
+operator_bxor
+operator_equal
+operator_paren
+operator_not_eq
+operator_require
+operator_brackets
+operator_defstruct
+operator_shift_left
+operator_shift_right
+void
diff --git a/test/ikc3/facts_with_tags.ret.expected b/test/ikc3/facts_with_tags.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ikc3/facts_with_tags.ret.expected
@@ -0,0 +1 @@
+0