diff --git a/libkc3/alist.c b/libkc3/alist.c
index 3a66a04..b7a105a 100644
--- a/libkc3/alist.c
+++ b/libkc3/alist.c
@@ -26,12 +26,12 @@
#include "tag.h"
#include "tuple.h"
-s_tag * alist_access (const s_list * const *alist,
- const s_list * const *key,
+s_tag * alist_access (s_list *alist,
+ s_list *key,
s_tag *dest)
{
- const s_tag *first;
- const s_list *next;
+ s_tag *first;
+ s_list *next;
s_tag *r;
s_tag tag;
assert(alist);
@@ -42,8 +42,8 @@ s_tag * alist_access (const s_list * const *alist,
assert(! "alist_access: not an associative list");
return NULL;
}
- first = &(*key)->tag;
- next = list_next(*key);
+ first = &key->tag;
+ next = list_next(key);
if (! next)
return alist_get(alist, first, dest);
if (! alist_get(alist, first, &tag)) {
@@ -60,15 +60,14 @@ s_tag * alist_access (const s_list * const *alist,
return r;
}
-s_tag * alist_get (const s_list * const *alist, const s_tag *key,
- s_tag *dest)
+s_tag * alist_get (s_list *alist, s_tag *key, s_tag *dest)
{
- const s_list *l;
+ s_list *l;
assert(alist);
assert(list_is_alist(alist));
assert(key);
assert(dest);
- l = *alist;
+ l = alist;
while (l) {
if (! compare_tag(&l->tag.data.tuple.tag[0], key))
return tag_init_copy(dest, l->tag.data.tuple.tag + 1);
diff --git a/libkc3/alist.h b/libkc3/alist.h
index d96f3c8..1c3c3c7 100644
--- a/libkc3/alist.h
+++ b/libkc3/alist.h
@@ -22,10 +22,7 @@
#include "types.h"
/* Observers */
-s_tag * alist_access (const s_list * const *alist,
- const s_list * const *key,
- s_tag *dest);
-s_tag * alist_get (const s_list * const *alist, const s_tag *key,
- s_tag *dest);
+s_tag * alist_access (s_list *alist, s_list *key, s_tag *dest);
+s_tag * alist_get (s_list *alist, s_tag *key, s_tag *dest);
#endif /* LIBKC3_ALIST_H */
diff --git a/libkc3/array.c b/libkc3/array.c
index 24d210e..941e6e9 100644
--- a/libkc3/array.c
+++ b/libkc3/array.c
@@ -23,12 +23,11 @@
#include "sym.h"
#include "tag.h"
-s_tag * array_access (const s_array *a, const s_list * const *key,
- s_tag *dest)
+s_tag * array_access (s_array *a, s_list *key, s_tag *dest)
{
s_array address;
s_tag *r;
- if (! list_to_array(*key, &g_sym_Uw_brackets, &address)) {
+ if (! list_to_array(key, &g_sym_Uw_brackets, &address)) {
err_puts("array_access: list_to_array");
assert(! "array_access: list_to_array");
return NULL;
@@ -108,7 +107,7 @@ void * array_data (const s_array *a, const uw *address)
}
s_array * array_data_set (s_array *a, const uw *address,
- const void *data)
+ void *data)
{
void *a_data;
assert(a);
diff --git a/libkc3/array.h b/libkc3/array.h
index 84bd87f..247712c 100644
--- a/libkc3/array.h
+++ b/libkc3/array.h
@@ -33,11 +33,10 @@ s_tag * array_data_tag (const s_array *a,
s_tag *dest);
/* Operators */
-s_tag * array_access (const s_array *a, const s_list * const *key,
- s_tag *dest);
+s_tag * array_access (s_array *a, s_list *key, s_tag *dest);
s_array * array_allocate (s_array *a);
s_array * array_data_set (s_array *a, const uw *address,
- const void *data);
+ void *data);
s_array * array_free (s_array *a);
#endif /* LIBKC3_ARRAY_H */
diff --git a/libkc3/binding.c b/libkc3/binding.c
index 4058492..d69e763 100644
--- a/libkc3/binding.c
+++ b/libkc3/binding.c
@@ -47,9 +47,9 @@ s_binding ** binding_find (s_binding **binding, const s_sym *name)
return NULL;
}
-const s_tag * binding_get (const s_binding *binding, const s_sym *name)
+s_tag * binding_get (s_binding *binding, const s_sym *name)
{
- const s_binding *b;
+ s_binding *b;
b = binding;
while (b) {
if (b->name == name)
@@ -96,11 +96,11 @@ s_binding * binding_new (const s_sym *name, s_binding *next)
return binding;
}
-s_binding * binding_new_copy (const s_binding *src)
+s_binding * binding_new_copy (s_binding *src)
{
s_binding **b;
s_binding *binding;
- const s_binding *s;
+ s_binding *s;
binding = NULL;
b = &binding;
s = src;
diff --git a/libkc3/binding.h b/libkc3/binding.h
index 640c791..1d8ab23 100644
--- a/libkc3/binding.h
+++ b/libkc3/binding.h
@@ -25,15 +25,12 @@ s_binding * binding_init (s_binding *binding, const s_sym *name,
s_binding * binding_delete (s_binding *binding);
void binding_delete_all (s_binding *binding);
s_binding * binding_new (const s_sym *name, s_binding *next);
-s_binding * binding_new_copy (const s_binding *src);
-
-/* Observers. */
-const s_tag * binding_get (const s_binding *binding, const s_sym *name);
-const s_tag * binding_is_bound (const s_binding *binding,
- const s_sym *name);
+s_binding * binding_new_copy (s_binding *src);
/* Operators. */
-s_tag * binding_get_w (s_binding *binding, const s_sym *name);
+s_tag * binding_get_w (s_binding *binding, const s_sym *name);
s_binding ** binding_find (s_binding **binding, const s_sym *name);
+s_tag * binding_get (s_binding *binding, const s_sym *name);
+s_tag * binding_is_bound (s_binding *binding, const s_sym *name);
#endif /* LIBC3_BINDING_H */
diff --git a/libkc3/block.c b/libkc3/block.c
index e235ef5..544dd85 100644
--- a/libkc3/block.c
+++ b/libkc3/block.c
@@ -76,7 +76,7 @@ s_block * block_init_1 (s_block *block, const char *p)
return block;
}
-s_block * block_init_cast (s_block *block, const s_tag *tag)
+s_block * block_init_cast (s_block *block, s_tag *tag)
{
switch (tag->type) {
case TAG_BLOCK:
@@ -91,7 +91,7 @@ s_block * block_init_cast (s_block *block, const s_tag *tag)
return NULL;
}
-s_block * block_init_copy (s_block *block, const s_block *src)
+s_block * block_init_copy (s_block *block, s_block *src)
{
uw i = 0;
assert(src);
@@ -106,10 +106,10 @@ s_block * block_init_copy (s_block *block, const s_block *src)
}
s_block * block_init_from_list (s_block *block,
- const s_list * const *list)
+ s_list **list)
{
uw i;
- const s_list *l;
+ s_list *l;
uw len;
s_block tmp;
assert(block);
diff --git a/libkc3/block.h b/libkc3/block.h
index 9805e72..4375a30 100644
--- a/libkc3/block.h
+++ b/libkc3/block.h
@@ -25,10 +25,10 @@
/* Stack allocation compatible functions */
s_block * block_init (s_block *block, uw count);
s_block * block_init_1 (s_block *block, const char *p);
-s_block * block_init_cast (s_block *block, const s_tag *tag);
-s_block * block_init_copy (s_block *block, const s_block *src);
+s_block * block_init_cast (s_block *block, s_tag *tag);
+s_block * block_init_copy (s_block *block, s_block *src);
s_block * block_init_from_list (s_block *block,
- const s_list * const *list);
+ s_list **list);
void block_clean (s_block *block);
/* Constructors, call block_delete after use */
diff --git a/libkc3/bool.c b/libkc3/bool.c
index fb65a09..3831df4 100644
--- a/libkc3/bool.c
+++ b/libkc3/bool.c
@@ -59,9 +59,8 @@ bool * bool_init_cast (bool *b, const s_sym * const *type,
case TAG_ARRAY:
case TAG_BLOCK:
case TAG_CALL:
- case TAG_CFN:
+ case TAG_CALLABLE:
case TAG_FACT:
- case TAG_FN:
case TAG_IDENT:
case TAG_LIST:
case TAG_MAP:
diff --git a/libkc3/buf_inspect.c b/libkc3/buf_inspect.c
index 13e624f..316a976 100644
--- a/libkc3/buf_inspect.c
+++ b/libkc3/buf_inspect.c
@@ -1438,7 +1438,7 @@ sw buf_inspect_complex_size (s_pretty *pretty, const s_complex *c)
return result;
}
-sw buf_inspect_cow (s_buf *buf, const s_cow *cow)
+sw buf_inspect_cow (s_buf *buf, s_cow *cow)
{
sw r;
sw result = 0;
@@ -1458,7 +1458,7 @@ sw buf_inspect_cow (s_buf *buf, const s_cow *cow)
return r;
}
-sw buf_inspect_cow_size (s_pretty *pretty, const s_cow *cow)
+sw buf_inspect_cow_size (s_pretty *pretty, s_cow *cow)
{
sw r;
sw result = 0;
@@ -2328,7 +2328,7 @@ sw buf_inspect_list (s_buf *buf, const s_list * const *x)
if ((r = buf_write_1(buf, "[")) <= 0)
return r;
result += r;
- alist = list_is_alist(x);
+ alist = list_is_alist(*x);
if (alist) {
pretty_save_init(&pretty_save, &buf->pretty);
pretty_indent_from_column(&buf->pretty, 0);
@@ -3626,7 +3626,9 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
case TAG_BLOCK: return buf_inspect_block(buf, &tag->data.block);
case TAG_BOOL: return buf_inspect_bool(buf, &tag->data.bool);
case TAG_CALL: return buf_inspect_call(buf, &tag->data.call);
- case TAG_CFN: return buf_inspect_cfn(buf, &tag->data.cfn);
+ case TAG_CALLABLE:
+ return buf_inspect_callable(buf, tag->data.callable);
+ //case TAG_CFN: return buf_inspect_cfn(buf, &tag->data.cfn);
case TAG_CHARACTER:
return buf_inspect_character(buf, &tag->data.character);
case TAG_COMPLEX: return buf_inspect_complex(buf, tag->data.complex);
@@ -3635,7 +3637,7 @@ sw buf_inspect_tag (s_buf *buf, const s_tag *tag)
case TAG_F64: return buf_inspect_f64(buf, &tag->data.f64);
case TAG_F128: return buf_inspect_f128(buf, &tag->data.f128);
case TAG_FACT: return buf_inspect_fact(buf, &tag->data.fact);
- case TAG_FN: return buf_inspect_fn(buf, &tag->data.fn);
+ //case TAG_FN: return buf_inspect_fn(buf, &tag->data.fn);
case TAG_IDENT: return buf_inspect_ident(buf, &tag->data.ident);
case TAG_INTEGER: return buf_inspect_integer(buf, &tag->data.integer);
case TAG_LIST:
@@ -3685,8 +3687,10 @@ sw buf_inspect_tag_size (s_pretty *pretty, const s_tag *tag)
return buf_inspect_bool_size(pretty, &tag->data.bool);
case TAG_CALL:
return buf_inspect_call_size(pretty, &tag->data.call);
- case TAG_CFN:
- return buf_inspect_cfn_size(pretty, &tag->data.cfn);
+ case TAG_CALLABLE:
+ return buf_inspect_callable_size(pretty, tag->data.callable);
+ //case TAG_CFN:
+ //return buf_inspect_cfn_size(pretty, &tag->data.cfn);
case TAG_CHARACTER:
return buf_inspect_character_size(pretty, &tag->data.character);
case TAG_COMPLEX:
@@ -3701,8 +3705,8 @@ sw buf_inspect_tag_size (s_pretty *pretty, const s_tag *tag)
return buf_inspect_f128_size(pretty, &tag->data.f128);
case TAG_FACT:
return buf_inspect_fact_size(pretty, &tag->data.fact);
- case TAG_FN:
- return buf_inspect_fn_size(pretty, &tag->data.fn);
+ //case TAG_FN:
+ //return buf_inspect_fn_size(pretty, &tag->data.fn);
case TAG_IDENT:
return buf_inspect_ident_size(pretty, &tag->data.ident);
case TAG_INTEGER:
diff --git a/libkc3/buf_inspect.h b/libkc3/buf_inspect.h
index 2842d89..f3f6a87 100644
--- a/libkc3/buf_inspect.h
+++ b/libkc3/buf_inspect.h
@@ -101,6 +101,9 @@ sw buf_inspect_call_special_operator_size (s_pretty *pretty,
const s_call *call);
sw buf_inspect_call_str (s_buf *buf, const s_call *call);
sw buf_inspect_call_str_size (s_pretty *pretty, const s_call *call);
+sw buf_inspect_callable (s_buf *buf, const s_callable *callable);
+sw buf_inspect_callable_size (s_pretty *pretty,
+ const s_callable *callable);
sw buf_inspect_cast (s_buf *buf, const s_call *call);
sw buf_inspect_cast_size (s_pretty *pretty, const s_call *call);
sw buf_inspect_cfn (s_buf *buf, const s_cfn *cfn);
@@ -109,8 +112,8 @@ sw buf_inspect_character (s_buf *buf, const character *c);
sw buf_inspect_character_size (s_pretty *pretty, const character *c);
sw buf_inspect_complex (s_buf *buf, const s_complex *c);
sw buf_inspect_complex_size (s_pretty *pretty, const s_complex *c);
-sw buf_inspect_cow (s_buf *buf, const s_cow *cow);
-sw buf_inspect_cow_size (s_pretty *pretty, const s_cow *cow);
+sw buf_inspect_cow (s_buf *buf, s_cow *cow);
+sw buf_inspect_cow_size (s_pretty *pretty, s_cow *cow);
sw buf_inspect_error_handler (s_buf *buf,
const s_error_handler *error_handler);
sw buf_inspect_f32 (s_buf *buf, const f32 *x);
diff --git a/libkc3/buf_parse.c b/libkc3/buf_parse.c
index d8a83a1..65c963d 100644
--- a/libkc3/buf_parse.c
+++ b/libkc3/buf_parse.c
@@ -1114,6 +1114,25 @@ sw buf_parse_call_paren (s_buf *buf, s_call *dest)
return r;
}
+sw buf_parse_callable (s_buf *buf, s_callable *dest)
+{
+ sw r;
+ s_callable tmp = {0};
+ assert(buf);
+ assert(dest);
+ if ((r = buf_parse_cfn(buf, &tmp.data.cfn)) > 0) {
+ tmp.type = CALLABLE_CFN;
+ tmp.reference_count = 1;
+ *dest = tmp;
+ }
+ else if ((r = buf_parse_fn(buf, &tmp.data.fn)) > 0) {
+ tmp.type = CALLABLE_FN;
+ tmp.reference_count = 1;
+ *dest = tmp;
+ }
+ return r;
+}
+
sw buf_parse_cast (s_buf *buf, s_call *dest)
{
const s_sym *module = NULL;
@@ -3833,23 +3852,23 @@ sw buf_parse_tag_call_op_unary (s_buf *buf, s_tag *dest)
return r;
}
-sw buf_parse_tag_cast (s_buf *buf, s_tag *dest)
+sw buf_parse_tag_callable (s_buf *buf, s_tag *dest)
{
sw r;
assert(buf);
assert(dest);
- if ((r = buf_parse_cast(buf, &dest->data.call)) > 0)
- dest->type = TAG_CALL;
+ if ((r = buf_parse_callable(buf, dest->data.callable)) > 0)
+ dest->type = TAG_CALLABLE;
return r;
}
-sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest)
+sw buf_parse_tag_cast (s_buf *buf, s_tag *dest)
{
sw r;
assert(buf);
assert(dest);
- if ((r = buf_parse_cfn(buf, &dest->data.cfn)) > 0)
- dest->type = TAG_CFN;
+ if ((r = buf_parse_cast(buf, &dest->data.call)) > 0)
+ dest->type = TAG_CALL;
return r;
}
@@ -3903,27 +3922,17 @@ sw buf_parse_tag_f64 (s_buf *buf, s_tag *dest)
return r;
}
-sw buf_parse_tag_fn (s_buf *buf, s_tag *dest)
-{
- sw r;
- assert(buf);
- assert(dest);
- if ((r = buf_parse_fn(buf, &dest->data.fn)) > 0)
- dest->type = TAG_FN;
- return r;
-}
-
sw buf_parse_tag_ident (s_buf *buf, s_tag *dest)
{
sw r;
- const s_tag *tag;
+ s_tag *tag;
assert(buf);
assert(dest);
r = buf_parse_ident(buf, &dest->data.ident);
if (r > 0) {
if (! dest->data.ident.module &&
- (tag = frame_get(&g_kc3_env.read_time_frame,
- dest->data.ident.sym)))
+ (tag = frame_get_w(&g_kc3_env.read_time_frame,
+ dest->data.ident.sym)))
tag_init_copy(dest, tag);
else
dest->type = TAG_IDENT;
diff --git a/libkc3/buf_parse.h b/libkc3/buf_parse.h
index 43994db..a64767e 100644
--- a/libkc3/buf_parse.h
+++ b/libkc3/buf_parse.h
@@ -55,6 +55,7 @@ sw buf_parse_call_op (s_buf *buf, s_call *dest);
sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, sw min_precedence);
sw buf_parse_call_op_unary (s_buf *buf, s_call *dest);
sw buf_parse_call_paren (s_buf *buf, s_call *dest);
+sw buf_parse_callable (s_buf *buf, s_callable *dest);
sw buf_parse_cast (s_buf *buf, s_call *dest);
sw buf_parse_cfn (s_buf *buf, s_cfn *dest);
sw buf_parse_character (s_buf *buf, character *dest);
diff --git a/libkc3/call.c b/libkc3/call.c
index afef36c..f8f994f 100644
--- a/libkc3/call.c
+++ b/libkc3/call.c
@@ -16,7 +16,7 @@
#include "buf_inspect.h"
#include "buf_parse.h"
#include "call.h"
-#include "cfn.h"
+#include "callable.h"
#include "facts.h"
#include "facts_cursor.h"
#include "facts_with.h"
@@ -30,10 +30,8 @@ void call_clean (s_call *call)
{
assert(call);
list_delete_all(call->arguments);
- if (call->cfn)
- cfn_delete(call->cfn);
- if (call->fn)
- fn_delete(call->fn);
+ if (call->callable)
+ callable_delete(call->callable);
}
bool call_get (s_call *call)
@@ -90,7 +88,7 @@ s_call * call_init_call_cast (s_call *call, const s_sym *type)
}
s_call * call_init_cast (s_call *call, const s_sym * const *type,
- const s_tag *tag)
+ s_tag *tag)
{
assert(call);
assert(type);
@@ -114,20 +112,16 @@ s_call * call_init_cast (s_call *call, const s_sym * const *type,
return NULL;
}
-s_call * call_init_copy (s_call *call, const s_call *src)
+s_call * call_init_copy (s_call *call, s_call *src)
{
s_call tmp = {0};
assert(src);
assert(call);
if (! ident_init_copy(&tmp.ident, &src->ident) ||
- ! list_init_copy(&tmp.arguments,
- (const s_list * const *) &src->arguments))
+ ! list_init_copy(&tmp.arguments, &src->arguments))
return NULL;
- // FIXME: copy cfn and fn ?
- if (src->cfn)
- tmp.cfn = cfn_new_copy(src->cfn);
- if (src->fn)
- tmp.fn = fn_new_copy(src->fn);
+ if (src->callable)
+ tmp.callable = callable_new_ref(src->callable);
*call = tmp;
return call;
}
diff --git a/libkc3/call.h b/libkc3/call.h
index 2ecfe15..0796b2b 100644
--- a/libkc3/call.h
+++ b/libkc3/call.h
@@ -21,8 +21,8 @@ s_call * call_init (s_call *call);
s_call * call_init_1 (s_call *call, const char *p);
s_call * call_init_call_cast (s_call *call, const s_sym *type);
s_call * call_init_cast (s_call *call, const s_sym * const *type,
- const s_tag *tag);
-s_call * call_init_copy (s_call *call, const s_call *src);
+ s_tag *tag);
+s_call * call_init_copy (s_call *call, s_call *src);
s_call * call_init_op (s_call *call);
s_call * call_init_op_unary (s_call *call);
diff --git a/libkc3/callable.h b/libkc3/callable.h
new file mode 100644
index 0000000..692cdda
--- /dev/null
+++ b/libkc3/callable.h
@@ -0,0 +1,33 @@
+/* kc3
+ * Copyright 2022,2023,2024 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef LIBKC3_CALLABLE_H
+#define LIBKC3_CALLABLE_H
+
+#include "types.h"
+
+/* Heap pointer manipulation functions. Call p_callable_clean
+ after use. */
+void p_callable_clean (p_callable *callable);
+p_callable * p_callable_init (p_callable *callable);
+p_callable * p_callable_init_cast (p_callable *callable,
+ const s_sym * const *type,
+ const s_tag *tag);
+s_callable * p_callable_init_copy (p_callable *callable,
+ p_callable *src);
+
+/* Heap-allocation functions, call callable_delete after use. */
+s_callable * callable_delete (s_callable *callable);
+s_callable * callable_new (s_callable *callable);
+s_callable * callable_new_ref (s_callable *callable);
+
+#endif /* LIBKC3_CALLABLE_H */
diff --git a/libkc3/cfn.c b/libkc3/cfn.c
index 01b5dfe..4a68a91 100644
--- a/libkc3/cfn.c
+++ b/libkc3/cfn.c
@@ -115,7 +115,7 @@ s_tag * cfn_apply (s_cfn *cfn, s_list *args, s_tag *dest)
err_write_1("cfn_apply: ");
err_inspect_str(&cfn->name->str);
err_write_1(" ");
- err_inspect_list((const s_list * const *) &args);
+ err_inspect_list(args);
err_puts(": tag_to_ffi_pointer 5");
assert(! "cfn_apply: tag_to_ffi_pointer 5");
goto ko;
@@ -139,7 +139,7 @@ s_tag * cfn_apply (s_cfn *cfn, s_list *args, s_tag *dest)
err_write_1("cfn_apply: ");
err_inspect_str(&cfn->name->str);
err_write_1(" ");
- err_inspect_list((const s_list * const *) &args);
+ err_inspect_list(args);
err_write_1(": ");
err_inspect_pointer(result_pointer);
err_write_1(" != ");
@@ -216,6 +216,7 @@ s_cfn * cfn_init (s_cfn *cfn, const s_sym *name, s_list *arg_types,
return cfn;
}
+/*
s_cfn * cfn_init_cast (s_cfn *cfn, const s_sym * const *type,
const s_tag *tag)
{
@@ -238,6 +239,7 @@ s_cfn * cfn_init_cast (s_cfn *cfn, const s_sym * const *type,
assert(! "cfn_init_cast: cannot cast to Cfn");
return NULL;
}
+*/
s_cfn * cfn_init_copy (s_cfn *cfn, const s_cfn *src)
{
diff --git a/libkc3/compare.c b/libkc3/compare.c
index 772c28f..b32a2d1 100644
--- a/libkc3/compare.c
+++ b/libkc3/compare.c
@@ -97,15 +97,37 @@ s8 compare_call (const s_call *a, const s_call *b)
s8 r;
if (a == b)
return 0;
- if (!a)
+ if (! a)
return -1;
- if (!b)
+ if (! b)
return 1;
if ((r = compare_ident(&a->ident, &b->ident)))
return r;
return compare_list(a->arguments, b->arguments);
}
+s8 compare_callable (const s_callable *a, const s_callable *b)
+{
+ if (a == b)
+ return 0;
+ if (! a)
+ return -1;
+ if (! b)
+ return 1;
+ if (a->type < b->type)
+ return -1;
+ if (a->type > b->type)
+ return 1;
+ switch (a->type) {
+ case CALLABLE_VOID: return 0;
+ case CALLABLE_CFN: return compare_cfn(&a->data.cfn, &b->data.cfn);
+ case CALLABLE_FN: return compare_fn(&a->data.fn, &b->data.fn);
+ }
+ err_puts("compare_callable: error");
+ assert(! "compare_callable: error");
+ return COMPARE_ERROR;
+}
+
s8 compare_cfn (const s_cfn *a, const s_cfn *b)
{
s8 r;
@@ -1119,13 +1141,13 @@ s8 compare_tag (const s_tag *a, const s_tag *b) {
case TAG_BOOL: return compare_bool(a->data.bool, b->data.bool);
case TAG_CALL: return compare_call(&a->data.call,
&b->data.call);
- case TAG_CFN: return compare_cfn(&a->data.cfn, &b->data.cfn);
+ case TAG_CALLABLE: return compare_callable(a->data.callable,
+ b->data.callable);
case TAG_CHARACTER: return compare_character(a->data.character,
b->data.character);
case TAG_COW: return compare_cow(a->data.cow, b->data.cow);
case TAG_FACT: return compare_fact(&a->data.fact,
&b->data.fact);
- case TAG_FN: return compare_fn(&a->data.fn, &b->data.fn);
case TAG_IDENT: return compare_ident(&a->data.ident,
&b->data.ident);
case TAG_LIST: return compare_list(a->data.list, b->data.list);
diff --git a/libkc3/compare.h b/libkc3/compare.h
index 5c9f2b9..79c79d4 100644
--- a/libkc3/compare.h
+++ b/libkc3/compare.h
@@ -27,6 +27,7 @@ s8 compare_array (const s_array *a, const s_array *b);
s8 compare_block (const s_block *a, const s_block *b);
s8 compare_bool (bool a, bool b);
s8 compare_call (const s_call *a, const s_call *b);
+s8 compare_callable (const s_callable *a, const s_callable *b);
s8 compare_cfn (const s_cfn *a, const s_cfn *b);
COMPARE_PROTOTYPE(character);
s8 compare_complex (const s_complex *a, const s_complex *b);
diff --git a/libkc3/complex.c b/libkc3/complex.c
index ce1ec7e..04e80f1 100644
--- a/libkc3/complex.c
+++ b/libkc3/complex.c
@@ -169,7 +169,7 @@ s_complex * complex_init_cast (s_complex *c, const s_sym * const *type,
return NULL;
}
-s_complex * complex_init_copy (s_complex *c, const s_complex *src)
+s_complex * complex_init_copy (s_complex *c, s_complex *src)
{
assert(c);
assert(src);
@@ -297,7 +297,7 @@ s_complex * complex_new_sub (const s_complex *a, const s_complex *b)
return c;
}
-s_complex * complex_new_copy (const s_complex *src)
+s_complex * complex_new_copy (s_complex *src)
{
s_complex *c;
assert(src);
diff --git a/libkc3/complex.h b/libkc3/complex.h
index b91765e..081f4d9 100644
--- a/libkc3/complex.h
+++ b/libkc3/complex.h
@@ -22,7 +22,7 @@ s_complex * complex_init (s_complex *c);
s_complex * complex_init_1 (s_complex *c, const s8 *p);
s_complex * complex_init_cast (s_complex *c, const s_sym * const *type,
const s_tag *src);
-s_complex * complex_init_copy (s_complex *c, const s_complex *src);
+s_complex * complex_init_copy (s_complex *c, s_complex *src);
s_complex * complex_init_f32 (s_complex *c, f32 src);
s_complex * complex_init_f64 (s_complex *c, f64 src);
s_complex * complex_init_f128 (s_complex *c, f128 src);
@@ -61,7 +61,7 @@ s_complex * complex_new_cast (const s_sym * const *type,
s_complex * complex_new_div (const s_complex *a, const s_complex *b);
s_complex * complex_new_mul (const s_complex *a, const s_complex *b);
s_complex * complex_new_sub (const s_complex *a, const s_complex *b);
-s_complex * complex_new_copy (const s_complex *a);
+s_complex * complex_new_copy (s_complex *a);
/* Observers */
bool complex_is_zero (const s_complex *c);
diff --git a/libkc3/cow.c b/libkc3/cow.c
index e73aae3..8b1c34e 100644
--- a/libkc3/cow.c
+++ b/libkc3/cow.c
@@ -47,7 +47,7 @@ s_cow * cow_freeze (s_cow *cow)
return cow;
}
-s_cow * cow_freeze_copy (s_cow *cow, const s_tag *src)
+s_cow * cow_freeze_copy (s_cow *cow, s_tag *src)
{
s_list *tmp = NULL;
assert(cow);
@@ -95,7 +95,7 @@ s_cow * cow_init_1 (s_cow *cow, const char *utf8)
}
s_cow * cow_init_cast (s_cow *cow, const s_sym * const *type,
- const s_tag *tag)
+ s_tag *tag)
{
void *data;
s_cow tmp;
@@ -120,7 +120,7 @@ s_cow * cow_init_cast (s_cow *cow, const s_sym * const *type,
return cow;
}
-s_cow * cow_init_copy (s_cow *cow, const s_cow *src)
+s_cow * cow_init_copy (s_cow *cow, s_cow *src)
{
s_cow tmp = {0};
assert(cow);
@@ -135,7 +135,7 @@ s_cow * cow_init_copy (s_cow *cow, const s_cow *src)
}
s_cow * cow_init_tag_copy (s_cow *cow, const s_sym *type,
- const s_tag *src)
+ s_tag *src)
{
assert(cow);
assert(src);
@@ -187,7 +187,7 @@ s_cow * cow_new_1 (const char *utf8)
return cow;
}
-s_cow * cow_new_cast (const s_sym * const *type, const s_tag *tag)
+s_cow * cow_new_cast (const s_sym * const *type, s_tag *tag)
{
s_cow *cow;
cow = alloc(sizeof(s_cow));
@@ -200,7 +200,7 @@ s_cow * cow_new_cast (const s_sym * const *type, const s_tag *tag)
return cow;
}
-s_cow * cow_new_copy (const s_cow *src)
+s_cow * cow_new_copy (s_cow *src)
{
s_cow *cow;
cow = alloc(sizeof(s_cow));
@@ -213,7 +213,7 @@ s_cow * cow_new_copy (const s_cow *src)
return cow;
}
-s_cow * cow_new_tag_copy (const s_sym *type, const s_tag *src)
+s_cow * cow_new_tag_copy (const s_sym *type, s_tag *src)
{
s_cow *cow;
cow = alloc(sizeof(s_cow));
@@ -226,7 +226,7 @@ s_cow * cow_new_tag_copy (const s_sym *type, const s_tag *src)
return cow;
}
-const s_tag * cow_read_only (const s_cow *cow)
+s_tag * cow_read_only (s_cow *cow)
{
assert(cow);
assert(cow->list);
@@ -270,7 +270,7 @@ s_cow * cow_thaw (s_cow *cow)
return cow;
}
-s_cow * cow_thaw_copy (s_cow *cow, const s_tag *src)
+s_cow * cow_thaw_copy (s_cow *cow, s_tag *src)
{
s_tag tmp = {0};
assert(cow);
diff --git a/libkc3/cow.h b/libkc3/cow.h
index 8fe0bd6..b2f22df 100644
--- a/libkc3/cow.h
+++ b/libkc3/cow.h
@@ -33,31 +33,31 @@ void cow_clean (s_cow *cow);
s_cow * cow_init (s_cow *cow, const s_sym *type);
/* s_cow * cow_init_1 (s_cow *cow, const char *utf8); */
s_cow * cow_init_cast (s_cow *cow, const s_sym * const *type,
- const s_tag *tag);
-s_cow * cow_init_copy (s_cow *cow, const s_cow *src);
+ s_tag *tag);
+s_cow * cow_init_copy (s_cow *cow, s_cow *src);
s_cow * cow_init_tag_copy (s_cow *cow, const s_sym *type,
- const s_tag *src);
+ s_tag *src);
/* Heap-allocation functions. Call cow_delete after use. */
void cow_delete (s_cow *cow);
s_cow * cow_new (const s_sym *type);
/* s_cow * cow_new_1 (const char *utf8); */
-s_cow * cow_new_cast (const s_sym * const *type, const s_tag *tag);
-s_cow * cow_new_copy (const s_cow *src);
-s_cow * cow_new_tag_copy (const s_sym *type, const s_tag *src);
+s_cow * cow_new_cast (const s_sym * const *type, s_tag *tag);
+s_cow * cow_new_copy (s_cow *src);
+s_cow * cow_new_tag_copy (const s_sym *type, s_tag *src);
/* Observers. */
s_str * cow_inspect (const s_cow *cow, s_str *dest);
-const s_tag * cow_read_only (const s_cow *cow);
+s_tag * cow_read_only (s_cow *cow);
s_tag * cow_read_write (s_cow *cow);
const s_tag * cow_resolve (const s_cow *cow);
/* Operators. */
s_cow * cow_freeze (s_cow *cow);
-s_cow * cow_freeze_copy (s_cow *cow, const s_tag *src);
+s_cow * cow_freeze_copy (s_cow *cow, s_tag *src);
sw cow_ref (s_cow *cow);
s_cow * cow_thaw (s_cow *cow);
-s_cow * cow_thaw_copy (s_cow *cow, const s_tag *src);
+s_cow * cow_thaw_copy (s_cow *cow, s_tag *src);
sw cow_unref (s_cow *cow);
#endif /* LIBKC3_COW_H */
diff --git a/libkc3/data.c b/libkc3/data.c
index 6898dc9..e90cb60 100644
--- a/libkc3/data.c
+++ b/libkc3/data.c
@@ -15,7 +15,7 @@
sw data_buf_inspect (s_buf *buf, const s_sym *type, const void *data)
{
s_struct s = {0};
- const s_struct_type *st;
+ s_struct_type *st;
if (type == &g_sym_Array ||
sym_is_array_type(type))
return buf_inspect_array(buf, data);
@@ -23,8 +23,10 @@ sw data_buf_inspect (s_buf *buf, const s_sym *type, const void *data)
return buf_inspect_bool(buf, data);
if (type == &g_sym_Call)
return buf_inspect_call(buf, data);
- if (type == &g_sym_Cfn)
- return buf_inspect_cfn(buf, data);
+ if (type == &g_sym_Callable ||
+ type == &g_sym_Cfn ||
+ type == &g_sym_Fn)
+ return buf_inspect_callable(buf, *(p_callable *) data);
if (type == &g_sym_Character)
return buf_inspect_character(buf, data);
if (type == &g_sym_F32)
@@ -33,8 +35,6 @@ sw data_buf_inspect (s_buf *buf, const s_sym *type, const void *data)
return buf_inspect_f64(buf, data);
if (type == &g_sym_Fact)
return buf_inspect_fact(buf, data);
- if (type == &g_sym_Fn)
- return buf_inspect_fn(buf, data);
if (type == &g_sym_Ident)
return buf_inspect_ident(buf, data);
if (type == &g_sym_Integer)
@@ -107,7 +107,7 @@ sw data_buf_inspect_size (s_pretty *pretty, const s_sym *type,
const void *data)
{
s_struct s = {0};
- const s_struct_type *st;
+ s_struct_type *st;
if (type == &g_sym_Array ||
sym_is_array_type(type))
return buf_inspect_array_size(pretty, data);
@@ -115,8 +115,10 @@ sw data_buf_inspect_size (s_pretty *pretty, const s_sym *type,
return buf_inspect_bool_size(pretty, data);
if (type == &g_sym_Call)
return buf_inspect_call_size(pretty, data);
- if (type == &g_sym_Cfn)
- return buf_inspect_cfn_size(pretty, data);
+ if (type == &g_sym_Callable ||
+ type == &g_sym_Cfn ||
+ type == &g_sym_Fn)
+ return buf_inspect_callable_size(pretty, *(p_callable *) data);
if (type == &g_sym_Character)
return buf_inspect_character_size(pretty, data);
if (type == &g_sym_F32)
@@ -125,8 +127,6 @@ sw data_buf_inspect_size (s_pretty *pretty, const s_sym *type,
return buf_inspect_f64_size(pretty, data);
if (type == &g_sym_Fact)
return buf_inspect_fact_size(pretty, data);
- if (type == &g_sym_Fn)
- return buf_inspect_fn_size(pretty, data);
if (type == &g_sym_Ident)
return buf_inspect_ident_size(pretty, data);
if (type == &g_sym_Integer)
@@ -198,7 +198,7 @@ sw data_buf_inspect_size (s_pretty *pretty, const s_sym *type,
bool data_clean (const s_sym *type, void *data)
{
s_struct s = {0};
- const s_struct_type *st;
+ s_struct_type *st;
assert(type);
if (! data)
return true;
@@ -214,8 +214,10 @@ bool data_clean (const s_sym *type, void *data)
call_clean(data);
return true;
}
- if (type == &g_sym_Cfn) {
- cfn_clean(data);
+ if (type == &g_sym_Callable ||
+ type == &g_sym_Cfn ||
+ type == &g_sym_Fn) {
+ p_callable_clean(data);
return true;
}
if (type == &g_sym_Character) {
@@ -230,10 +232,6 @@ bool data_clean (const s_sym *type, void *data)
if (type == &g_sym_Fact) {
return true;
}
- if (type == &g_sym_Fn) {
- fn_clean(data);
- return true;
- }
if (type == &g_sym_Ident) {
return true;
}
@@ -346,7 +344,7 @@ bool data_compare (const s_sym *type, const void *a, const void *b)
{
s_struct sa = {0};
s_struct sb = {0};
- const s_struct_type *st;
+ s_struct_type *st;
if (type == &g_sym_Array ||
sym_is_array_type(type))
return compare_array(a, b);
@@ -354,8 +352,10 @@ bool data_compare (const s_sym *type, const void *a, const void *b)
return compare_bool(*(bool *) a, *(bool *) b);
if (type == &g_sym_Call)
return compare_call(a, b);
- if (type == &g_sym_Cfn)
- return compare_cfn(a, b);
+ if (type == &g_sym_Callable ||
+ type == &g_sym_Cfn ||
+ type == &g_sym_Fn)
+ return compare_callable(*(p_callable *) a, *(p_callable *) b);
if (type == &g_sym_Character)
return compare_character(*(character *) a, *(character *) b);
if (type == &g_sym_F32)
@@ -364,8 +364,6 @@ bool data_compare (const s_sym *type, const void *a, const void *b)
return compare_f64(*(f64 *) a, *(f64 *) b);
if (type == &g_sym_Fact)
return compare_fact(a, b);
- if (type == &g_sym_Fn)
- return compare_fn(a, b);
if (type == &g_sym_Ident)
return compare_ident(a, b);
if (type == &g_sym_Integer)
@@ -435,7 +433,7 @@ bool data_compare (const s_sym *type, const void *a, const void *b)
bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
{
s_struct s = {0};
- const s_struct_type *st;
+ s_struct_type *st;
if (type == &g_sym_Array ||
sym_is_array_type(type))
return hash_update_array(hash, data);
@@ -443,18 +441,20 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
return hash_update_bool(hash, data);
if (type == &g_sym_Call)
return hash_update_call(hash, data);
- if (type == &g_sym_Cfn)
- return hash_update_cfn(hash, data);
+ if (type == &g_sym_Callable ||
+ type == &g_sym_Cfn ||
+ type == &g_sym_Fn)
+ return hash_update_callable(hash, *(p_callable *) data);
if (type == &g_sym_Character)
- return hash_update_character(hash, data);
+ return hash_update_character(hash, *(character *) data);
if (type == &g_sym_F32)
- return hash_update_f32(hash, data);
+ return hash_update_f32(hash, *(f32 *) data);
if (type == &g_sym_F64)
- return hash_update_f64(hash, data);
+ return hash_update_f64(hash, *(f64 *) data);
+ if (type == &g_sym_F128)
+ return hash_update_f128(hash, *(f128 *) data);
if (type == &g_sym_Fact)
return hash_update_fact(hash, data);
- if (type == &g_sym_Fn)
- return hash_update_fn(hash, data);
if (type == &g_sym_Ident)
return hash_update_ident(hash, data);
if (type == &g_sym_Integer)
@@ -470,13 +470,13 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
if (type == &g_sym_Quote)
return hash_update_quote(hash, data);
if (type == &g_sym_S8)
- return hash_update_s8(hash, data);
+ return hash_update_s8(hash, *(s8 *) data);
if (type == &g_sym_S16)
- return hash_update_s16(hash, data);
+ return hash_update_s16(hash, *(s16 *) data);
if (type == &g_sym_S32)
- return hash_update_s32(hash, data);
+ return hash_update_s32(hash, *(s32 *) data);
if (type == &g_sym_S64)
- return hash_update_s64(hash, data);
+ return hash_update_s64(hash, *(s64 *) data);
if (type == &g_sym_Str)
return hash_update_str(hash, data);
if (type == &g_sym_Struct)
@@ -484,7 +484,7 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
if (type == &g_sym_StructType)
return hash_update_struct_type(hash, data);
if (type == &g_sym_Sw)
- return hash_update_sw(hash, data);
+ return hash_update_sw(hash, *(sw *) data);
if (type == &g_sym_Sym)
return hash_update_sym(hash, data);
if (type == &g_sym_Tag)
@@ -494,19 +494,19 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
if (type == &g_sym_Tuple)
return hash_update_tuple(hash, data);
if (type == &g_sym_U8)
- return hash_update_u8(hash, data);
+ return hash_update_u8(hash, *(u8 *) data);
if (type == &g_sym_U16)
- return hash_update_u16(hash, data);
+ return hash_update_u16(hash, *(u16 *) data);
if (type == &g_sym_U32)
- return hash_update_u32(hash, data);
+ return hash_update_u32(hash, *(u32 *) data);
if (type == &g_sym_U64)
- return hash_update_u64(hash, data);
+ return hash_update_u64(hash, *(u64 *) data);
if (type == &g_sym_Uw)
- return hash_update_uw(hash, data);
+ return hash_update_uw(hash, *(uw *) data);
if (type == &g_sym_Var)
return hash_update_var(hash, data);
if (type == &g_sym_Void)
- return hash_update_void(hash, data);
+ return hash_update_void(hash);
if (! struct_type_find(type, &st))
return false;
if (st) {
@@ -522,10 +522,10 @@ bool data_hash_update (const s_sym *type, t_hash *hash, const void *data)
}
void * data_init_cast (void *data, const s_sym * const *type,
- const s_tag *tag)
+ s_tag *tag)
{
s_struct s = {0};
- const s_struct_type *st;
+ s_struct_type *st;
const s_sym *t;
t = *type;
if (t == &g_sym_Array ||
@@ -535,8 +535,10 @@ void * data_init_cast (void *data, const s_sym * const *type,
return bool_init_cast(data, type, tag);
if (t == &g_sym_Call)
return call_init_cast(data, type, tag);
- if (t == &g_sym_Cfn)
- return cfn_init_cast(data, type, tag);
+ if (t == &g_sym_Callable ||
+ t == &g_sym_Cfn ||
+ t == &g_sym_Fn)
+ return p_callable_init_cast(data, type, tag);
if (t == &g_sym_Character)
return character_init_cast(data, type, tag);
if (t == &g_sym_F32)
@@ -545,8 +547,6 @@ void * data_init_cast (void *data, const s_sym * const *type,
return f64_init_cast(data, type, tag);
if (t == &g_sym_Fact)
return fact_init_cast(data, type, tag);
- if (t == &g_sym_Fn)
- return fn_init_cast(data, type, tag);
if (t == &g_sym_Ident)
return ident_init_cast(data, type, tag);
if (t == &g_sym_Integer)
@@ -613,9 +613,9 @@ void * data_init_cast (void *data, const s_sym * const *type,
return NULL;
}
-void * data_init_copy (const s_sym *type, void *data, const void *src)
+void * data_init_copy (const s_sym *type, void *data, void *src)
{
- const s_struct_type *st;
+ s_struct_type *st;
if (type == &g_sym_Array ||
sym_is_array_type(type))
return array_init_copy(data, src);
@@ -623,8 +623,10 @@ void * data_init_copy (const s_sym *type, void *data, const void *src)
return bool_init_copy(data, src);
if (type == &g_sym_Call)
return call_init_copy(data, src);
- if (type == &g_sym_Cfn)
- return cfn_init_copy(data, src);
+ if (type == &g_sym_Callable ||
+ type == &g_sym_Cfn ||
+ type == &g_sym_Fn)
+ return p_callable_init_copy(data, src);
if (type == &g_sym_Character)
return character_init_copy(data, src);
if (type == &g_sym_Cow)
@@ -635,8 +637,6 @@ void * data_init_copy (const s_sym *type, void *data, const void *src)
return f64_init_copy(data, src);
if (type == &g_sym_Fact)
return fact_init_copy(data, src);
- if (type == &g_sym_Fn)
- return fn_init_copy(data, src);
if (type == &g_sym_Ident)
return ident_init_copy(data, src);
if (type == &g_sym_Integer)
diff --git a/libkc3/data.h b/libkc3/data.h
index 46b8db1..b3413eb 100644
--- a/libkc3/data.h
+++ b/libkc3/data.h
@@ -29,7 +29,7 @@ bool data_compare (const s_sym *type, const void *a, const void *b);
bool data_hash_update (const s_sym *type, t_hash *hash,
const void *s);
void * data_init_cast (void *v, const s_sym * const *type,
- const s_tag *src);
-void * data_init_copy (const s_sym *type, void *v, const void *src);
+ s_tag *src);
+void * data_init_copy (const s_sym *type, void *v, void *src);
#endif /* LIBKC3_DATA_H */
diff --git a/libkc3/env.c b/libkc3/env.c
index 20b74fc..535945b 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -25,6 +25,7 @@
#include "buf_parse.h"
#include "buf_save.h"
#include "call.h"
+#include "callable.h"
#include "cfn.h"
#include "compare.h"
#include "complex.h"
@@ -70,7 +71,7 @@ static s_env * env_init_args (s_env *env, int *argc, char ***argv);
static s_env * env_init_globals (s_env *env);
static s_env * env_init_toplevel (s_env *env);
-bool * env_and (s_env *env, const s_tag *a, const s_tag *b, bool *dest)
+bool * env_and (s_env *env, s_tag *a, s_tag *b, bool *dest)
{
s_tag eval;
bool tmp;
@@ -124,8 +125,8 @@ s_list ** env_args (s_env *env, s_list **dest)
bool env_call_get (s_env *env, s_call *call)
{
s_facts_cursor cursor;
- const s_fact *fact;
- const s_fact *found;
+ s_fact *fact;
+ s_fact *found;
s_tag tag_ident;
s_tag tag_is_a;
s_tag tag_macro;
@@ -183,33 +184,20 @@ bool env_call_get (s_env *env, s_call *call)
err_puts(" :symbol_value not found");
return false;
}
- if (tag_var.type == TAG_FN) {
- call->fn = fn_new_copy(&tag_var.data.fn);
- fn_set_name_if_null(call->fn, call->ident.module,
- call->ident.sym);
- }
- else if (tag_var.type == TAG_CFN)
- call->cfn = cfn_new_copy(&tag_var.data.cfn);
- else {
+ if (tag_var.type != TAG_CALLABLE) {
err_write_1("env_call_get: ");
err_inspect_ident(&call->ident);
- err_puts(" is not a function");
+ err_puts(" is not a Callable");
facts_cursor_clean(&cursor);
return false;
}
- facts_cursor_clean(&cursor);
- if (! facts_find_fact_by_tags(&env->facts, &tag_ident, &tag_is_a,
- &tag_macro, &found)) {
- err_puts("env_call_get: facts_find_fact_by_tags 3");
- assert(! "env_call_get: facts_find_fact_by_tags 3");
- return false;
- }
- if (found) {
- if (call->fn)
- call->fn->macro = true;
- if (call->cfn)
- call->cfn->macro = true;
+ call->callable = callable_new_ref(tag_var.data.callable);
+ if (call->callable->type == CALLABLE_FN) {
+ fn_set_name_if_null(&call->callable->data.fn,
+ call->ident.module,
+ call->ident.sym);
}
+ facts_cursor_clean(&cursor);
if (! facts_find_fact_by_tags(&env->facts, &tag_ident, &tag_is_a,
&tag_special_operator, &found)) {
err_puts("env_call_get: facts_find_fact_by_tags 4");
@@ -217,10 +205,18 @@ bool env_call_get (s_env *env, s_call *call)
return false;
}
if (found) {
- if (call->fn)
- call->fn->special_operator = true;
- if (call->cfn)
- call->cfn->special_operator = true;
+ switch (call->callable->type) {
+ case CALLABLE_CFN:
+ call->callable->data.cfn.special_operator = true;
+ break;
+ case CALLABLE_FN:
+ call->callable->data.fn.special_operator = true;
+ break;
+ case CALLABLE_VOID:
+ err_puts("env_call_get: void callable");
+ assert(! "env_call_get: void callable");
+ break;
+ }
}
return true;
}
@@ -256,7 +252,7 @@ void env_clean_toplevel (s_env *env)
frame_delete_all(env->frame);
}
-bool env_def (s_env *env, const s_ident *ident, const s_tag *value)
+bool env_def (s_env *env, const s_ident *ident, s_tag *value)
{
const s_struct *s;
s_tag tag;
@@ -328,7 +324,8 @@ const s_sym * env_def_clean (s_env *env, const s_sym *module,
assert(! "env_def_clean: module struct type not found");
return NULL;
}
- if (clean->type != TAG_CFN) {
+ if (clean->type != TAG_CALLABLE ||
+ clean->data.callable->type != CALLABLE_CFN) {
err_write_1("env_def_clean: module ");
err_inspect_sym(&module);
err_write_1(": clean method must be a Cfn");
@@ -336,7 +333,8 @@ const s_sym * env_def_clean (s_env *env, const s_sym *module,
return NULL;
}
tag_init_sym(&tag_module_name, module);
- tag_init_struct_type_update_clean(&tag_st, st, &clean->data.cfn);
+ tag_init_struct_type_update_clean(&tag_st, st,
+ &clean->data.callable->data.cfn);
tag_init_sym(&tag_struct_type, &g_sym_struct_type);
if (! facts_replace_tags(&env->facts, &tag_module_name,
&tag_struct_type, &tag_st)) {
@@ -390,7 +388,7 @@ s_tag * env_defmodule (s_env *env, const s_sym * const *name,
s_tag * env_defoperator (s_env *env, const s_sym * const *name,
const s_sym * const *sym,
- const s_tag *symbol_value,
+ s_tag *symbol_value,
u8 op_precedence,
const s_sym * const *op_assoc,
s_tag *dest)
@@ -483,7 +481,7 @@ void env_error_f (s_env *env, const char *fmt, ...)
env_error_tag(env, &tag);
}
-void env_error_tag (s_env *env, const s_tag *tag)
+void env_error_tag (s_env *env, s_tag *tag)
{
s_error_handler *error_handler;
assert(env);
@@ -581,7 +579,7 @@ bool env_eval_block (s_env *env, const s_block *block, s_tag *dest)
return env_eval_tag(env, block->tag + i, dest);
}
-bool env_eval_call (s_env *env, const s_call *call, s_tag *dest)
+bool env_eval_call (s_env *env, s_call *call, s_tag *dest)
{
s_call c = {0};
bool result;
@@ -596,22 +594,19 @@ bool env_eval_call (s_env *env, const s_call *call, s_tag *dest)
err_write_1("\n");
return false;
}
- if (c.cfn)
- result = env_eval_call_cfn(env, &c, dest);
- else if (c.fn)
- result = env_eval_call_fn(env, &c, dest);
- else {
+ if (! c.callable || c.callable->type == CALLABLE_VOID) {
err_write_1("env_eval_call: could not resolve call ");
err_inspect_ident(&c.ident);
err_write_1("\n");
result = false;
}
+ result = env_eval_callable(env, c.callable, dest);
call_clean(&c);
return result;
}
// FIXME: better error message (cite call function name if any)
-bool env_eval_call_arguments (s_env *env, const s_list *args,
+bool env_eval_call_arguments (s_env *env, s_list *args,
s_list **dest)
{
s_list **tail;
@@ -633,26 +628,44 @@ bool env_eval_call_arguments (s_env *env, const s_list *args,
return true;
}
-bool env_eval_call_cfn (s_env *env, const s_call *call, s_tag *dest)
+bool env_eval_call_callable (s_env *env, const s_call *call,
+ s_tag *dest)
+{
+ switch (call->callable->type) {
+ case CALLABLE_CFN:
+ return env_eval_call_cfn_args(env, &call->callable->data.cfn,
+ call->arguments, dest);
+ case CALLABLE_FN:
+ return env_eval_call_fn_args(env, &call->callable->data.fn,
+ call->arguments, dest);
+ case CALLABLE_VOID:
+ err_puts("env_eval_call_callable: CALLABLE_VOID");
+ assert(! "env_eval_call_callable: CALLABLE_VOID");
+ return false;
+ }
+ err_puts("env_eval_call_callable: unknown callable type");
+ assert(! "env_eval_call_callable: unknown callable type");
+ return false;
+}
+
+bool env_eval_call_cfn_args (s_env *env, s_cfn *cfn, s_list *arguments,
+ s_tag *dest)
{
s_list *args = NULL;
s_list *args_final = NULL;
- s_cfn *cfn;
//s_frame frame;
s_tag tag;
assert(env);
assert(call);
assert(dest);
- cfn = call->cfn;
- assert(cfn);
//if (! frame_init(&frame, env->frame))
// return false;
//env->frame = &frame;
- if (call->arguments) {
+ if (arguments) {
if (cfn->macro || cfn->special_operator)
- args_final = call->arguments;
+ args_final = arguments;
else {
- if (! env_eval_call_arguments(env, call->arguments, &args)) {
+ if (! env_eval_call_arguments(env, arguments, &args)) {
//env->frame = frame_clean(&frame);
return false;
}
@@ -675,14 +688,21 @@ bool env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
assert(env);
assert(call);
assert(dest);
- return env_eval_call_fn_args(env, call->fn, call->arguments, dest);
+ if (! call->callable ||
+ call->callable->type != CALLABLE_FN) {
+ err_puts("env_eval_call_fn: not a Fn");
+ assert(! "env_eval_call_fn: not a Fn");
+ return false;
+ }
+ return env_eval_call_fn_args(env, &call->callable->data.fn,
+ call->arguments, dest);
}
bool env_eval_call_fn_args (s_env *env, const s_fn *fn,
- const s_list *arguments, s_tag *dest)
+ s_list *arguments, s_tag *dest)
{
s_list *args = NULL;
- const s_list *args_final = NULL;
+ s_list *args_final = NULL;
s_fn_clause *clause;
s_frame *env_frame;
s_frame frame;
@@ -802,13 +822,8 @@ bool env_eval_call_resolve (s_env *env, s_call *call)
tmp = *call;
if (tmp.ident.module == NULL &&
(value = env_frames_get(env, tmp.ident.sym))) {
- if (value->type == TAG_CFN) {
- tmp.cfn = cfn_new_copy(&value->data.cfn);
- *call = tmp;
- return true;
- }
- else if (value->type == TAG_FN) {
- tmp.fn = fn_new_copy(&value->data.fn);
+ if (value->type == TAG_CALLABLE) {
+ tmp.callable = callable_new_ref(value->data.callable);
*call = tmp;
return true;
}
@@ -849,24 +864,48 @@ bool env_eval_call_resolve (s_env *env, s_call *call)
return true;
}
-bool env_eval_cfn (s_env *env, const s_cfn *cfn, s_tag *dest)
+bool env_eval_callable (s_env *env, s_callable *callable,
+ s_tag *dest)
{
- s_cfn tmp = {0};
- assert(cfn);
+ s_callable *tmp = NULL;
+ assert(env);
+ assert(callable);
assert(dest);
(void) env;
- if (! cfn_init_copy(&tmp, cfn))
- return false;
- if (! cfn_prep_cif(&tmp))
+ if (! (tmp = callable_new_ref(callable)))
return false;
- if (! cfn_link(&tmp))
+ switch (tmp->type) {
+ case CALLABLE_CFN:
+ if (! tmp->data.cfn.ready) {
+ if (! cfn_prep_cif(&tmp->data.cfn))
+ goto ko;
+ if (! cfn_link(&tmp->data.cfn))
+ goto ko;
+ tmp->data.cfn.ready = true;
+ }
+ break;
+ case CALLABLE_FN:
+ if (! tmp->data.fn.module)
+ tmp->data.fn.module = env->current_defmodule;
+ if (! tmp->data.fn.frame &&
+ ! (tmp->data.fn.frame = frame_new_copy(env->frame)))
+ return false;
+ break;
+ case CALLABLE_VOID:
+ err_puts("env_eval_callable: CALLABLE_VOID");
+ assert(! "env_eval_callable: CALLABLE_VOID");
return false;
- dest->type = TAG_CFN;
- dest->data.cfn = tmp;
+ }
+ dest->type = TAG_CALLABLE;
+ dest->data.callable = tmp;
return true;
+ ko:
+ if (tmp)
+ callable_delete(tmp);
+ return false;
}
-bool env_eval_complex (s_env *env, const s_complex *c, s_tag *dest)
+bool env_eval_complex (s_env *env, s_complex *c, s_tag *dest)
{
s_complex *tmp = NULL;
assert(env);
@@ -889,7 +928,7 @@ bool env_eval_complex (s_env *env, const s_complex *c, s_tag *dest)
return true;
}
-bool env_eval_cow (s_env *env, const s_cow *cow, s_tag *dest)
+bool env_eval_cow (s_env *env, s_cow *cow, s_tag *dest)
{
s_cow *tmp = NULL;
assert(env);
@@ -909,8 +948,8 @@ bool env_eval_cow (s_env *env, const s_cow *cow, s_tag *dest)
return true;
}
-bool env_eval_equal_cow (s_env *env, const s_cow *a,
- const s_cow *b, s_cow **dest)
+bool env_eval_equal_cow (s_env *env, s_cow *a,
+ s_cow *b, s_cow **dest)
{
s8 r;
s_cow *tmp = {0};
@@ -937,8 +976,8 @@ bool env_eval_equal_cow (s_env *env, const s_cow *a,
return true;
}
-bool env_eval_equal_list (s_env *env, bool macro, const s_list *a,
- const s_list *b, s_list **dest)
+bool env_eval_equal_list (s_env *env, bool macro, s_list *a,
+ s_list *b, s_list **dest)
{
s_list *a_next;
s_list *b_next;
@@ -1027,8 +1066,8 @@ bool env_eval_equal_map (s_env *env, bool macro, const s_map *a,
return true;
}
-bool env_eval_equal_tag (s_env *env, bool macro, const s_tag *a,
- const s_tag *b, s_tag *dest)
+bool env_eval_equal_tag (s_env *env, bool macro, s_tag *a,
+ s_tag *b, s_tag *dest)
{
bool is_unbound_a;
bool is_unbound_b;
@@ -1209,10 +1248,9 @@ bool env_eval_equal_tag (s_env *env, bool macro, const s_tag *a,
case TAG_BLOCK:
case TAG_BOOL:
case TAG_CALL:
- case TAG_CFN:
+ case TAG_CALLABLE:
case TAG_CHARACTER:
case TAG_FACT:
- case TAG_FN:
case TAG_IDENT:
case TAG_PTAG:
case TAG_PTR:
@@ -1253,8 +1291,8 @@ bool env_eval_equal_tag (s_env *env, bool macro, const s_tag *a,
return false;
}
-bool env_eval_equal_time (s_env *env, bool macro, const s_time *a,
- const s_time *b, s_time *dest)
+bool env_eval_equal_time (s_env *env, bool macro, s_time *a,
+ s_time *b, s_time *dest)
{
s_tag *a2;
s_tag a_tag[2] = {0};
@@ -1306,8 +1344,8 @@ bool env_eval_equal_time (s_env *env, bool macro, const s_time *a,
return true;
}
-bool env_eval_equal_tuple (s_env *env, bool macro, const s_tuple *a,
- const s_tuple *b, s_tuple *dest)
+bool env_eval_equal_tuple (s_env *env, bool macro, s_tuple *a,
+ s_tuple *b, s_tuple *dest)
{
uw i;
s_tuple tmp = {0};
@@ -1346,27 +1384,9 @@ bool env_eval_equal_tuple (s_env *env, bool macro, const s_tuple *a,
return true;
}
-bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest)
-{
- s_tag tmp = {0};
- assert(env);
- assert(fn);
- assert(dest);
- tmp.type = TAG_FN;
- if (! fn_init_copy(&tmp.data.fn, fn))
- return false;
- if (! tmp.data.fn.module)
- tmp.data.fn.module = env->current_defmodule;
- if (! tmp.data.fn.frame &&
- ! (tmp.data.fn.frame = frame_new_copy(env->frame)))
- return false;
- *dest = tmp;
- return true;
-}
-
bool env_eval_ident (s_env *env, const s_ident *ident, s_tag *dest)
{
- const s_tag *tag;
+ s_tag *tag;
s_tag tmp = {0};
s_ident tmp_ident;
assert(env);
@@ -1383,7 +1403,7 @@ bool env_eval_ident (s_env *env, const s_ident *ident, s_tag *dest)
err_write_1("\n");
if (true) {
err_puts("env_eval_ident: stacktrace:");
- err_inspect_list((const s_list * const *) &env->stacktrace);
+ err_inspect_list(env->stacktrace);
err_write_1("\n");
}
if (false) {
@@ -1414,7 +1434,7 @@ bool env_eval_ident_is_bound (s_env *env, const s_ident *ident)
return false;
}
-bool env_eval_list (s_env *env, const s_list *list, s_tag *dest)
+bool env_eval_list (s_env *env, s_list *list, s_tag *dest)
{
s_list *next;
s_list *tmp = NULL;
@@ -1440,7 +1460,7 @@ bool env_eval_list (s_env *env, const s_list *list, s_tag *dest)
return false;
}
-bool env_eval_map (s_env *env, const s_map *map, s_tag *dest)
+bool env_eval_map (s_env *env, s_map *map, s_tag *dest)
{
s_map tmp = {0};
uw i = 0;
@@ -1464,7 +1484,7 @@ bool env_eval_map (s_env *env, const s_map *map, s_tag *dest)
return false;
}
-bool env_eval_quote (s_env *env, const s_quote *quote, s_tag *dest)
+bool env_eval_quote (s_env *env, s_quote *quote, s_tag *dest)
{
bool r;
assert(env);
@@ -1476,7 +1496,7 @@ bool env_eval_quote (s_env *env, const s_quote *quote, s_tag *dest)
return r;
}
-bool env_eval_quote_array (s_env *env, const s_array *array,
+bool env_eval_quote_array (s_env *env, s_array *array,
s_tag *dest)
{
uw i;
@@ -1514,7 +1534,7 @@ bool env_eval_quote_array (s_env *env, const s_array *array,
return false;
}
-bool env_eval_quote_block (s_env *env, const s_block *block, s_tag *dest)
+bool env_eval_quote_block (s_env *env, s_block *block, s_tag *dest)
{
uw i = 0;
s_block tmp = {0};
@@ -1535,9 +1555,9 @@ bool env_eval_quote_block (s_env *env, const s_block *block, s_tag *dest)
return false;
}
-bool env_eval_quote_call (s_env *env, const s_call *call, s_tag *dest)
+bool env_eval_quote_call (s_env *env, s_call *call, s_tag *dest)
{
- const s_list *arg;
+ s_list *arg;
s_call tmp = {0};
s_list **tmp_arg_last;
assert(call);
@@ -1553,16 +1573,8 @@ bool env_eval_quote_call (s_env *env, const s_call *call, s_tag *dest)
tmp_arg_last = &(*tmp_arg_last)->next.data.list;
arg = list_next(arg);
}
- if (call->cfn) {
- tmp.cfn = cfn_new_copy(call->cfn);
- if (! tmp.cfn)
- goto ko;
- }
- if (call->fn) {
- tmp.fn = fn_new_copy(call->fn);
- if (! tmp.fn)
- goto ko;
- }
+ if (call->callable)
+ tmp.callable = callable_new_ref(call->callable);
dest->type = TAG_CALL;
dest->data.call = tmp;
return true;
@@ -1571,7 +1583,7 @@ bool env_eval_quote_call (s_env *env, const s_call *call, s_tag *dest)
return false;
}
-bool env_eval_quote_complex (s_env *env, const s_complex *c,
+bool env_eval_quote_complex (s_env *env, s_complex *c,
s_tag *dest)
{
s_tag tmp = {0};
@@ -1591,7 +1603,7 @@ bool env_eval_quote_complex (s_env *env, const s_complex *c,
return true;
}
-bool env_eval_quote_cow (s_env *env, const s_cow *cow,
+bool env_eval_quote_cow (s_env *env, s_cow *cow,
s_tag *dest)
{
s_tag tmp = {0};
@@ -1612,7 +1624,7 @@ bool env_eval_quote_cow (s_env *env, const s_cow *cow,
return true;
}
-bool env_eval_quote_list (s_env *env, const s_list *list, s_tag *dest)
+bool env_eval_quote_list (s_env *env, s_list *list, s_tag *dest)
{
s_list *next = NULL;
s_list *tmp = NULL;
@@ -1640,7 +1652,7 @@ bool env_eval_quote_list (s_env *env, const s_list *list, s_tag *dest)
return false;
}
-bool env_eval_quote_map (s_env *env, const s_map *map, s_tag *dest)
+bool env_eval_quote_map (s_env *env, s_map *map, s_tag *dest)
{
s_map tmp = {0};
uw i = 0;
@@ -1663,7 +1675,7 @@ bool env_eval_quote_map (s_env *env, const s_map *map, s_tag *dest)
return false;
}
-bool env_eval_quote_quote (s_env *env, const s_quote *quote, s_tag *dest)
+bool env_eval_quote_quote (s_env *env, s_quote *quote, s_tag *dest)
{
bool r;
s_quote tmp = {0};
@@ -1683,7 +1695,7 @@ bool env_eval_quote_quote (s_env *env, const s_quote *quote, s_tag *dest)
return true;
}
-bool env_eval_quote_struct (s_env *env, const s_struct *s, s_tag *dest)
+bool env_eval_quote_struct (s_env *env, s_struct *s, s_tag *dest)
{
uw i;
s_struct *t;
@@ -1717,7 +1729,7 @@ bool env_eval_quote_struct (s_env *env, const s_struct *s, s_tag *dest)
}
// Like tag_init_copy excepted that the unquote parts get evaluated.
-bool env_eval_quote_tag (s_env *env, const s_tag *tag, s_tag *dest)
+bool env_eval_quote_tag (s_env *env, s_tag *tag, s_tag *dest)
{
assert(env);
assert(tag);
@@ -1749,13 +1761,12 @@ bool env_eval_quote_tag (s_env *env, const s_tag *tag, s_tag *dest)
return env_eval_quote_unquote(env, &tag->data.unquote, dest);
case TAG_VOID:
case TAG_BOOL:
- case TAG_CFN:
+ case TAG_CALLABLE:
case TAG_CHARACTER:
case TAG_F32:
case TAG_F64:
case TAG_F128:
case TAG_FACT:
- case TAG_FN:
case TAG_IDENT:
case TAG_INTEGER:
case TAG_PTAG:
@@ -1785,7 +1796,7 @@ bool env_eval_quote_tag (s_env *env, const s_tag *tag, s_tag *dest)
return false;
}
-bool env_eval_quote_time (s_env *env, const s_time *time, s_tag *dest)
+bool env_eval_quote_time (s_env *env, s_time *time, s_tag *dest)
{
s_time tmp = {0};
assert(env);
@@ -1818,7 +1829,7 @@ bool env_eval_quote_time (s_env *env, const s_time *time, s_tag *dest)
return true;
}
-bool env_eval_quote_tuple (s_env *env, const s_tuple *tuple, s_tag *dest)
+bool env_eval_quote_tuple (s_env *env, s_tuple *tuple, s_tag *dest)
{
uw i = 0;
s_tuple tmp = {0};
@@ -1839,7 +1850,8 @@ bool env_eval_quote_tuple (s_env *env, const s_tuple *tuple, s_tag *dest)
return false;
}
-bool env_eval_quote_unquote (s_env *env, const s_unquote *unquote, s_tag *dest)
+bool env_eval_quote_unquote (s_env *env, s_unquote *unquote,
+ s_tag *dest)
{
bool r;
s_tag tmp = {0};
@@ -1869,7 +1881,7 @@ bool env_eval_quote_unquote (s_env *env, const s_unquote *unquote, s_tag *dest)
bool env_eval_struct (s_env *env, const s_struct *s, s_struct *dest)
{
- const void *data = NULL;
+ void *data = NULL;
uw i;
s_tag tag = {0};
s_struct tmp = {0};
@@ -1943,7 +1955,7 @@ bool env_eval_struct_tag (s_env *env, const s_struct *s, s_tag *dest)
return true;
}
-bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
+bool env_eval_tag (s_env *env, s_tag *tag, s_tag *dest)
{
assert(env);
assert(tag);
@@ -1958,14 +1970,12 @@ bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
return env_eval_block(env, &tag->data.block, dest);
case TAG_CALL:
return env_eval_call(env, &tag->data.call, dest);
- case TAG_CFN:
- return env_eval_cfn(env, &tag->data.cfn, dest);
+ case TAG_CALLABLE:
+ return env_eval_callable(env, tag->data.callable, dest);
case TAG_COMPLEX:
return env_eval_complex(env, tag->data.complex, dest);
case TAG_COW:
return env_eval_cow(env, tag->data.cow, dest);
- case TAG_FN:
- return env_eval_fn(env, &tag->data.fn, dest);
case TAG_IDENT:
return env_eval_ident(env, &tag->data.ident, dest);
case TAG_LIST:
@@ -2089,14 +2099,14 @@ bool env_eval_var (s_env *env, const s_var *var, s_tag *dest)
return true;
}
-s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
+s_fact_w * env_fact_w_eval (s_env *env, s_fact_w *fact,
s_fact_w *dest)
{
s_fact_w tmp = {0};
assert(env);
assert(fact);
assert(dest);
- if (fact->subject.type == TAG_CFN) {
+ if (fact->subject.type == TAG_CALLABLE) {
if (! env_eval_tag(env, &fact->subject, &tmp.subject))
return NULL;
}
@@ -2104,7 +2114,7 @@ s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
if (! tag_init_copy(&tmp.subject, &fact->subject))
return NULL;
}
- if (fact->predicate.type == TAG_CFN) {
+ if (fact->predicate.type == TAG_CALLABLE) {
if (! env_eval_tag(env, &fact->predicate, &tmp.predicate))
return NULL;
}
@@ -2112,7 +2122,7 @@ s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
if (! tag_init_copy(&tmp.predicate, &fact->predicate))
return NULL;
}
- if (fact->object.type == TAG_CFN) {
+ if (fact->object.type == TAG_CALLABLE) {
if (! env_eval_tag(env, &fact->object, &tmp.object))
return NULL;
}
@@ -2192,7 +2202,7 @@ s_tag * env_facts_collect_with_tags (s_env *env, s_facts *facts,
{
s_list *arguments;
s_facts_cursor cursor = {0};
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_fact_w *fact_w = NULL;
s_list **l;
s_list *list;
@@ -2241,7 +2251,7 @@ s_tag * env_facts_first_with (s_env *env, s_facts *facts,
{
s_list *arguments;
s_facts_with_cursor cursor = {0};
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_fact_w *fact_w = NULL;
s_tag tmp = {0};
assert(env);
@@ -2290,7 +2300,7 @@ s_tag * env_facts_first_with_tags (s_env *env, s_facts *facts,
{
s_list *arguments;
s_facts_cursor cursor = {0};
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_fact_w *fact_w = NULL;
s_tag tmp = {0};
assert(env);
@@ -2334,7 +2344,7 @@ s_tag * env_facts_with (s_env *env, s_facts *facts, s_list **spec,
{
s_list *arguments;
s_facts_with_cursor cursor = {0};
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_fact_w *fact_w = NULL;
s_tag tmp = {0};
if (! (arguments = list_new_struct(&g_sym_FactW, NULL)))
@@ -2423,7 +2433,7 @@ s_tag * env_facts_with_tags (s_env *env, s_facts *facts, s_tag *subject,
{
s_list *arguments;
s_facts_cursor cursor = {0};
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_fact_w *fact_w = NULL;
s_tag tmp = {0};
if (! (arguments = list_new_struct(&g_sym_FactW, NULL)))
@@ -2460,9 +2470,9 @@ s_tag * env_facts_with_tags (s_env *env, s_facts *facts, s_tag *subject,
return NULL;
}
-const s_tag * env_frames_get (const s_env *env, const s_sym *name)
+s_tag * env_frames_get (s_env *env, const s_sym *name)
{
- const s_tag *tag;
+ s_tag *tag;
if ((tag = frame_get(env->frame, name)) ||
(tag = frame_get(&env->global_frame, name)))
return tag;
@@ -2472,7 +2482,7 @@ const s_tag * env_frames_get (const s_env *env, const s_sym *name)
s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
{
s_facts_with_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
const s_sym *module;
s_tag tag_ident;
s_tag tag_is_a;
@@ -2526,20 +2536,6 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
}
facts_with_cursor_clean(&cursor);
if (! facts_with(&env->facts, &cursor, (t_facts_spec) {
- &tag_ident, &tag_is_a, &tag_macro, NULL, NULL }))
- return NULL;
- if (! facts_with_cursor_next(&cursor, &fact)) {
- facts_with_cursor_clean(&cursor);
- return NULL;
- }
- if (fact) {
- if (tmp.type == TAG_CFN)
- tmp.data.cfn.macro = true;
- else if (tmp.type == TAG_FN)
- tmp.data.fn.macro = true;
- }
- facts_with_cursor_clean(&cursor);
- if (! facts_with(&env->facts, &cursor, (t_facts_spec) {
&tag_ident, &tag_is_a, &tag_special_operator, NULL, NULL}))
return NULL;
if (! facts_with_cursor_next(&cursor, &fact)) {
@@ -2547,10 +2543,21 @@ s_tag * env_ident_get (s_env *env, const s_ident *ident, s_tag *dest)
return NULL;
}
if (fact) {
- if (tmp.type == TAG_CFN)
- tmp.data.cfn.special_operator = true;
- else if (tmp.type == TAG_FN)
- tmp.data.fn.special_operator = true;
+ if (tmp.type == TAG_CALLABLE) {
+ switch (tmp.data.callable->type) {
+ case CALLABLE_CFN:
+ tmp.data.callable->data.cfn.special_operator = true;
+ break;
+ case CALLABLE_FN:
+ tmp.data.callable->data.fn.special_operator = true;
+ break;
+ case CALLABLE_VOID:
+ err_puts("env_ident_get: CALLABLE_VOID");
+ assert(! "env_ident_get: CALLABLE_VOID");
+ facts_with_cursor_clean(&cursor);
+ return NULL;
+ }
+ }
}
facts_with_cursor_clean(&cursor);
*dest = tmp;
@@ -2561,7 +2568,7 @@ bool * env_ident_is_special_operator (s_env *env,
const s_ident *ident,
bool *dest)
{
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_ident;
s_tag tag_is_a;
s_tag tag_special_operator;
@@ -2759,12 +2766,12 @@ s_tag * env_kc3_def (s_env *env, const s_call *call, s_tag *dest)
return dest;
}
-s_tag * env_let (s_env *env, const s_tag *vars, const s_tag *tag,
+s_tag * env_let (s_env *env, s_tag *vars, s_tag *tag,
s_tag *dest)
{
s_frame frame;
uw i;
- const s_map *map;
+ s_map *map;
s_tag tmp = {0};
assert(env);
assert(vars);
@@ -2783,6 +2790,7 @@ s_tag * env_let (s_env *env, const s_tag *vars, const s_tag *tag,
break;
case TAG_STRUCT:
map = &tmp.data.struct_.type->map;
+ // FIXME
break;
default:
tag_clean(&tmp);
@@ -2920,7 +2928,7 @@ const s_sym ** env_module (s_env *env, const s_sym **dest)
bool env_module_ensure_loaded (s_env *env, const s_sym *module)
{
bool b;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_module_name;
s_tag tag_is_a;
s_tag tag_module;
@@ -2957,7 +2965,7 @@ bool * env_module_has_ident (s_env *env, const s_sym *module,
const s_ident *ident, bool *dest)
{
s_facts_with_cursor cursor;
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_tag tag_ident;
s_tag tag_module_name;
s_tag tag_operator;
@@ -3021,7 +3029,7 @@ bool * env_module_has_symbol (s_env *env, const s_sym *module,
bool * env_module_is_loading (s_env *env, const s_sym *module,
bool *dest)
{
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_module;
s_tag tag_is_loading;
s_tag tag_true;
@@ -3133,7 +3141,7 @@ const s_time ** env_module_load_time (s_env *env, const s_sym *module,
const s_time **dest)
{
s_facts_with_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_module_name;
s_tag tag_load_time;
s_tag tag_time_var;
@@ -3231,7 +3239,7 @@ s_list ** env_module_search_modules (s_env *env,
s8 env_operator_arity (s_env *env, const s_ident *op)
{
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s8 r = -1;
s_tag tag_op;
s_tag tag_arity;
@@ -3259,7 +3267,7 @@ s8 env_operator_arity (s_env *env, const s_ident *op)
bool * env_operator_find (s_env *env, const s_ident *op, bool *dest)
{
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_is_a;
s_tag tag_op;
s_tag tag_operator;
@@ -3280,7 +3288,7 @@ s_tag * env_operator_find_by_sym (s_env *env,
s_tag *dest)
{
s_facts_with_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_ident;
s_tag tag_is_a;
s_tag tag_operator;
@@ -3362,7 +3370,7 @@ s_ident * env_operator_ident (s_env *env, const s_ident *op,
bool * env_operator_is_right_associative (s_env *env, const s_ident *op,
bool *dest)
{
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_assoc;
s_tag tag_op;
s_tag tag_right;
@@ -3381,7 +3389,7 @@ bool * env_operator_is_right_associative (s_env *env, const s_ident *op,
sw * env_operator_precedence (s_env *env, const s_ident *op, sw *dest)
{
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
const s_sym *sym_sw = &g_sym_Sw;
s_tag tag_op;
s_tag tag_precedence;
@@ -3416,7 +3424,7 @@ s_ident * env_operator_resolve (s_env *env, const s_ident *op,
u8 arity, s_ident *dest)
{
s_facts_with_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_arity;
s_tag tag_arity_u8;
s_tag tag_is_a;
@@ -3483,7 +3491,7 @@ const s_sym ** env_operator_symbol (s_env *env, const s_ident *op,
const s_sym **dest)
{
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
const s_sym **result = NULL;
s_tag tag_op;
s_tag tag_sym_sym;
@@ -3513,7 +3521,7 @@ const s_sym ** env_operator_symbol (s_env *env, const s_ident *op,
return result;
}
-bool * env_or (s_env *env, const s_tag *a, const s_tag *b, bool *dest)
+bool * env_or (s_env *env, s_tag *a, s_tag *b, bool *dest)
{
s_tag eval;
bool tmp;
@@ -3575,7 +3583,7 @@ s_list ** env_search_modules (s_env *env, s_list **dest)
assert(dest);
assert(env->search_modules);
assert(env->search_modules->tag.type == TAG_SYM);
- return list_init_copy(dest, (const s_list * const *) &env->search_modules);
+ return list_init_copy(dest, &env->search_modules);
}
s_list ** env_stacktrace (s_env *env, s_list **dest)
@@ -3633,7 +3641,7 @@ bool env_sym_search_modules (s_env *env, const s_sym *sym,
err_write_1(": search_module: ");
err_inspect_sym(&module);
err_write_1(" ");
- err_inspect_list((const s_list * const *) &search_module);
+ err_inspect_list(search_module);
err_puts(" -> not found");
}
search_module = list_next(search_module);
@@ -3642,7 +3650,7 @@ bool env_sym_search_modules (s_env *env, const s_sym *sym,
err_write_1("env_sym_search_modules: ");
err_inspect_sym(&sym);
err_write_1(": search_module: ");
- err_inspect_list((const s_list * const *) &env->search_modules);
+ err_inspect_list(env->search_modules);
err_write_1(" -> false\n");
}
*dest = NULL;
@@ -3653,7 +3661,7 @@ u8 env_special_operator_arity (s_env *env, const s_ident *ident)
{
u8 arity;
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_arity;
s_tag tag_ident;
s_tag tag_var;
@@ -3693,7 +3701,7 @@ bool * env_struct_type_exists (s_env *env, const s_sym *module,
bool *dest)
{
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_struct_type;
s_tag tag_module;
s_tag tag_var;
@@ -3720,7 +3728,7 @@ const s_struct_type ** env_struct_type_find (s_env *env,
const s_struct_type **dest)
{
s_facts_with_cursor cursor;
- const s_fact *found;
+ s_fact *found;
s_tag tag_struct_type;
s_tag tag_module;
s_tag tag_var;
@@ -3776,7 +3784,7 @@ const s_struct_type ** env_struct_type_find (s_env *env,
f_clean env_struct_type_get_clean (s_env *env, const s_sym *module)
{
s_facts_with_cursor cursor;
- const s_fact *found;
+ s_fact *found;
s_tag tag_clean;
s_tag tag_module;
s_tag tag_var;
@@ -3793,7 +3801,8 @@ f_clean env_struct_type_get_clean (s_env *env, const s_sym *module)
facts_with_cursor_clean(&cursor);
return NULL;
}
- if (found->object->type != TAG_CFN) {
+ if (found->object->type != TAG_CALLABLE ||
+ found->object->data.callable->type != CALLABLE_CFN) {
tag_type(found->object, &type);
err_write_1("env_struct_type_get_clean: ");
err_inspect_sym(&module);
@@ -3804,17 +3813,17 @@ f_clean env_struct_type_get_clean (s_env *env, const s_sym *module)
facts_with_cursor_clean(&cursor);
return NULL;
}
- if (found->object->data.cfn.arity != 1) {
+ if (found->object->data.callable->data.cfn.arity != 1) {
err_write_1("env_struct_type_get_clean: ");
err_inspect_sym(&module);
err_write_1(": clean arity is ");
- err_inspect_u8(&found->object->data.cfn.arity);
+ err_inspect_u8(&found->object->data.callable->data.cfn.arity);
err_write_1(", it should be 1.\n");
assert(! "env_struct_type_get_clean: invalid arity");
facts_with_cursor_clean(&cursor);
return NULL;
}
- tmp = (f_clean) found->object->data.cfn.ptr.f;
+ tmp = (f_clean) found->object->data.callable->data.cfn.ptr.f;
facts_with_cursor_clean(&cursor);
return tmp;
}
@@ -3823,7 +3832,7 @@ s_list ** env_struct_type_get_spec (s_env *env,
const s_sym *module,
s_list **dest)
{
- const s_fact *found;
+ s_fact *found;
s_tag tag_defstruct;
s_tag tag_module;
s_tag tag_var;
@@ -3862,7 +3871,7 @@ bool * env_struct_type_has_spec (s_env *env, const s_sym *module,
bool *dest)
{
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag tag_defstruct;
s_tag tag_module;
s_tag tag_var;
@@ -3909,7 +3918,7 @@ s_tag * env_unwind_protect (s_env *env, s_tag *protected, s_block *cleanup,
return dest;
}
-s_tag * env_while (s_env *env, const s_tag *cond, const s_tag *body,
+s_tag * env_while (s_env *env, s_tag *cond, s_tag *body,
s_tag *dest)
{
s_tag cond_bool = {0};
diff --git a/libkc3/env.h b/libkc3/env.h
index b3242f0..367da01 100644
--- a/libkc3/env.h
+++ b/libkc3/env.h
@@ -23,7 +23,7 @@ s_env * env_init (s_env *env, int *argc, char ***argv);
/* Observers. */
s_list ** env_args (s_env *env, s_list **dest);
-const s_tag * env_frames_get (const s_env *env, const s_sym *name);
+s_tag * env_frames_get (s_env *env, const s_sym *name);
s_ident * env_ident_resolve_module (s_env *env,
const s_ident *ident,
s_ident *dest);
@@ -44,22 +44,21 @@ bool env_sym_search_modules (s_env *env,
const s_sym **dest);
/* Operators. */
-bool * env_and (s_env *env, const s_tag *a, const s_tag *b,
+bool * env_and (s_env *env, s_tag *a, s_tag *b,
bool *dest);
-bool env_def (s_env *env, const s_ident *ident,
- const s_tag *value);
+bool env_def (s_env *env, const s_ident *ident, s_tag *value);
const s_sym * env_def_clean (s_env *env, const s_sym *module,
const s_tag *tag_clean);
s_tag * env_defmodule (s_env *env, const s_sym * const *name,
const s_block *block, s_tag *dest);
s_tag * env_defoperator (s_env *env, const s_sym * const *name,
const s_sym * const *sym,
- const s_tag *symbol_value,
+ s_tag *symbol_value,
u8 op_precedence,
const s_sym * const *op_assoc,
s_tag *dest);
const s_sym * env_defstruct (s_env *env, const s_list *spec);
-s_fact_w * env_fact_w_eval (s_env *env, const s_fact_w *fact,
+s_fact_w * env_fact_w_eval (s_env *env, s_fact_w *fact,
s_fact_w *dest);
s_tag * env_facts_collect_with (s_env *env, s_facts *facts,
s_list **spec, s_fn *callback,
@@ -95,7 +94,7 @@ bool * env_ident_is_special_operator (s_env *env,
bool *dest);
s_tag * env_kc3_def (s_env *env, const s_call *call,
s_tag *dest);
-s_tag * env_let (s_env *env, const s_tag *vars, const s_tag *tag,
+s_tag * env_let (s_env *env, s_tag *vars, s_tag *tag,
s_tag *dest);
bool env_load (s_env *env, const s_str *path);
bool * env_module_is_loading (s_env *env, const s_sym *module,
@@ -123,7 +122,7 @@ s_ident * env_operator_resolve (s_env *env, const s_ident *op,
u8 arity, s_ident *dest);
const s_sym ** env_operator_symbol (s_env *env, const s_ident *op,
const s_sym **dest);
-bool * env_or (s_env *env, const s_tag *a, const s_tag *b,
+bool * env_or (s_env *env, s_tag *a, s_tag *b,
bool *dest);
u8 env_special_operator_arity (s_env *env,
const s_ident *ident);
@@ -142,8 +141,8 @@ bool * env_struct_type_has_spec (s_env *env,
bool *dest);
bool env_tag_ident_is_bound (s_env *env,
const s_tag *tag);
-s_tag * env_while (s_env *env, const s_tag *cond,
- const s_tag *body, s_tag *dest);
+s_tag * env_while (s_env *env, s_tag *cond, s_tag *body,
+ s_tag *dest);
/* Evaluator. */
bool env_eval_array (s_env *env, const s_array *array,
@@ -152,118 +151,84 @@ bool env_eval_array_tag (s_env *env, const s_array *array,
s_tag *dest);
bool env_eval_block (s_env *env, const s_block *block,
s_tag *dest);
-bool env_eval_call (s_env *env, const s_call *call,
+bool env_eval_call (s_env *env, s_call *call,
s_tag *dest);
-bool env_eval_call_arguments (s_env *env, const s_list *args,
+bool env_eval_call_arguments (s_env *env, s_list *args,
s_list **dest);
-bool env_eval_call_cfn (s_env *env, const s_call *call,
- s_tag *dest);
+bool env_eval_call_cfn_args (s_env *env, s_cfn *cfn, s_list *arguments,
+ s_tag *dest);
bool env_eval_call_fn (s_env *env, const s_call *call,
s_tag *dest);
bool env_eval_call_fn_args (s_env *env, const s_fn *fn,
- const s_list *arguments,
+ s_list *arguments,
s_tag *dest);
bool env_eval_call_resolve (s_env *env, s_call *call);
-bool env_eval_cfn (s_env *env, const s_cfn *cfn, s_tag *dest);
-bool env_eval_complex (s_env *env, const s_complex *c,
+bool env_eval_complex (s_env *env, s_complex *c,
s_tag *dest);
-bool env_eval_cow (s_env *env, const s_cow *cow, s_tag *dest);
+bool env_eval_cow (s_env *env, s_cow *cow, s_tag *dest);
bool env_eval_equal_block (s_env *env, bool macro,
- const s_block *a, const s_block *b,
+ s_block *a, s_block *b,
s_block *dest);
bool env_eval_equal_list (s_env *env, bool macro,
- const s_list *a, const s_list *b,
+ s_list *a, s_list *b,
s_list **dest);
bool env_eval_equal_struct (s_env *env, bool macro,
- const s_struct *a,
- const s_struct *b,
+ s_struct *a,
+ s_struct *b,
s_struct *dest);
bool env_eval_equal_tag (s_env *env, bool macro,
- const s_tag *a, const s_tag *b,
+ s_tag *a, s_tag *b,
s_tag *dest);
bool env_eval_equal_time (s_env *env, bool macro,
- const s_time *a, const s_time *b,
+ s_time *a, s_time *b,
s_time *dest);
bool env_eval_equal_tuple (s_env *env, bool macro,
- const s_tuple *a, const s_tuple *b,
+ s_tuple *a, s_tuple *b,
s_tuple *dest);
-bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
-bool env_eval_fn_tag (s_env *env, const s_tag *tag,
- s_tag *dest);
-bool env_eval_fn_tag_array (s_env *env, const s_array *array,
- s_tag *dest);
-bool env_eval_fn_tag_block (s_env *env, const s_block *block,
- s_tag *dest);
-bool env_eval_fn_tag_call (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_fn_tag_complex (s_env *env, const s_complex *c,
- s_tag *dest);
-bool env_eval_fn_tag_ident (s_env *env, const s_ident *ident,
- s_tag *dest);
-bool env_eval_fn_tag_list (s_env *env, const s_list *list,
- s_tag *dest);
-bool env_eval_fn_tag_map (s_env *env, const s_map *map,
- s_tag *dest);
-bool env_eval_fn_tag_quote (s_env *env, const s_quote *quote,
- s_tag *dest);
-bool env_eval_fn_tag_str (s_env *env, const s_str *str,
- s_tag *dest);
-bool env_eval_fn_tag_struct (s_env *env, const s_struct *s,
- s_tag *dest);
-bool env_eval_fn_tag_tag (s_env *env, const s_tag *tag,
- s_tag *dest);
-bool env_eval_fn_tag_tuple (s_env *env, const s_tuple *tuple,
- s_tag *dest);
-bool env_eval_fn_tag_unquote (s_env *env,
- const s_unquote *unquote,
- s_tag *dest);
bool env_eval_ident (s_env *env, const s_ident *ident,
s_tag *dest);
bool env_eval_ident_is_bound (s_env *env,
const s_ident *ident);
bool env_eval_integer (s_env *env, const s_integer *integer,
s_integer *dest);
-bool env_eval_list (s_env *env, const s_list *list,
- s_tag *dest);
-bool env_eval_map (s_env *env, const s_map *map,
+bool env_eval_list (s_env *env, s_list *list, s_tag *dest);
+bool env_eval_map (s_env *env, s_map *map,
s_tag *dest);
-bool env_eval_progn (s_env *env, const s_list *program,
+bool env_eval_progn (s_env *env, s_list *program,
s_tag *dest);
-bool env_eval_quote (s_env *env, const s_quote *quote,
+bool env_eval_quote (s_env *env, s_quote *quote,
s_tag *dest);
-bool env_eval_quote_array (s_env *env, const s_array *array,
+bool env_eval_quote_array (s_env *env, s_array *array,
s_tag *dest);
-bool env_eval_quote_block (s_env *env, const s_block *block,
+bool env_eval_quote_block (s_env *env, s_block *block,
s_tag *dest);
-bool env_eval_quote_call (s_env *env, const s_call *call,
- s_tag *dest);
-bool env_eval_quote_complex (s_env *env, const s_complex *c,
+bool env_eval_quote_call (s_env *env, s_call *call, s_tag *dest);
+bool env_eval_quote_complex (s_env *env, s_complex *c,
s_tag *dest);
-bool env_eval_quote_cow (s_env *env, const s_cow *cow,
+bool env_eval_quote_cow (s_env *env, s_cow *cow,
s_tag *dest);
-bool env_eval_quote_list (s_env *env, const s_list *list,
+bool env_eval_quote_list (s_env *env, s_list *list,
s_tag *dest);
-bool env_eval_quote_map (s_env *env, const s_map *map,
+bool env_eval_quote_map (s_env *env, s_map *map,
s_tag *dest);
-bool env_eval_quote_quote (s_env *env, const s_quote *quote,
+bool env_eval_quote_quote (s_env *env, s_quote *quote,
s_tag *dest);
-bool env_eval_quote_struct (s_env *env, const s_struct *s,
+bool env_eval_quote_struct (s_env *env, s_struct *s,
s_tag *dest);
-bool env_eval_quote_tag (s_env *env, const s_tag *tag,
+bool env_eval_quote_tag (s_env *env, s_tag *tag,
s_tag *dest);
-bool env_eval_quote_time (s_env *env, const s_time *time,
+bool env_eval_quote_time (s_env *env, s_time *time,
s_tag *dest);
-bool env_eval_quote_tuple (s_env *env, const s_tuple *tuple,
+bool env_eval_quote_tuple (s_env *env, s_tuple *tuple,
s_tag *dest);
bool env_eval_quote_unquote (s_env *env,
- const s_unquote *unquote,
+ s_unquote *unquote,
s_tag *dest);
bool env_eval_struct (s_env *env, const s_struct *s,
s_struct *dest);
bool env_eval_struct_tag (s_env *env, const s_struct *s,
s_tag *dest);
-bool env_eval_tag (s_env *env, const s_tag *tag,
- s_tag *dest);
+bool env_eval_tag (s_env *env, s_tag *tag, s_tag *dest);
bool env_eval_time (s_env *env, const s_time *time,
s_tag *dest);
bool env_eval_tuple (s_env *env, const s_tuple *tuple,
@@ -272,11 +237,13 @@ bool env_eval_var (s_env *env, const s_var *var, s_tag *dest);
/* Modifiers. */
bool env_call_get (s_env *env, s_call *call);
+bool env_eval_callable (s_env *env, s_callable *callable,
+ s_tag *dest);
bool env_module_ensure_loaded (s_env *env, const s_sym *module);
/* Control structures. */
void env_error_f (s_env *env, const char *fmt, ...);
-void env_error_tag (s_env *env, const s_tag *tag);
+void env_error_tag (s_env *env, s_tag *tag);
void env_longjmp (s_env *env, jmp_buf *jmp_buf);
#endif /* LIBKC3_ENV_H */
diff --git a/libkc3/eval.c b/libkc3/eval.c
index 69ee5cb..b146fb6 100644
--- a/libkc3/eval.c
+++ b/libkc3/eval.c
@@ -11,21 +11,51 @@
* THIS SOFTWARE.
*/
#include <stdlib.h>
-#include "types.h"
+#include "assert.h"
#include "env.h"
-bool eval_call (const s_call *call, s_tag *dest)
+bool eval_call (s_call *call, s_tag *dest)
{
return env_eval_call(&g_kc3_env, call, dest);
}
-bool eval_fn_call (const s_fn *fn, const s_list *args, s_tag *dest)
+bool eval_callable_call (s_callable *callable, s_list *arguments,
+ s_tag *dest)
+{
+ assert(callable);
+ assert(arguments);
+ assert(dest);
+ if (! callable) {
+ err_puts("eval_callable_call: NULL callable");
+ assert(! "eval_callable_call: NULL callable");
+ return false;
+ }
+ switch (callable->type) {
+ case CALLABLE_CFN:
+ return env_eval_call_cfn_args(&g_kc3_env, &callable->data.cfn,
+ arguments, dest);
+ case CALLABLE_FN:
+ return env_eval_call_fn_args(&g_kc3_env, &callable->data.fn,
+ arguments, dest);
+ case CALLABLE_VOID:
+ err_puts("eval_callable_call: CALLABLE_VOID");
+ assert(! "eval_callable_call: CALLABLE_VOID");
+ return false;
+ }
+ err_puts("eval_callable_call: unknown callable type");
+ assert(! "eval_callable_call: unknown callable type");
+ return false;
+
+
+}
+
+bool eval_fn_call (const s_fn *fn, s_list *args, s_tag *dest)
{
return env_eval_call_fn_args(&g_kc3_env, fn, args, dest);
}
-bool eval_tag (const s_tag *tag, s_tag *dest)
+bool eval_tag (s_tag *tag, s_tag *dest)
{
return env_eval_tag(&g_kc3_env, tag, dest);
}
diff --git a/libkc3/eval.h b/libkc3/eval.h
index a99e5c7..54b2d99 100644
--- a/libkc3/eval.h
+++ b/libkc3/eval.h
@@ -15,15 +15,17 @@
#include "types.h"
-bool eval_call (const s_call *call, s_tag *dest);
-bool eval_call_function (const s_call *call,
+bool eval_call (s_call *call, s_tag *dest);
+bool eval_call_function (s_call *call,
+ s_tag *dest);
+bool eval_call_macro (s_call *call, s_tag *dest);
+bool eval_callable_call (s_callable *callable, s_list *arguments,
s_tag *dest);
-bool eval_call_macro (const s_call *call, s_tag *dest);
bool eval_fn (const s_fn *fn, s_tag *dest);
-bool eval_fn_call (const s_fn *fn, const s_list *arguments,
+bool eval_fn_call (const s_fn *fn, s_list *arguments,
s_tag *dest);
bool eval_ident (const s_ident *ident, s_tag *dest);
-bool eval_progn (const s_list *program, s_tag *dest);
-bool eval_tag (const s_tag *tag, s_tag *dest);
+bool eval_progn (s_list *program, s_tag *dest);
+bool eval_tag (s_tag *tag, s_tag *dest);
#endif /* LIBKC3_EVAL_H */
diff --git a/libkc3/fact.c b/libkc3/fact.c
index a129f4b..9c7885a 100644
--- a/libkc3/fact.c
+++ b/libkc3/fact.c
@@ -29,8 +29,8 @@ uw * fact_hash_uw (const s_fact *fact, uw *dest)
return dest;
}
-s_fact * fact_init (s_fact *fact, const s_tag *subject,
- const s_tag *predicate, const s_tag *object)
+s_fact * fact_init (s_fact *fact, s_tag *subject,
+ s_tag *predicate, s_tag *object)
{
assert(fact);
fact->subject = subject;
@@ -41,7 +41,7 @@ s_fact * fact_init (s_fact *fact, const s_tag *subject,
}
s_fact * fact_init_cast (s_fact *fact, const s_sym * const *type,
- const s_tag *tag)
+ s_tag *tag)
{
assert(fact);
assert(type);
@@ -73,7 +73,7 @@ s_fact * fact_init_copy (s_fact *fact, const s_fact *src)
return fact;
}
-void fact_r (const s_fact_w *fact, s_fact *dest)
+void fact_r (s_fact_w *fact, s_fact *dest)
{
s_fact tmp = {0};
tmp.subject = &fact->subject;
@@ -90,7 +90,7 @@ void fact_w_clean (s_fact_w *fact)
tag_clean(&fact->object);
}
-s_fact_w * fact_w_eval (const s_fact_w *fact, s_fact_w *dest)
+s_fact_w * fact_w_eval (s_fact_w *fact, s_fact_w *dest)
{
return env_fact_w_eval(&g_kc3_env, fact, dest);
}
@@ -104,7 +104,7 @@ s_fact_w * fact_w_init (s_fact_w *fact)
}
s_fact_w * fact_w_init_cast (s_fact_w *fact, const s_sym * const *type,
- const s_tag *tag)
+ s_tag *tag)
{
assert(fact);
assert(type);
@@ -129,7 +129,7 @@ s_fact_w * fact_w_init_cast (s_fact_w *fact, const s_sym * const *type,
return NULL;
}
-s_fact_w * fact_w_init_fact (s_fact_w *fact, const s_fact *src)
+s_fact_w * fact_w_init_fact (s_fact_w *fact, s_fact *src)
{
s_fact_w tmp = {0};
if (! tag_init_copy(&tmp.subject, src->subject))
diff --git a/libkc3/fact.h b/libkc3/fact.h
index 6c47b9d..01dc26b 100644
--- a/libkc3/fact.h
+++ b/libkc3/fact.h
@@ -17,20 +17,20 @@
/* 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 (s_fact *fact, s_tag *subject,
+ s_tag *predicate, s_tag *object);
s_fact * fact_init_cast (s_fact *fact, const s_sym * const *type,
- const s_tag *tag);
+ 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);
+s_fact_w * fact_w_init_fact (s_fact_w *fact, s_fact *src);
void fact_w_clean (s_fact_w *fact);
/* Observers */
uw * fact_hash_uw (const s_fact *fact, uw *dest);
-void fact_r (const s_fact_w *fact, s_fact *dest);
/* Operators */
-s_fact_w * fact_w_eval (const s_fact_w *fact, s_fact_w *dest);
+void fact_r (s_fact_w *fact, s_fact *dest);
+s_fact_w * fact_w_eval (s_fact_w *fact, s_fact_w *dest);
#endif /* LIBKC3_FACT_H */
diff --git a/libkc3/facts.c b/libkc3/facts.c
index 3974096..365bcb4 100644
--- a/libkc3/facts.c
+++ b/libkc3/facts.c
@@ -41,7 +41,7 @@ static int facts_compare_pfact_id_reverse (const void *a,
static sw facts_open_file_create (s_facts *facts, const s_str *path);
static sw facts_open_log (s_facts *facts, s_buf *buf);
-const s_fact * facts_add_fact (s_facts *facts, const s_fact *fact)
+s_fact * facts_add_fact (s_facts *facts, s_fact *fact)
{
s_fact tmp = {0};
s_fact *f = NULL;
@@ -131,9 +131,8 @@ const s_fact * facts_add_fact (s_facts *facts, const s_fact *fact)
return NULL;
}
-const s_fact * facts_add_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object)
+s_fact * facts_add_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate, s_tag *object)
{
s_fact fact;
fact_init(&fact, subject, predicate, object);
@@ -198,7 +197,7 @@ void facts_delete (s_facts *facts)
sw facts_dump (s_facts *facts, s_buf *buf)
{
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_tag predicate;
s_tag object;
sw r;
@@ -261,8 +260,8 @@ sw facts_dump_file (s_facts *facts, const char *path)
return r;
}
-const s_fact ** facts_find_fact (s_facts *facts, const s_fact *fact,
- const s_fact **dest)
+s_fact ** facts_find_fact (s_facts *facts, const s_fact *fact,
+ s_fact **dest)
{
s_fact f;
s_set_item__fact *item;
@@ -280,7 +279,7 @@ const s_fact ** facts_find_fact (s_facts *facts, const s_fact *fact,
return NULL;
*dest = NULL;
if (f.subject && f.predicate && f.object &&
- (item = set_get__fact((const s_set__fact *) &facts->facts, &f)))
+ (item = set_get__fact(&facts->facts, &f)))
*dest = &item->data;
#if HAVE_PTHREAD
facts_lock_unlock_r(facts);
@@ -288,18 +287,15 @@ const s_fact ** facts_find_fact (s_facts *facts, const s_fact *fact,
return dest;
}
-const s_fact ** facts_find_fact_by_tags (s_facts *facts,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
- const s_fact **dest)
+s_fact ** facts_find_fact_by_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate, s_tag *object,
+ s_fact **dest)
{
s_fact f = {subject, predicate, object, 0};
return facts_find_fact(facts, &f, dest);
}
-const s_tag ** facts_find_tag (s_facts *facts, const s_tag *tag,
- const s_tag **dest)
+s_tag ** facts_find_tag (s_facts *facts, const s_tag *tag, s_tag **dest)
{
s_set_item__tag *item;
assert(facts);
@@ -743,7 +739,7 @@ sw facts_open_log (s_facts *facts, s_buf *buf)
return result;
}
-const s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag)
+s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag)
{
s_set_item__tag *item;
assert(facts);
@@ -801,7 +797,7 @@ bool * facts_remove_fact (s_facts *facts, const s_fact *fact,
bool *dest)
{
s_fact f;
- const s_fact *found;
+ s_fact *found;
assert(facts);
assert(fact);
#if HAVE_PTHREAD
@@ -829,9 +825,9 @@ bool * facts_remove_fact (s_facts *facts, const s_fact *fact,
return dest;
}
-bool * facts_remove_fact_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+bool * facts_remove_fact_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest)
{
s_fact fact;
@@ -845,7 +841,7 @@ bool * facts_remove_fact_tags (s_facts *facts, const s_tag *subject,
return facts_remove_fact(facts, &fact, dest);
}
-const s_fact * facts_replace_fact (s_facts *facts, const s_fact *fact)
+s_fact * facts_replace_fact (s_facts *facts, s_fact *fact)
{
assert(facts);
assert(fact);
@@ -853,13 +849,13 @@ const s_fact * facts_replace_fact (s_facts *facts, const s_fact *fact)
fact->object);
}
-const s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object)
+s_fact * facts_replace_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate,
+ s_tag *object)
{
bool b;
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
s_list *list = NULL;
s_facts_transaction transaction;
s_tag var;
diff --git a/libkc3/facts.h b/libkc3/facts.h
index 8b34939..7c1fd8d 100644
--- a/libkc3/facts.h
+++ b/libkc3/facts.h
@@ -31,36 +31,34 @@ s_facts * facts_new (void);
void facts_delete (s_facts *facts);
/* Modifiers */
-const s_fact * facts_add_fact (s_facts *facts, const s_fact *fact);
-const s_fact * facts_add_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object);
-void facts_close (s_facts *facts);
-sw facts_load (s_facts *facts, s_buf *buf,
- const s_str *path);
-sw facts_load_file (s_facts *facts, const s_str *path);
+s_fact * facts_add_fact (s_facts *facts, s_fact *fact);
+s_fact * facts_add_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate, s_tag *object);
+void facts_close (s_facts *facts);
+sw facts_load (s_facts *facts, s_buf *buf,
+ const s_str *path);
+sw facts_load_file (s_facts *facts, const s_str *path);
#if HAVE_PTHREAD
-s_facts * facts_lock_clean (s_facts *facts);
-s_facts * facts_lock_init (s_facts *facts);
-s_facts * facts_lock_r (s_facts *facts);
-s_facts * facts_lock_unlock_r (s_facts *facts);
-s_facts * facts_lock_unlock_w (s_facts *facts);
-s_facts * facts_lock_w (s_facts *facts);
+s_facts * facts_lock_clean (s_facts *facts);
+s_facts * facts_lock_init (s_facts *facts);
+s_facts * facts_lock_r (s_facts *facts);
+s_facts * facts_lock_unlock_r (s_facts *facts);
+s_facts * facts_lock_unlock_w (s_facts *facts);
+s_facts * facts_lock_w (s_facts *facts);
#endif
-sw facts_open_file (s_facts *facts, const s_str *path);
-const s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag);
-bool * facts_remove_fact (s_facts *facts, const s_fact *fact,
+sw facts_open_file (s_facts *facts, const s_str *path);
+s_tag * facts_ref_tag (s_facts *facts, const s_tag *tag);
+bool * facts_remove_fact (s_facts *facts, const s_fact *fact,
+ bool *dest);
+bool * facts_remove_fact_tags (s_facts *facts,
+ s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest);
-bool * facts_remove_fact_tags (s_facts *facts,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
- bool *dest);
-s_facts * facts_remove_all (s_facts *facts);
-const s_fact * facts_replace_fact (s_facts *facts, const s_fact *fact);
-const s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object);
+s_facts * facts_remove_all (s_facts *facts);
+s_fact * facts_replace_fact (s_facts *facts, s_fact *fact);
+s_fact * facts_replace_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate, s_tag *object);
sw facts_save_file (s_facts *facts, const char *path);
s_facts_transaction * facts_transaction_clean
(s_facts_transaction *transaction);
@@ -72,18 +70,18 @@ void facts_transaction_start
bool facts_unref_tag (s_facts *facts, const s_tag *tag);
/* Observers */
-sw facts_dump (s_facts *facts, s_buf *buf);
-sw facts_dump_file (s_facts *facts, const char *path);
-const s_fact ** facts_find_fact (s_facts *facts, const s_fact *fact,
- const s_fact **dest);
-const s_fact ** facts_find_fact_by_tags (s_facts *facts,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
- const s_fact **dest);
-const s_tag ** facts_find_tag (s_facts *facts, const s_tag *tag,
- const s_tag **dest);
-sw facts_log_add (s_log *log, const s_fact *fact);
-sw facts_log_remove (s_log *log, const s_fact *fact);
+sw facts_dump (s_facts *facts, s_buf *buf);
+sw facts_dump_file (s_facts *facts, const char *path);
+s_fact ** facts_find_fact (s_facts *facts, const s_fact *fact,
+ s_fact **dest);
+s_fact ** facts_find_fact_by_tags (s_facts *facts,
+ s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
+ s_fact **dest);
+s_tag ** facts_find_tag (s_facts *facts, const s_tag *tag,
+ s_tag **dest);
+sw facts_log_add (s_log *log, const s_fact *fact);
+sw facts_log_remove (s_log *log, const s_fact *fact);
#endif /* LIBKC3_FACTS_H */
diff --git a/libkc3/facts_cursor.c b/libkc3/facts_cursor.c
index 1e8419c..cb22b18 100644
--- a/libkc3/facts_cursor.c
+++ b/libkc3/facts_cursor.c
@@ -128,10 +128,10 @@ s_facts_cursor * facts_cursor_lock_unlock (s_facts_cursor *cursor)
#endif /* HAVE_PTHREAD */
-const s_fact ** facts_cursor_next (s_facts_cursor *cursor,
- const s_fact **dest)
+s_fact ** facts_cursor_next (s_facts_cursor *cursor,
+ s_fact **dest)
{
- const s_fact *fact;
+ s_fact *fact;
const s_sym *type;
assert(cursor);
#if HAVE_PTHREAD
diff --git a/libkc3/facts_cursor.h b/libkc3/facts_cursor.h
index 347caa8..5a77698 100644
--- a/libkc3/facts_cursor.h
+++ b/libkc3/facts_cursor.h
@@ -31,7 +31,7 @@ s_facts_cursor * facts_cursor_lock_clean (s_facts_cursor *cursor);
s_facts_cursor * facts_cursor_lock_init (s_facts_cursor *cursor);
s_facts_cursor * facts_cursor_lock_unlock (s_facts_cursor *cursor);
#endif
-const s_fact ** facts_cursor_next (s_facts_cursor *cursor,
- const s_fact **dest);
+s_fact ** facts_cursor_next (s_facts_cursor *cursor,
+ s_fact **dest);
#endif /* LIBKC3_FACTS_H */
diff --git a/libkc3/facts_spec_cursor.c b/libkc3/facts_spec_cursor.c
index a76f33d..b348dbc 100644
--- a/libkc3/facts_spec_cursor.c
+++ b/libkc3/facts_spec_cursor.c
@@ -28,8 +28,8 @@ facts_spec_cursor_init (s_facts_spec_cursor *cursor,
bool facts_spec_cursor_next (s_facts_spec_cursor *cursor,
s_fact *fact)
{
- const s_tag *predicate;
- const s_tag *object;
+ s_tag *predicate;
+ s_tag *object;
assert(cursor);
assert(fact);
do {
diff --git a/libkc3/facts_with.c b/libkc3/facts_with.c
index 9568a6b..3cc5125 100644
--- a/libkc3/facts_with.c
+++ b/libkc3/facts_with.c
@@ -76,9 +76,9 @@ s_facts_cursor * facts_with_0 (s_facts *facts,
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_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
s_var *var_subject,
s_var *var_predicate,
s_var *var_object)
@@ -116,9 +116,9 @@ s_facts_cursor * facts_with_1_2 (s_facts *facts,
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_tag *subject,
+ s_tag *predicate,
+ s_tag *object)
{
s_fact fact;
assert(facts);
diff --git a/libkc3/facts_with.h b/libkc3/facts_with.h
index 72be309..b6ddb7c 100644
--- a/libkc3/facts_with.h
+++ b/libkc3/facts_with.h
@@ -27,18 +27,18 @@ s_facts_cursor * facts_with_0 (s_facts *facts,
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_tag *subject,
+ s_tag *predicate,
+ 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_tag *subject,
+ s_tag *predicate,
+ s_tag *object);
s_facts_with_cursor * facts_with_list (s_facts *facts,
s_facts_with_cursor *cursor,
diff --git a/libkc3/facts_with_cursor.c b/libkc3/facts_with_cursor.c
index 2495fd5..cee732b 100644
--- a/libkc3/facts_with_cursor.c
+++ b/libkc3/facts_with_cursor.c
@@ -41,10 +41,10 @@ void facts_with_cursor_clean (s_facts_with_cursor *cursor)
}
}
-const s_fact ** facts_with_cursor_next (s_facts_with_cursor *cursor,
- const s_fact **dest)
+s_fact ** facts_with_cursor_next (s_facts_with_cursor *cursor,
+ s_fact **dest)
{
- const s_fact *fact = NULL;
+ s_fact *fact = NULL;
s_facts_with_cursor_level *level;
p_facts_spec parent_spec;
assert(cursor);
diff --git a/libkc3/facts_with_cursor.h b/libkc3/facts_with_cursor.h
index 334b81d..0ffda7d 100644
--- a/libkc3/facts_with_cursor.h
+++ b/libkc3/facts_with_cursor.h
@@ -16,7 +16,7 @@
#include "types.h"
void facts_with_cursor_clean (s_facts_with_cursor *cursor);
-const s_fact ** facts_with_cursor_next (s_facts_with_cursor *cursor,
- const s_fact **dest);
+s_fact ** facts_with_cursor_next (s_facts_with_cursor *cursor,
+ s_fact **dest);
#endif /* LIBKC3_FACTS_WITH_CURSOR_H */
diff --git a/libkc3/fn.c b/libkc3/fn.c
index ce3c8af..06128b9 100644
--- a/libkc3/fn.c
+++ b/libkc3/fn.c
@@ -84,6 +84,7 @@ s_fn * fn_init_1 (s_fn *fn, const char *p)
return fn;
}
+/*
s_fn * fn_init_cast (s_fn *fn, const s_sym * const *type, const s_tag *tag)
{
assert(fn);
@@ -107,6 +108,7 @@ s_fn * fn_init_cast (s_fn *fn, const s_sym * const *type, const s_tag *tag)
assert(! "fn_init_cast: cannot cast to Fn");
return NULL;
}
+*/
s_fn * fn_init_copy (s_fn *fn, const s_fn *src)
{
diff --git a/libkc3/fn.h b/libkc3/fn.h
index 16dec5b..9674517 100644
--- a/libkc3/fn.h
+++ b/libkc3/fn.h
@@ -25,8 +25,8 @@
void fn_clean (s_fn *fn);
s_fn * fn_init (s_fn *fn, const s_sym *module);
s_fn * fn_init_1 (s_fn *fn, const char *p);
-s_fn * fn_init_cast (s_fn *fn, const s_sym * const *type,
- const s_tag *tag);
+// s_fn * fn_init_cast (s_fn *fn, const s_sym * const *type,
+// const s_tag *tag);
s_fn * fn_init_copy (s_fn *fn, const s_fn *src);
/* Heap-allocation functions, call fn_delete after use. */
diff --git a/libkc3/fn_clause.c b/libkc3/fn_clause.c
index 64cbcab..b210a5a 100644
--- a/libkc3/fn_clause.c
+++ b/libkc3/fn_clause.c
@@ -59,7 +59,7 @@ s_fn_clause * fn_clause_new (s_fn_clause *next_clause)
return fn_clause_init(fn_clause, next_clause);
}
-s_fn_clause * fn_clause_new_copy (const s_fn_clause *src)
+s_fn_clause * fn_clause_new_copy (s_fn_clause *src)
{
s_fn_clause *tmp = NULL;
s_fn_clause **tail = NULL;
diff --git a/libkc3/fn_clause.h b/libkc3/fn_clause.h
index 314f752..dd8628f 100644
--- a/libkc3/fn_clause.h
+++ b/libkc3/fn_clause.h
@@ -21,16 +21,16 @@
#include "types.h"
-/* stack-allocation compatible functions */
+/* Stack-allocation compatible functions, call fn_clause_clean
+ after use. */
void fn_clause_clean (s_fn_clause *clause);
-s_fn_clause * fn_clause_init (s_fn_clause *clause, s_fn_clause *next_clause);
+s_fn_clause * fn_clause_init (s_fn_clause *clause,
+ s_fn_clause *next_clause);
-/* constructors */
-s_fn_clause * fn_clause_new (s_fn_clause *next_clause);
-s_fn_clause * fn_clause_new_copy (const s_fn_clause *src);
-
-/* destructors */
+/* Heap-allocation functions, call fn_clause_delete* after use. */
s_fn_clause * fn_clause_delete (s_fn_clause *clause);
void fn_clause_delete_all (s_fn_clause *clause);
+s_fn_clause * fn_clause_new (s_fn_clause *next_clause);
+s_fn_clause * fn_clause_new_copy (s_fn_clause *src);
-#endif /* LIBKC3_FN_H */
+#endif /* LIBKC3_FN_CLAUSE_H */
diff --git a/libkc3/frame.c b/libkc3/frame.c
index e19af11..c046d88 100644
--- a/libkc3/frame.c
+++ b/libkc3/frame.c
@@ -59,8 +59,10 @@ s_frame * frame_binding_new_copy (s_frame *frame, const s_sym *name,
frame = frame_binding_delete(frame, name);
return NULL;
}
- if (tag->type == TAG_FN)
- fn_set_name_if_null(&tag->data.fn, NULL, name);
+ if (tag->type == TAG_CALLABLE &&
+ tag->data.callable &&
+ tag->data.callable->type == CALLABLE_FN)
+ fn_set_name_if_null(&tag->data.callable->data.fn, NULL, name);
}
return frame;
}
@@ -77,7 +79,7 @@ s_tag * frame_binding_new_var (s_frame *frame)
}
s_frame * frame_binding_replace (s_frame *frame, const s_sym *name,
- const s_tag *value)
+ s_tag *value)
{
s_tag *tag;
tag = binding_get_w(frame->bindings, name);
@@ -135,10 +137,10 @@ void frame_delete_all (s_frame *frame)
f = frame_delete(f);
}
-const s_tag * frame_get (const s_frame *frame, const s_sym *sym)
+s_tag * frame_get (s_frame *frame, const s_sym *sym)
{
- const s_frame *f;
- const s_tag *result;
+ s_frame *f;
+ s_tag *result;
assert(sym);
f = frame;
while (f) {
@@ -247,8 +249,10 @@ s_frame * frame_replace (s_frame *frame, const s_sym *sym,
assert(! "frame_replace: tag_init_copy");
return NULL;
}
- if (result->type == TAG_FN)
- fn_set_name_if_null(&result->data.fn, NULL, sym);
+ if (result->type == TAG_CALLABLE &&
+ result->data.callable &&
+ result->data.callable->type == CALLABLE_FN)
+ fn_set_name_if_null(&result->data.callable->data.fn, NULL, sym);
}
return frame;
}
diff --git a/libkc3/frame.h b/libkc3/frame.h
index db3e04a..4f3c540 100644
--- a/libkc3/frame.h
+++ b/libkc3/frame.h
@@ -28,9 +28,6 @@ s_frame * frame_new_copy (const s_frame *src);
s_frame * frame_delete (s_frame *frame);
void frame_delete_all (s_frame *frame);
-/* Observers. */
-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,
@@ -38,7 +35,8 @@ s_frame * frame_binding_new_copy (s_frame *frame, const s_sym *name,
s_tag * frame_binding_new_var (s_frame *frame);
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 *value);
+s_tag * frame_get (s_frame *frame, const s_sym *sym);
s_tag * frame_get_w (s_frame *frame, const s_sym *sym);
s_frame * frame_replace (s_frame *frame, const s_sym *sym,
s_tag *value);
diff --git a/libkc3/hash.c b/libkc3/hash.c
index 65e3087..ff5a744 100644
--- a/libkc3/hash.c
+++ b/libkc3/hash.c
@@ -22,13 +22,13 @@
#include "tag_type.h"
#define HASH_UPDATE_DEF(type) \
- bool hash_update_##type (t_hash *hash, const type *x) \
+ bool hash_update_##type (t_hash *hash, type x) \
{ \
- const char t[] = #type; \
+ const char t[] = #type; \
assert(hash); \
assert(x); \
return hash_update(hash, t, sizeof(t)) && \
- hash_update(hash, x, sizeof(type)); \
+ hash_update(hash, &x, sizeof(x)); \
}
void hash_clean (t_hash *hash)
@@ -176,7 +176,7 @@ bool hash_update_complex (t_hash *hash, const s_complex *c)
return true;
}
-bool hash_update_cow (t_hash *hash, const s_cow *cow)
+bool hash_update_cow (t_hash *hash, s_cow *cow)
{
const s8 type[] = "cow";
assert(hash);
@@ -234,7 +234,7 @@ bool hash_update_fn_clauses (t_hash *hash, const s_fn_clause *clauses)
count++;
f = f->next_clause;
}
- if (! hash_update_uw(hash, &count))
+ if (! hash_update_uw(hash, count))
return false;
f = clauses;
while (f) {
@@ -256,7 +256,7 @@ bool hash_update_ident (t_hash *hash, const s_ident *ident)
return false;
if (ident->module) {
if (! hash_update_sym(hash, &ident->module) ||
- ! hash_update_char(hash, "."))
+ ! hash_update_char(hash, '.'))
return false;
}
return hash_update_sym(hash, &ident->sym);
@@ -294,7 +294,7 @@ bool hash_update_list (t_hash *hash, const s_list * const *list)
l = *list;
count = list_length(l);
if (! hash_update(hash, type, sizeof(type)) ||
- ! hash_update_uw(hash, &count))
+ ! hash_update_uw(hash, count))
return false;
if (l) {
while (l) {
@@ -441,11 +441,11 @@ bool hash_update_struct_type (t_hash *hash, const s_struct_type *st)
return false;
i = 0;
while (i < st->map.count) {
- if (! hash_update_uw(hash, st->offset + i))
+ if (! hash_update_uw(hash, st->offset[i]))
return false;
i++;
}
- return hash_update_uw(hash, &st->size);
+ return hash_update_uw(hash, st->size);
}
bool hash_update_sym (t_hash *hash, const s_sym * const *sym)
@@ -467,23 +467,23 @@ bool hash_update_tag (t_hash *hash, const s_tag *tag)
if (! hash_update(hash, type, strlen(type)))
return false;
tag_type = tag->type;
- if (! hash_update_u8(hash, &tag_type))
+ if (! hash_update_u8(hash, tag_type))
return false;
switch (tag->type) {
case TAG_ARRAY: return hash_update_array(hash, &tag->data.array);
case TAG_BLOCK: return hash_update_block(hash, &tag->data.block);
case TAG_BOOL: return hash_update_bool(hash, &tag->data.bool);
case TAG_CALL: return hash_update_call(hash, &tag->data.call);
- case TAG_CFN: return hash_update_cfn(hash, &tag->data.cfn);
+ case TAG_CALLABLE:
+ return hash_update_callable(hash, tag->data.callable);
case TAG_CHARACTER:
- return hash_update_character(hash, &tag->data.character);
+ return hash_update_character(hash, tag->data.character);
case TAG_COMPLEX: return hash_update_complex(hash, tag->data.complex);
case TAG_COW: return hash_update_cow(hash, tag->data.cow);
- case TAG_F32: return hash_update_f32(hash, &tag->data.f32);
- case TAG_F64: return hash_update_f64(hash, &tag->data.f64);
- case TAG_F128: return hash_update_f128(hash, &tag->data.f128);
+ case TAG_F32: return hash_update_f32(hash, tag->data.f32);
+ case TAG_F64: return hash_update_f64(hash, tag->data.f64);
+ case TAG_F128: return hash_update_f128(hash, tag->data.f128);
case TAG_FACT: return hash_update_fact(hash, &tag->data.fact);
- case TAG_FN: return hash_update_fn(hash, &tag->data.fn);
case TAG_IDENT: return hash_update_ident(hash, &tag->data.ident);
case TAG_INTEGER:
return hash_update_integer(hash, &tag->data.integer);
@@ -497,11 +497,11 @@ bool hash_update_tag (t_hash *hash, const s_tag *tag)
return hash_update_ptr_free(hash, &tag->data.ptr_free);
case TAG_QUOTE: return hash_update_quote(hash, &tag->data.quote);
case TAG_RATIO: return hash_update_ratio(hash, &tag->data.ratio);
- case TAG_S8: return hash_update_s8(hash, &tag->data.s8);
- case TAG_S16: return hash_update_s16(hash, &tag->data.s16);
- case TAG_S32: return hash_update_s32(hash, &tag->data.s32);
- case TAG_S64: return hash_update_s64(hash, &tag->data.s64);
- case TAG_SW: return hash_update_sw(hash, &tag->data.sw);
+ case TAG_S8: return hash_update_s8(hash, tag->data.s8);
+ case TAG_S16: return hash_update_s16(hash, tag->data.s16);
+ case TAG_S32: return hash_update_s32(hash, tag->data.s32);
+ case TAG_S64: return hash_update_s64(hash, tag->data.s64);
+ case TAG_SW: return hash_update_sw(hash, tag->data.sw);
case TAG_STR: return hash_update_str(hash, &tag->data.str);
case TAG_STRUCT: return hash_update_struct(hash, &tag->data.struct_);
case TAG_STRUCT_TYPE:
@@ -509,15 +509,15 @@ bool hash_update_tag (t_hash *hash, const s_tag *tag)
case TAG_SYM: return hash_update_sym(hash, &tag->data.sym);
case TAG_TIME: return hash_update_time(hash, &tag->data.time);
case TAG_TUPLE: return hash_update_tuple(hash, &tag->data.tuple);
- case TAG_U8: return hash_update_u8(hash, &tag->data.u8);
- case TAG_U16: return hash_update_u16(hash, &tag->data.u16);
- case TAG_U32: return hash_update_u32(hash, &tag->data.u32);
- case TAG_U64: return hash_update_u64(hash, &tag->data.u64);
+ case TAG_U8: return hash_update_u8(hash, tag->data.u8);
+ case TAG_U16: return hash_update_u16(hash, tag->data.u16);
+ case TAG_U32: return hash_update_u32(hash, tag->data.u32);
+ case TAG_U64: return hash_update_u64(hash, tag->data.u64);
case TAG_UNQUOTE:
return hash_update_unquote(hash, &tag->data.unquote);
- case TAG_UW: return hash_update_uw(hash, &tag->data.uw);
+ case TAG_UW: return hash_update_uw(hash, tag->data.uw);
case TAG_VAR: return hash_update_var(hash, tag);
- case TAG_VOID: return hash_update_void(hash, tag);
+ case TAG_VOID: return hash_update_void(hash);
}
err_puts("hash_update_tag: unknown tag type");
assert(! "hash_update_tag: unknown tag type");
@@ -540,8 +540,8 @@ bool hash_update_time (t_hash *hash, const s_time *time)
return false;
return true;
}
- if (! hash_update_sw(hash, &time->tv_sec) ||
- ! hash_update_sw(hash, &time->tv_nsec))
+ if (! hash_update_sw(hash, time->tv_sec) ||
+ ! hash_update_sw(hash, time->tv_nsec))
return false;
return true;
}
@@ -588,11 +588,9 @@ bool hash_update_var (t_hash *hash, const s_tag *tag)
hash_update_sym(hash, &tag->data.var.type);
}
-bool hash_update_void (t_hash *hash, const s_tag *tag)
+bool hash_update_void (t_hash *hash)
{
char type[] = "void";
assert(hash);
- assert(tag);
- (void) tag;
return hash_update(hash, type, strlen(type));
}
diff --git a/libkc3/hash.h b/libkc3/hash.h
index cbf6d40..387ecc5 100644
--- a/libkc3/hash.h
+++ b/libkc3/hash.h
@@ -16,7 +16,7 @@
#include "types.h"
#define HASH_UPDATE_PROTOTYPE(type) \
- bool hash_update_##type (t_hash *hash, const type *x)
+ bool hash_update_##type (t_hash *hash, type x)
void hash_clean (t_hash *hash);
void hash_init (t_hash *hash);
@@ -28,11 +28,12 @@ bool hash_update_array (t_hash *hash, const s_array *a);
bool hash_update_block (t_hash *hash, const s_block *block);
bool hash_update_bool (t_hash *hash, const bool *b);
bool hash_update_call (t_hash *hash, const s_call *call);
+bool hash_update_callable (t_hash *hash, const s_callable *call);
bool hash_update_cfn (t_hash *hash, const s_cfn *cfn);
HASH_UPDATE_PROTOTYPE(char);
HASH_UPDATE_PROTOTYPE(character);
bool hash_update_complex (t_hash *hash, const s_complex *c);
-bool hash_update_cow (t_hash *hash, const s_cow *cow);
+bool hash_update_cow (t_hash *hash, s_cow *cow);
HASH_UPDATE_PROTOTYPE(f32);
HASH_UPDATE_PROTOTYPE(f64);
HASH_UPDATE_PROTOTYPE(f128);
@@ -66,6 +67,6 @@ HASH_UPDATE_PROTOTYPE(u64);
bool hash_update_unquote (t_hash *hash, const s_unquote *unquote);
HASH_UPDATE_PROTOTYPE(uw);
bool hash_update_var (t_hash *hash, const s_tag *tag);
-bool hash_update_void (t_hash *hash, const s_tag *tag);
+bool hash_update_void (t_hash *hash);
#endif /* LIBKC3_HASH_H */
diff --git a/libkc3/inspect.c b/libkc3/inspect.c
index 3712b47..c22c9d6 100644
--- a/libkc3/inspect.c
+++ b/libkc3/inspect.c
@@ -113,7 +113,7 @@ s_str * inspect_call (const s_call *call, s_str *dest)
return buf_to_str(&buf, dest);
}
-s_str * inspect_cow (const s_cow *cow, s_str *dest)
+s_str * inspect_cow (s_cow *cow, s_str *dest)
{
s_buf buf;
s_pretty pretty = {0};
diff --git a/libkc3/io.c b/libkc3/io.c
index 1e928f5..5e0c698 100644
--- a/libkc3/io.c
+++ b/libkc3/io.c
@@ -72,6 +72,16 @@ sw err_inspect_buf (const s_buf *buf)
return err_write(buf->ptr.pchar + pos, buf->rpos - pos);
}
+sw err_inspect_list (const s_list *x)
+{
+ sw r;
+ r = buf_inspect_list(&g_kc3_env.err, &x);
+ if (r < 0)
+ return r;
+ buf_flush(&g_kc3_env.err);
+ return r;
+}
+
sw err_inspect_tag_type (e_tag_type type)
{
return err_write_1(tag_type_to_string(type));
@@ -213,7 +223,6 @@ DEF_ERR_IO_INSPECT(fn_clause, const s_fn_clause *)
DEF_ERR_IO_INSPECT(fn_pattern, const s_list *)
DEF_ERR_IO_INSPECT(frame, const s_frame *)
DEF_ERR_IO_INSPECT(ident, const s_ident *)
-DEF_ERR_IO_INSPECT(list, const s_list * const *)
DEF_ERR_IO_INSPECT(map, const s_map *)
DEF_ERR_IO_INSPECT(pointer, const void *)
DEF_ERR_IO_INSPECT(ptr, const u_ptr_w *)
diff --git a/libkc3/io.h b/libkc3/io.h
index cf4bc1d..fd4dbab 100644
--- a/libkc3/io.h
+++ b/libkc3/io.h
@@ -60,7 +60,7 @@ PROTOTYPES_ERR_IO_INSPECT(fn_pattern, const s_list *);
PROTOTYPES_ERR_IO_INSPECT(frame, const s_frame *);
PROTOTYPES_ERR_IO_INSPECT(ident, const s_ident *);
PROTOTYPES_ERR_IO_INSPECT(integer, const s_integer *);
-PROTOTYPES_ERR_IO_INSPECT(list, const s_list * const *);
+PROTOTYPES_ERR_IO_INSPECT(list, const s_list *);
PROTOTYPES_ERR_IO_INSPECT(map, const s_map *);
PROTOTYPES_ERR_IO_INSPECT(pointer, const void *);
PROTOTYPES_ERR_IO_INSPECT(ptr, const u_ptr_w *);
diff --git a/libkc3/kc3.c b/libkc3/kc3.c
index 5824153..fa9015a 100644
--- a/libkc3/kc3.c
+++ b/libkc3/kc3.c
@@ -60,7 +60,7 @@ sw g_kc3_exit_code = 1;
void kc3_system_pipe_exec (s32 pipe_fd, char **argv,
const s_list * const *list);
-s_tag * kc3_access (const s_tag *tag, const s_list * const *key,
+s_tag * kc3_access (s_tag *tag, s_list **key,
s_tag *dest)
{
s_struct s = {0};
@@ -69,37 +69,36 @@ s_tag * kc3_access (const s_tag *tag, const s_list * const *key,
assert(dest);
switch (tag->type) {
case TAG_ARRAY:
- return array_access(&tag->data.array, key, dest);
+ return array_access(&tag->data.array, *key, dest);
case TAG_LIST:
- if (list_is_alist((const s_list * const *) &tag->data.list)) {
- if (! alist_access((const s_list * const *) &tag->data.list,
- key, dest))
+ if (list_is_alist(tag->data.list)) {
+ if (! alist_access(tag->data.list, *key, dest))
return tag_init_void(dest);
return dest;
}
break;
case TAG_MAP:
- return map_access(&tag->data.map, key, dest);
+ return map_access(&tag->data.map, *key, dest);
case TAG_STRUCT:
- return struct_access(&tag->data.struct_, key, dest);
+ return struct_access(&tag->data.struct_, *key, dest);
case TAG_TIME:
if (! struct_init_with_data(&s, &g_sym_Time,
(s_time *) &tag->data.time,
false))
return NULL;
- return struct_access(&s, key, dest);
+ return struct_access(&s, *key, dest);
default:
break;
}
err_write_1("kc3_access: cannot access tag type ");
err_write_1(tag_type_to_string(tag->type));
err_write_1(" for key ");
- err_inspect_list(key);
+ err_inspect_list(*key);
err_write_1("\n");
return NULL;
}
-bool * kc3_and (const s_tag *a, const s_tag *b, bool *dest)
+bool * kc3_and (s_tag *a, s_tag *b, bool *dest)
{
return env_and(&g_kc3_env, a, b, dest);
}
@@ -144,10 +143,10 @@ 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 *dest)
+ s_tag *symbol_value,
+ u8 operator_precedence,
+ const s_sym **operator_associativity,
+ s_tag *dest)
{
return env_defoperator(&g_kc3_env, name, sym, symbol_value,
operator_precedence,
@@ -236,9 +235,9 @@ 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);
}
-bool * kc3_facts_add_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+bool * kc3_facts_add_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest)
{
const s_fact *fact;
@@ -287,9 +286,9 @@ uw * kc3_facts_next_id (uw *dest)
return dest;
}
-bool * kc3_facts_remove_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+bool * kc3_facts_remove_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest)
{
bool b;
@@ -300,9 +299,9 @@ bool * kc3_facts_remove_tags (s_facts *facts, const s_tag *subject,
}
bool * kc3_facts_replace_tags (s_facts *facts,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+ s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest)
{
const s_fact *fact;
@@ -366,9 +365,14 @@ s_str * kc3_getenv (const s_str *name, s_str *dest)
return str_init_1(dest, NULL, p);
}
+s_tag * kc3_identity (s_tag *tag, s_tag *dest)
+{
+ return tag_init_copy(dest, tag);
+}
+
/* Special operator. */
-s_tag * kc3_if_then_else (const s_tag *cond, const s_tag *then,
- const s_tag *else_, s_tag *dest)
+s_tag * kc3_if_then_else (s_tag *cond, s_tag *then,
+ s_tag *else_, s_tag *dest)
{
bool cond_bool = false;
s_tag cond_eval = {0};
@@ -402,7 +406,7 @@ s_env * kc3_init (s_env *env, int *argc, char ***argv)
return env_init(env, argc, argv);
}
-s_tag * kc3_integer_reduce (const s_tag *tag, s_tag *dest)
+s_tag * kc3_integer_reduce (s_tag *tag, s_tag *dest)
{
s_tag tmp;
if (! tag_init_copy(&tmp, tag))
@@ -412,7 +416,7 @@ s_tag * kc3_integer_reduce (const s_tag *tag, s_tag *dest)
return dest;
}
-s_tag * kc3_let (const s_tag *vars, const s_tag *tag, s_tag *dest)
+s_tag * kc3_let (s_tag *vars, s_tag *tag, s_tag *dest)
{
return env_let(&g_kc3_env, vars, tag, dest);
}
@@ -448,7 +452,7 @@ uw * kc3_offsetof (const s_sym * const *module,
const s_sym * const *key, uw *dest)
{
uw i = 0;
- const s_struct_type *st;
+ s_struct_type *st;
if (! struct_type_find(*module, &st) ||
! st ||
! struct_type_find_key_index(st, *key, &i))
@@ -462,16 +466,11 @@ s_tag * kc3_operator_find_by_sym (const s_sym * const *sym, s_tag *dest)
return env_operator_find_by_sym(&g_kc3_env, *sym, dest);
}
-bool * kc3_or (const s_tag *a, const s_tag *b, bool *dest)
+bool * kc3_or (s_tag *a, s_tag *b, bool *dest)
{
return env_or(&g_kc3_env, a, b, dest);
}
-s_tag * kc3_identity (const s_tag *tag, s_tag *dest)
-{
- return tag_init_copy(dest, tag);
-}
-
sw kc3_puts (const s_tag *tag)
{
sw r;
@@ -531,8 +530,8 @@ s_str * kc3_strerror (sw err_no, s_str *dest)
return str_init_1_alloc(dest, s);
}
-s_tag * kc3_struct_put (const s_tag *s, const s_sym * const *key,
- const s_tag *value, s_tag *dest)
+s_tag * kc3_struct_put (s_tag *s, const s_sym * const *key,
+ s_tag *value, s_tag *dest)
{
s_struct tmp;
assert(s);
@@ -651,14 +650,14 @@ void kc3_system_pipe_exec (s32 pipe_w, char **argv,
execvp(argv[0], argv);
e = errno;
err_write_1("kc3_system: execvp ");
- err_inspect_list(list);
+ err_inspect_list(*list);
err_write_1(": ");
err_puts(strerror(e));
assert(! "kc3_system: execvp");
_exit(1);
}
-s_tag * kc3_while (const s_tag *cond, const s_tag *body, s_tag *dest)
+s_tag * kc3_while (s_tag *cond, s_tag *body, s_tag *dest)
{
return env_while(&g_kc3_env, cond, body, dest);
}
diff --git a/libkc3/kc3.h b/libkc3/kc3.h
index 60ea7f4..d53c154 100644
--- a/libkc3/kc3.h
+++ b/libkc3/kc3.h
@@ -39,6 +39,7 @@
#include "buf_rw.h"
#include "buf_save.h"
#include "call.h"
+#include "callable.h"
#include "ceiling.h"
#include "cfn.h"
#include "character.h"
diff --git a/libkc3/kc3_main.h b/libkc3/kc3_main.h
index 3bb6617..a345ceb 100644
--- a/libkc3/kc3_main.h
+++ b/libkc3/kc3_main.h
@@ -51,20 +51,17 @@ uw * kc3_offsetof (const s_sym * const *module,
sw kc3_puts (const s_tag *tag);
s_list ** kc3_stacktrace (s_list **dest);
s_str * kc3_str (const s_tag *tag, s_str *dest);
-s_tag * kc3_struct_put (const s_tag *s,
- const s_sym * const *key,
- const s_tag *value, s_tag *dest);
/* Operators. */
-s_tag * kc3_access (const s_tag *tag, const s_list * const *addr,
+s_tag * kc3_access (s_tag *tag, s_list **addr,
s_tag *dest);
-bool * kc3_and (const s_tag *a, const s_tag *b, bool *dest);
+bool * kc3_and (s_tag *a, s_tag *b, bool *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,
+ s_tag *symbol_value,
u8 operator_precedence,
const s_sym **operator_associativity,
s_tag *dest);
@@ -73,9 +70,9 @@ void ** kc3_dlopen (const s_str *path, void **dest);
s_facts ** kc3_env_db (s_facts **dest);
sw kc3_errno (void);
void kc3_exit (s_tag *code);
-bool * kc3_facts_add_tags (s_facts *facts, const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+bool * kc3_facts_add_tags (s_facts *facts, s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest);
s_tag * kc3_facts_collect_with (s_facts *facts, s_list **spec,
s_fn *callback, s_tag *dest);
@@ -91,14 +88,14 @@ s_tag * kc3_facts_first_with_tags (s_facts *facts, s_tag *subject,
s_tag *predicate, s_tag *object,
s_fn *callback, s_tag *dest);
bool * kc3_facts_remove_tags (s_facts *facts,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+ s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest);
bool * kc3_facts_replace_tags (s_facts *facts,
- const s_tag *subject,
- const s_tag *predicate,
- const s_tag *object,
+ s_tag *subject,
+ s_tag *predicate,
+ s_tag *object,
bool *dest);
s_tag * kc3_facts_with (s_facts *facts, s_list **spec,
s_fn *callback, s_tag *dest);
@@ -107,21 +104,23 @@ s_tag * kc3_facts_with_macro (s_tag *facts_tag, s_tag *spec_tag,
s_tag * kc3_facts_with_tags (s_facts *facts, s_tag *subject,
s_tag *predicate, s_tag *object,
s_fn *callback, s_tag *dest);
-s_tag * kc3_identity (const s_tag *tag, s_tag *dest);
-s_tag * kc3_integer_reduce (const s_tag *tag, s_tag *dest);
-s_tag * kc3_let (const s_tag *vars, const s_tag *tag, s_tag *dest);
+s_tag * kc3_identity (s_tag *tag, s_tag *dest);
+s_tag * kc3_integer_reduce (s_tag *tag, s_tag *dest);
+s_tag * kc3_let (s_tag *vars, s_tag *tag, s_tag *dest);
bool kc3_load (const s_str *path);
s_tag * kc3_operator_find_by_sym (const s_sym * const *sym,
s_tag *dest);
-bool * kc3_or (const s_tag *a, const s_tag *b, bool *dest);
+bool * kc3_or (s_tag *a, s_tag *b, bool *dest);
bool kc3_require (const s_sym * const *module);
s_str * kc3_strerror (sw err_no, s_str *dest);
+s_tag * kc3_struct_put (s_tag *s, const s_sym * const *key,
+ s_tag *value, s_tag *dest);
s_str * kc3_system (const s_list * const *list, s_str *dest);
/* Special operators. */
-s_tag * kc3_if_then_else (const s_tag *cond, const s_tag *then,
- const s_tag *else_, s_tag *dest);
-s_tag * kc3_while (const s_tag *cond, const s_tag *body, s_tag *dest);
+s_tag * kc3_if_then_else (s_tag *cond, s_tag *then,
+ s_tag *else_, s_tag *dest);
+s_tag * kc3_while (s_tag *cond, s_tag *body, s_tag *dest);
/* debug */
void kc3_break (void);
diff --git a/libkc3/list.c b/libkc3/list.c
index e2897cc..2efae1f 100644
--- a/libkc3/list.c
+++ b/libkc3/list.c
@@ -60,11 +60,11 @@ void list_f_clean (s_list **list)
l = list_delete(l);
}
-s_list ** list_filter (const s_list * const *list, const s_fn *f,
+s_list ** list_filter (s_list **list, s_callable *function,
s_list **dest)
{
s_list *arg;
- const s_list *l;
+ s_list *l;
s_list **tail;
s_list *tmp;
if (! (arg = list_new(NULL)))
@@ -76,7 +76,7 @@ s_list ** list_filter (const s_list * const *list, const s_fn *f,
if (! tag_copy(&arg->tag, &l->tag))
goto ko;
*tail = list_new(NULL);
- if (! eval_fn_call(f, arg, &(*tail)->tag))
+ if (! eval_callable_call(function, arg, &(*tail)->tag))
goto ko;
if ((*tail)->tag.type == TAG_VOID)
*tail = list_delete(*tail);
@@ -126,10 +126,10 @@ s_list * list_init_1 (s_list *list, const char *p, s_list *next)
return list;
}
-s_list ** list_init_append (s_list **list, const s_list * const *src,
- const s_tag *tag)
+s_list ** list_init_append (s_list **list, s_list **src,
+ s_tag *tag)
{
- const s_list *s;
+ s_list *s;
s_list *tmp;
s_list **tail;
tmp = NULL;
@@ -146,15 +146,14 @@ s_list ** list_init_append (s_list **list, const s_list * const *src,
}
s_list ** list_init_cast (s_list **list, const s_sym * const *type,
- const s_tag *tag)
+ s_tag *tag)
{
assert(list);
assert(type);
assert(tag);
switch (tag->type) {
case TAG_LIST:
- return list_init_copy(list,
- (const s_list * const *) &tag->data.list);
+ return list_init_copy(list, &tag->data.list);
default:
break;
}
@@ -171,7 +170,7 @@ s_list ** list_init_cast (s_list **list, const s_sym * const *type,
return NULL;
}
-s_list ** list_init_copy (s_list **list, const s_list * const *src)
+s_list ** list_init_copy (s_list **list, s_list **src)
{
s_list *tmp = NULL;
assert(src);
@@ -182,7 +181,7 @@ s_list ** list_init_copy (s_list **list, const s_list * const *src)
return list;
}
-s_list * list_init_tag_copy (s_list *list, const s_tag *tag, s_list *next)
+s_list * list_init_tag_copy (s_list *list, s_tag *tag, s_list *next)
{
assert(list);
assert(tag);
@@ -192,13 +191,13 @@ s_list * list_init_tag_copy (s_list *list, const s_tag *tag, s_list *next)
return list;
}
-bool list_is_alist (const s_list * const *list)
+bool list_is_alist (const s_list *list)
{
const s_list *l;
assert(list);
if (! list)
return false;
- l = *list;
+ l = list;
while (l) {
if (l->tag.type != TAG_TUPLE ||
l->tag.data.tuple.count != 2)
@@ -234,11 +233,11 @@ sw list_length (const s_list *list)
return length;
}
-s_list ** list_map (const s_list * const *list, const s_fn *f,
+s_list ** list_map (s_list **list, s_callable *function,
s_list **dest)
{
s_list *arg;
- const s_list *l;
+ s_list *l;
s_list **tail;
s_list *tmp;
if (! (arg = list_new(NULL)))
@@ -250,7 +249,7 @@ s_list ** list_map (const s_list * const *list, const s_fn *f,
if (! tag_copy(&arg->tag, &l->tag))
goto ko;
*tail = list_new(NULL);
- if (! eval_fn_call(f, arg, &(*tail)->tag))
+ if (! eval_callable_call(function, arg, &(*tail)->tag))
goto ko;
tail = &(*tail)->next.data.list;
l = list_next(l);
@@ -298,11 +297,11 @@ s_list * list_new_1 (const char *p)
}
/* FIXME: does not work on circular lists */
-s_list * list_new_copy (const s_list *src)
+s_list * list_new_copy (s_list *src)
{
s_list **i;
s_list *next;
- const s_list *s;
+ s_list *s;
s_list *list;
list = NULL;
i = &list;
@@ -339,7 +338,7 @@ s_list * list_new_list (s_list *x, s_list *next)
return dest;
}
-s_list * list_new_tag_copy (const s_tag *x, s_list *next)
+s_list * list_new_tag_copy (s_tag *x, s_list *next)
{
s_list *dest;
dest = list_new(next);
@@ -371,9 +370,9 @@ s_list ** list_remove_void (s_list **list)
return list;
}
-s_list ** list_sort (const s_list * const *list, s_list **dest)
+s_list ** list_sort (s_list **list, s_list **dest)
{
- const s_list *l;
+ s_list *l;
s_list *new_;
s_list *tmp;
s_list **t;
@@ -396,13 +395,13 @@ s_list ** list_sort (const s_list * const *list, s_list **dest)
return dest;
}
-s_list ** list_sort_by (const s_list * const *list, const s_fn *compare,
+s_list ** list_sort_by (s_list **list, s_callable *compare,
s_list **dest)
{
s_list *arg1;
s_list *arg2;
bool b;
- const s_list *l;
+ s_list *l;
s_list *new_;
const s_sym *sym_Bool = &g_sym_Bool;
s_list *tmp;
@@ -425,7 +424,7 @@ s_list ** list_sort_by (const s_list * const *list, const s_fn *compare,
goto ko;
if (! tag_init_copy(&arg2->tag, &l->tag))
goto ko;
- if (! eval_fn_call(compare, arg1, &tag))
+ if (! eval_callable_call(compare, arg1, &tag))
goto ko;
tag_void(&arg1->tag);
tag_void(&arg2->tag);
@@ -462,11 +461,11 @@ s_list ** list_tail (s_list **list)
return tail;
}
-s_array * list_to_array (const s_list *list, const s_sym *array_type,
+s_array * list_to_array (s_list *list, const s_sym *array_type,
s_array *dest)
{
s8 *data;
- const s_list *l;
+ s_list *l;
uw len;
bool must_clean;
uw size;
diff --git a/libkc3/list.h b/libkc3/list.h
index 8c25808..47e0c5d 100644
--- a/libkc3/list.h
+++ b/libkc3/list.h
@@ -26,13 +26,13 @@
void list_clean (s_list *list);
s_list * list_init (s_list *list, s_list *next);
s_list * list_init_1 (s_list *list, const char *p, s_list *next);
-s_list ** list_init_append (s_list **list, const s_list * const *src,
- const s_tag *tag);
+s_list ** list_init_append (s_list **list, s_list **src,
+ s_tag *tag);
s_list ** list_init_cast (s_list **list, const s_sym * const *type,
- const s_tag *tag);
-s_list ** list_init_copy (s_list **list, const s_list * const *src);
+ s_tag *tag);
+s_list ** list_init_copy (s_list **list, s_list **src);
s_list * list_init_eval (s_list *list, const char *p);
-s_list * list_init_tag_copy (s_list *list, const s_tag *tag,
+s_list * list_init_tag_copy (s_list *list, s_tag *tag,
s_list *next);
/* Heap-allocation functions, call list_delete after use */
@@ -41,30 +41,33 @@ void list_delete_all (s_list *list);
void list_f_clean (s_list **list);
s_list * list_new (s_list *next);
s_list * list_new_1 (const char *p);
-s_list * list_new_copy (const s_list *src);
+s_list * list_new_copy (s_list *src);
s_list * list_new_f64 (f64 x, s_list *next);
s_list * list_new_list (s_list *list, s_list *next);
s_list * list_new_map (uw count, s_list *next);
s_list * list_new_str_1 (char *free, const char *p, s_list *next);
-s_list * list_new_tag_copy (const s_tag *tag, s_list *next);
+s_list * list_new_tag_copy (s_tag *tag, s_list *next);
/* Observers */
s_list ** list_cast (const s_tag *tag, s_list **list);
bool * list_has (const s_list * const *list, const s_tag *tag,
bool *dest);
-bool list_is_alist (const s_list * const *list);
+bool list_is_alist (const s_list *list);
bool list_is_plist (const s_list *list);
sw list_length (const s_list *list);
-s_list ** list_map (const s_list * const *list, const s_fn *f,
- s_list **dest);
s_list * list_next (const s_list *list);
-s_list ** list_sort (const s_list * const *list, s_list **dest);
+s_list ** list_sort (s_list **list, s_list **dest);
s_list ** list_tail (s_list **list);
-s_array * list_to_array (const s_list *list, const s_sym *type,
- s_array *dest);
s_tuple * list_to_tuple_reverse (const s_list *list, s_tuple *dest);
/* Operators */
+s_list ** list_filter (s_list **list, s_callable *function,
+ s_list **dest);
+s_list ** list_map (s_list **list, s_callable *function, s_list **dest);
s_list ** list_remove_void (s_list **list);
+s_list ** list_sort_by (s_list **list, s_callable *compare,
+ s_list **dest);
+s_array * list_to_array (s_list *list, const s_sym *type,
+ s_array *dest);
#endif /* LIBKC3_LIST_H */
diff --git a/libkc3/list_init.c b/libkc3/list_init.c
index a8c241b..1558e7e 100644
--- a/libkc3/list_init.c
+++ b/libkc3/list_init.c
@@ -17,6 +17,7 @@
#include "buf_inspect.h"
#include "buf_parse.h"
#include "call.h"
+#include "callable.h"
#include "cfn.h"
#include "compare.h"
#include "env.h"
@@ -140,17 +141,6 @@ s_list * list_init_f128 (s_list *list, f128 f, s_list *next)
return list;
}
-s_list * list_init_fn_copy (s_list *list, const s_fn *fn, s_list *next)
-{
- s_list tmp = {0};
- assert(list);
- list_init(&tmp, next);
- if (! tag_init_fn_copy(&tmp.tag, fn))
- return NULL;
- *list = tmp;
- return list;
-}
-
s_list * list_init_ident (s_list *list, const s_ident *ident,
s_list *next)
{
@@ -789,19 +779,6 @@ s_list * list_new_f128 (f128 f, s_list *next)
return list;
}
-s_list * list_new_fn_copy (const s_fn *fn, s_list *next)
-{
- s_list *list;
- list = list_new(next);
- if (! list)
- return NULL;
- if (! tag_init_fn_copy(&list->tag, fn)) {
- free(list);
- return NULL;
- }
- return list;
-}
-
s_list * list_new_ident (const s_ident *ident, s_list *next)
{
s_list *list;
diff --git a/libkc3/list_init.h b/libkc3/list_init.h
index a30132b..295cc71 100644
--- a/libkc3/list_init.h
+++ b/libkc3/list_init.h
@@ -29,7 +29,6 @@ s_list * list_init_complex (s_list *list, s_complex *c, s_list *next);
s_list * list_init_f32 (s_list *list, f32 f, s_list *next);
s_list * list_init_f64 (s_list *list, f64 f, s_list *next);
s_list * list_init_f128 (s_list *list, f128 f, s_list *next);
-s_list * list_init_fn_copy (s_list *list, const s_fn *fn, s_list *next);
s_list * list_init_ident (s_list *list, const s_ident *ident,
s_list *next);
s_list * list_init_ident_1 (s_list *list, const char *p, s_list *next);
@@ -119,7 +118,6 @@ s_list * list_new_complex (s_complex *c, s_list *next);
s_list * list_new_f32 (f32 f, s_list *next);
s_list * list_new_f64 (f64 f, s_list *next);
s_list * list_new_f128 (f128 f, s_list *next);
-s_list * list_new_fn_copy (const s_fn *fn, s_list *next);
s_list * list_new_ident (const s_ident *ident, s_list *next);
s_list * list_new_ident_1 (const char *p, s_list *next);
s_list * list_new_integer_1 (const char *p, s_list *next);
diff --git a/libkc3/map.c b/libkc3/map.c
index 3ae6131..6f16f27 100644
--- a/libkc3/map.c
+++ b/libkc3/map.c
@@ -22,18 +22,18 @@
#include "map.h"
#include "tag.h"
-s_tag * map_access (const s_map *map, const s_list * const *key,
+s_tag * map_access (const s_map *map, s_list *key,
s_tag *dest)
{
- const s_tag *first;
- const s_list *next;
+ s_tag *first;
+ s_list *next;
s_tag *r;
s_tag tag;
assert(map);
assert(key);
assert(dest);
- first = &(*key)->tag;
- next = list_next(*key);
+ first = &key->tag;
+ next = list_next(key);
if (! next) {
if (! map_get(map, first, dest))
tag_init_void(dest);
@@ -205,14 +205,14 @@ s_map * map_init_copy (s_map *map, const s_map *src)
return NULL;
}
-s_map * map_init_from_alist (s_map *map, const s_list * const *alist)
+s_map * map_init_from_alist (s_map *map, s_list *alist)
{
sw i = 0;
- const s_list *a;
+ s_list *a;
sw len;
s_map tmp = {0};
assert(map);
- len = list_length(*alist);
+ len = list_length(alist);
if (! list_is_alist(alist)) {
err_write_1("map_init_from_alist: not an alist: ");
err_inspect_list(alist);
@@ -220,7 +220,7 @@ s_map * map_init_from_alist (s_map *map, const s_list * const *alist)
assert(! "map_init_from_alist: not an alist");
}
map_init(&tmp, len);
- a = *alist;
+ a = alist;
while (i < len) {
if (! tag_init_copy(tmp.key + i, a->tag.data.tuple.tag) ||
! tag_init_copy(tmp.value + i, a->tag.data.tuple.tag + 1))
@@ -237,14 +237,14 @@ s_map * map_init_from_alist (s_map *map, const s_list * const *alist)
return NULL;
}
-s_map * map_init_from_lists (s_map *map, const s_list *keys,
- const s_list *values)
+s_map * map_init_from_lists (s_map *map, s_list *keys,
+ s_list *values)
{
sw i = 0;
- const s_list *k;
+ s_list *k;
sw len;
s_map tmp = {0};
- const s_list *v;
+ s_list *v;
assert(map);
if ((len = list_length(keys)) != list_length(values)) {
err_puts("map_init_from_lists:"
diff --git a/libkc3/map.h b/libkc3/map.h
index 0c3d0b8..d70744f 100644
--- a/libkc3/map.h
+++ b/libkc3/map.h
@@ -21,8 +21,8 @@ s_map * map_init (s_map *map, uw count);
s_map * map_init_1 (s_map *map, const char *p);
s_map * map_init_cast (s_map *map, const s_tag *tag);
s_map * map_init_copy (s_map *map, const s_map *src);
-s_map * map_init_from_lists (s_map *map, const s_list *keys,
- const s_list *values);
+s_map * map_init_from_lists (s_map *map, s_list *keys, s_list *values);
+s_map * map_init_from_alist (s_map *map, s_list *alist);
/* Heap allocation functions, call map_delete after use. */
void map_delete (s_map *map);
@@ -34,7 +34,7 @@ s_map * map_new_from_lists (const s_list *keys, const s_list *values);
s_map * map_sort (s_map *map);
/* Observers. */
-s_tag * map_access (const s_map *map, const s_list * const *key,
+s_tag * map_access (const s_map *map, s_list *key,
s_tag *value);
s_map * map_cast (const s_tag *tag, s_map *map);
s_tag * map_get (const s_map *map, const s_tag *key,
diff --git a/libkc3/str.c b/libkc3/str.c
index 07e00ca..8f8a2f4 100644
--- a/libkc3/str.c
+++ b/libkc3/str.c
@@ -368,12 +368,10 @@ s_str * str_init_cast (s_str *str, const s_sym * const *type,
return str_init_array(str, &tag->data.array);
case TAG_BOOL:
return str_init_bool(str, tag->data.bool);
- case TAG_CFN:
- return str_init_cfn(str, &tag->data.cfn);
+ case TAG_CALLABLE:
+ return str_init_callable(str, tag->data.callable);
case TAG_CHARACTER:
return str_init_character(str, tag->data.character);
- case TAG_FN:
- return str_init_fn(str, &tag->data.fn);
case TAG_IDENT:
return str_init_ident(str, &tag->data.ident);
case TAG_LIST:
diff --git a/libkc3/str.h b/libkc3/str.h
index d87e350..06399e2 100644
--- a/libkc3/str.h
+++ b/libkc3/str.h
@@ -29,7 +29,7 @@
#define PROTOTYPE_STR_INIT(name, type) \
s_str * str_init_ ## name (s_str *str, type x)
-#define PROTOTYPE_STR_INIT_INT(type) \
+#define PROTOTYPE_STR_INIT_DIRECT(type) \
s_str * str_init_ ## type (s_str *str, type x)
#define PROTOTYPE_STR_INIT_STRUCT(type) \
@@ -55,7 +55,10 @@ s_str * str_init_copy (s_str *str, const s_str *src);
s_str * str_init_copy_1 (s_str *str, const char *p);
s_str * str_init_empty (s_str *str);
s_str * str_init_f (s_str *str, const char *fmt, ...);
-PROTOTYPE_STR_INIT_STRUCT(fn);
+PROTOTYPE_STR_INIT_DIRECT(f32);
+PROTOTYPE_STR_INIT_DIRECT(f64);
+PROTOTYPE_STR_INIT_DIRECT(f128);
+PROTOTYPE_STR_INIT(callable, s_callable *);
s_str * str_init_ftime (s_str *str, s_time *time, const s_str *format);
PROTOTYPE_STR_INIT_STRUCT(ident);
PROTOTYPE_STR_INIT(list, const s_list * const *);
@@ -63,10 +66,10 @@ PROTOTYPE_STR_INIT_STRUCT(map);
PROTOTYPE_STR_INIT(ptr, const u_ptr_w *);
PROTOTYPE_STR_INIT(ptr_free, const u_ptr_w *);
s_str * str_init_random_base64 (s_str *str, const s_tag *len);
-PROTOTYPE_STR_INIT_INT(s8);
-PROTOTYPE_STR_INIT_INT(s16);
-PROTOTYPE_STR_INIT_INT(s32);
-PROTOTYPE_STR_INIT_INT(s64);
+PROTOTYPE_STR_INIT_DIRECT(s8);
+PROTOTYPE_STR_INIT_DIRECT(s16);
+PROTOTYPE_STR_INIT_DIRECT(s32);
+PROTOTYPE_STR_INIT_DIRECT(s64);
s_str * str_init_slice (s_str *str, const s_str *src, sw start, sw end);
s_str * str_init_slice_utf8 (s_str *str, const s_str *src, sw start,
sw end);
@@ -75,15 +78,15 @@ s_str * str_init_subst (s_str *str, const s_str *src,
sw str_init_subst_size (const s_str *src, const s_str *search,
const s_str *replace);
PROTOTYPE_STR_INIT_STRUCT(struct);
-PROTOTYPE_STR_INIT_INT(sw);
+PROTOTYPE_STR_INIT_DIRECT(sw);
s_str * str_init_to_lower (s_str *str, const s_str *src);
s_str * str_init_to_upper (s_str *str, const s_str *src);
PROTOTYPE_STR_INIT_STRUCT(tuple);
-PROTOTYPE_STR_INIT_INT(u8);
-PROTOTYPE_STR_INIT_INT(u16);
-PROTOTYPE_STR_INIT_INT(u32);
-PROTOTYPE_STR_INIT_INT(u64);
-PROTOTYPE_STR_INIT_INT(uw);
+PROTOTYPE_STR_INIT_DIRECT(u8);
+PROTOTYPE_STR_INIT_DIRECT(u16);
+PROTOTYPE_STR_INIT_DIRECT(u32);
+PROTOTYPE_STR_INIT_DIRECT(u64);
+PROTOTYPE_STR_INIT_DIRECT(uw);
PROTOTYPE_STR_INIT_STRUCT(var);
s_str * str_init_vf (s_str *str, const char *fmt, va_list ap);
diff --git a/libkc3/struct.c b/libkc3/struct.c
index fdbb215..de5d805 100644
--- a/libkc3/struct.c
+++ b/libkc3/struct.c
@@ -26,18 +26,17 @@
#include "tag.h"
#include "tag_type.h"
-s_tag * struct_access (const s_struct *s, const s_list * const *key,
- s_tag *dest)
+s_tag * struct_access (s_struct *s, s_list *key, s_tag *dest)
{
- const s_tag *first;
- const s_list *next;
+ s_tag *first;
+ s_list *next;
s_tag *r;
s_tag tag;
assert(s);
assert(key);
assert(dest);
- first = &(*key)->tag;
- next = list_next(*key);
+ first = &key->tag;
+ next = list_next(key);
if (first->type != TAG_SYM) {
err_write_1("struct_access: key is not a Sym: (");
err_inspect_struct(s);
@@ -63,16 +62,16 @@ s_tag * struct_access (const s_struct *s, const s_list * const *key,
return r;
}
-s_tag * struct_access_sym (const s_struct *s, const s_sym *key, s_tag *dest)
+s_tag * struct_access_sym (s_struct *s, const s_sym *key, s_tag *dest)
{
- const void *data;
+ void *data;
const s_struct_type *st;
const s_sym *type;
s_tag tmp = {0};
void *tmp_data;
if (! struct_get_var_type(s, key, &type))
return NULL;
- data = struct_get(s, key);
+ data = struct_get_w(s, key);
if (! data)
return NULL;
if (type != &g_sym_Tag) {
@@ -198,6 +197,17 @@ const s_sym ** struct_get_var_type (const s_struct *s, const s_sym *key,
return map_get_var_type(&s->type->map, &tag_key, dest);
}
+void * struct_get_w (s_struct *s, const s_sym *key)
+{
+ uw i = 0;
+ assert(s);
+ assert(key);
+ if (! struct_find_key_index(s, key, &i))
+ return NULL;
+ assert(i < s->type->map.count);
+ return (u8 *) s->data + s->type->offset[i];
+}
+
s_struct * struct_init (s_struct *s, const s_sym *module)
{
s_struct tmp = {0};
@@ -451,8 +461,8 @@ uw * struct_offset (const s_struct *s, const s_sym * const *key,
return dest;
}
-s_struct * struct_put (const s_struct *s, const s_sym *key,
- const s_tag *value, s_struct *dest)
+s_struct * struct_put (s_struct *s, const s_sym *key,
+ s_tag *value, s_struct *dest)
{
s_struct tmp;
if (! struct_init_copy(&tmp, s)) {
@@ -469,10 +479,10 @@ s_struct * struct_put (const s_struct *s, const s_sym *key,
}
s_struct * struct_set (s_struct *s, const s_sym *key,
- const s_tag *value)
+ s_tag *value)
{
void *data;
- const void *data_src;
+ void *data_src;
uw i;
const s_sym *type_sym;
assert(s);
diff --git a/libkc3/struct.h b/libkc3/struct.h
index fb5b7b7..a9912b8 100644
--- a/libkc3/struct.h
+++ b/libkc3/struct.h
@@ -41,30 +41,31 @@ s_struct * struct_new_copy (const s_struct *src);
s_struct * struct_new_with_data (const s_sym *module, void *data);
/* Operators. */
+s_tag * struct_access (s_struct *s,
+ s_list *key,
+ s_tag *dest);
+s_tag * struct_access_sym (s_struct *s, const s_sym *key,
+ s_tag *dest);
s_struct * struct_allocate (s_struct *s);
+s_tag * struct_get_tag (s_struct *s, const s_sym *key);
+void * struct_get_w (s_struct *s, const s_sym *key);
+s_struct * struct_put (s_struct *s, const s_sym *key,
+ s_tag *value, s_struct *dest);
s_struct * struct_set (s_struct *s, const s_sym *key,
- const s_tag *value);
+ s_tag *value);
/* Observers. */
-s_tag * struct_access (const s_struct *s,
- const s_list * const *key,
- s_tag *dest);
-s_tag * struct_access_sym (const s_struct *s, const s_sym *key,
- s_tag *dest);
uw * struct_find_key_index (const s_struct *s,
const s_sym *key, uw *dest);
const void * struct_get (const s_struct *s, const s_sym *key);
const s_sym ** struct_get_type (const s_struct *s, const s_sym *key,
const s_sym **dest);
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);
-s_struct * struct_put (const s_struct *s, const s_sym *key,
- const s_tag *value, s_struct *dest);
#endif /* LIBKC3_STRUCT_H */
diff --git a/libkc3/struct_type.h b/libkc3/struct_type.h
index 48c243d..f57e593 100644
--- a/libkc3/struct_type.h
+++ b/libkc3/struct_type.h
@@ -43,15 +43,16 @@ void struct_type_delete (s_struct_type *st);
s_struct_type * struct_type_new (const s_sym *module,
const s_list *spec);
/* Observers. */
-void * struct_type_copy_data (const s_struct_type *st,
- void *dest,
- const void *src);
-bool * struct_type_exists (const s_sym *module,
- bool *dest);
-const s_struct_type ** struct_type_find (const s_sym *module,
- const s_struct_type **dest);
-uw * struct_type_find_key_index
-(const s_struct_type *st, const s_sym *key, uw *dest);
-uw struct_type_padding (uw offset, uw size);
+void * struct_type_copy_data (const s_struct_type *st,
+ void *dest,
+ const void *src);
+bool * struct_type_exists (const s_sym *module,
+ bool *dest);
+s_struct_type ** struct_type_find (const s_sym *module,
+ s_struct_type **dest);
+uw * struct_type_find_key_index (s_struct_type *st,
+ const s_sym *key,
+ uw *dest);
+uw struct_type_padding (uw offset, uw size);
#endif /* LIBKC3_STRUCT_TYPE_H */
diff --git a/libkc3/sym.c b/libkc3/sym.c
index ab696f1..66a491c 100644
--- a/libkc3/sym.c
+++ b/libkc3/sym.c
@@ -34,6 +34,7 @@ const s_sym g_sym_Bool = {{{NULL}, 4, {"Bool"}}};
const s_sym g_sym_Buf = {{{NULL}, 3, {"Buf"}}};
const s_sym g_sym_BufRW = {{{NULL}, 5, {"BufRW"}}};
const s_sym g_sym_Call = {{{NULL}, 4, {"Call"}}};
+const s_sym g_sym_Callable = {{{NULL}, 8, {"Callable"}}};
const s_sym g_sym_Cfn = {{{NULL}, 3, {"Cfn"}}};
const s_sym g_sym_Character = {{{NULL}, 9, {"Character"}}};
const s_sym g_sym_Char__star = {{{NULL}, 5, {"Char*"}}};
@@ -350,6 +351,7 @@ void sym_init_g_sym (void)
sym_register(&g_sym_Buf, NULL);
sym_register(&g_sym_BufRW, NULL);
sym_register(&g_sym_Call, NULL);
+ sym_register(&g_sym_Callable, NULL);
sym_register(&g_sym_Cfn, NULL);
sym_register(&g_sym_Character, NULL);
sym_register(&g_sym_Char__star, NULL);
@@ -551,7 +553,9 @@ bool * sym_must_clean (const s_sym *sym, bool *must_clean)
*must_clean = false;
return must_clean;
}
- if (sym == &g_sym_Cfn) {
+ if (sym == &g_sym_Callable ||
+ sym == &g_sym_Cfn ||
+ sym == &g_sym_Fn) {
*must_clean = true;
return must_clean;
}
@@ -579,10 +583,6 @@ bool * sym_must_clean (const s_sym *sym, bool *must_clean)
*must_clean = false;
return must_clean;
}
- if (sym == &g_sym_Fn) {
- *must_clean = true;
- return must_clean;
- }
if (sym == &g_sym_Integer) {
*must_clean = true;
return must_clean;
@@ -744,6 +744,12 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_pointer;
return true;
}
+ if (sym == &g_sym_Callable ||
+ sym == &g_sym_Cfn ||
+ sym == &g_sym_Fn) {
+ *dest = &ffi_type_pointer;
+ return true;
+ }
if (sym == &g_sym_Char__star) {
*dest = &ffi_type_pointer;
return true;
@@ -772,10 +778,6 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
*dest = &ffi_type_longdouble;
return true;
}
- if (sym == &g_sym_Fn) {
- *dest = &ffi_type_pointer;
- return true;
- }
if (sym == &g_sym_Integer) {
*dest = &ffi_type_pointer;
return true;
@@ -909,8 +911,10 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
*dest = TAG_CALL;
return true;
}
- if (sym == &g_sym_Cfn) {
- *dest = TAG_CFN;
+ if (sym == &g_sym_Callable ||
+ sym == &g_sym_Cfn ||
+ sym == &g_sym_Fn) {
+ *dest = TAG_CALLABLE;
return true;
}
if (sym == &g_sym_Character) {
@@ -937,10 +941,6 @@ bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
*dest = TAG_F128;
return true;
}
- if (sym == &g_sym_Fn) {
- *dest = TAG_FN;
- return true;
- }
if (sym == &g_sym_Ident) {
*dest = TAG_IDENT;
return true;
@@ -1086,8 +1086,10 @@ uw * sym_type_size (const s_sym * const *type, uw *dest)
*dest = sizeof(s_call);
return dest;
}
- if (*type == &g_sym_Cfn) {
- *dest = sizeof(s_cfn);
+ if (*type == &g_sym_Callable ||
+ *type == &g_sym_Cfn ||
+ *type == &g_sym_Fn) {
+ *dest = sizeof(p_callable);
return dest;
}
if (*type == &g_sym_Character) {
@@ -1118,10 +1120,6 @@ uw * sym_type_size (const s_sym * const *type, uw *dest)
*dest = sizeof(s_fact);
return dest;
}
- if (*type == &g_sym_Fn) {
- *dest = sizeof(s_fn);
- return dest;
- }
if (*type == &g_sym_Ident) {
*dest = sizeof(s_ident);
return dest;
diff --git a/libkc3/sym.h b/libkc3/sym.h
index 9646ec3..d66a86d 100644
--- a/libkc3/sym.h
+++ b/libkc3/sym.h
@@ -38,6 +38,7 @@ extern const s_sym g_sym_Bool;
extern const s_sym g_sym_Buf;
extern const s_sym g_sym_BufRW;
extern const s_sym g_sym_Call;
+extern const s_sym g_sym_Callable;
extern const s_sym g_sym_Cfn;
extern const s_sym g_sym_Character;
extern const s_sym g_sym_Char__star;
diff --git a/libkc3/tag.c b/libkc3/tag.c
index 32e737a..dd78d7f 100644
--- a/libkc3/tag.c
+++ b/libkc3/tag.c
@@ -21,6 +21,7 @@
#include "buf_inspect.h"
#include "buf_parse.h"
#include "call.h"
+#include "callable.h"
#include "cfn.h"
#include "compare.h"
#include "cow.h"
@@ -72,11 +73,16 @@ bool * tag_and (const s_tag *a, const s_tag *b, bool *dest)
s8 tag_arity (const s_tag *tag)
{
- switch (tag->type) {
- case TAG_CFN: return cfn_arity(&tag->data.cfn);
- case TAG_FN: return fn_arity(&tag->data.fn);
- default:
- break;
+ if (tag->type == TAG_CALLABLE &&
+ tag->data.callable) {
+ switch (tag->data.callable->type) {
+ case CALLABLE_CFN:
+ return cfn_arity(&tag->data.callable->data.cfn);
+ case CALLABLE_FN:
+ return fn_arity(&tag->data.callable->data.fn);
+ case CALLABLE_VOID:
+ break;
+ }
}
return -1;
}
@@ -203,10 +209,11 @@ void tag_clean (s_tag *tag)
case TAG_ARRAY: array_clean(&tag->data.array); break;
case TAG_BLOCK: block_clean(&tag->data.block); break;
case TAG_CALL: call_clean(&tag->data.call); break;
- case TAG_CFN: cfn_clean(&tag->data.cfn); break;
+ case TAG_CALLABLE:
+ p_callable_clean(&tag->data.callable);
+ break;
case TAG_COMPLEX: pcomplex_clean(&tag->data.complex); break;
case TAG_COW: pcow_clean(&tag->data.cow); break;
- case TAG_FN: fn_clean(&tag->data.fn); break;
case TAG_INTEGER: integer_clean(&tag->data.integer); break;
case TAG_LIST: list_delete_all(tag->data.list); break;
case TAG_MAP: map_clean(&tag->data.map); break;
@@ -418,7 +425,7 @@ s_tag * tag_init_cast_struct (s_tag *tag, const s_sym * const *type,
return NULL;
}
-s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
+s_tag * tag_init_copy (s_tag *tag, s_tag *src)
{
assert(tag);
assert(src);
@@ -442,9 +449,10 @@ s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
if (! call_init_copy(&tag->data.call, &src->data.call))
return NULL;
return tag;
- case TAG_CFN:
+ case TAG_CALLABLE:
tag->type = src->type;
- if (! cfn_init_copy(&tag->data.cfn, &src->data.cfn))
+ if (! p_callable_init_copy(&tag->data.callable,
+ &src->data.callable))
return NULL;
return tag;
case TAG_CHARACTER:
@@ -479,11 +487,6 @@ s_tag * tag_init_copy (s_tag *tag, const s_tag *src)
tag->type = src->type;
tag->data.fact = src->data.fact;
return tag;
- case TAG_FN:
- tag->type = src->type;
- if (! fn_init_copy(&tag->data.fn, &src->data.fn))
- return NULL;
- return tag;
case TAG_IDENT:
tag->type = src->type;
tag->data.ident = src->data.ident;
@@ -803,10 +806,9 @@ bool tag_is_number (const s_tag *tag)
case TAG_BLOCK:
case TAG_BOOL:
case TAG_CALL:
- case TAG_CFN:
+ case TAG_CALLABLE:
case TAG_CHARACTER:
case TAG_FACT:
- case TAG_FN:
case TAG_LIST:
case TAG_MAP:
case TAG_PTAG:
@@ -1053,8 +1055,8 @@ uw * tag_size (const s_tag *tag, uw *dest)
return dest;
}
-bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
- const void **dest)
+bool tag_to_const_pointer (s_tag *tag, const s_sym *type,
+ void **dest)
{
e_tag_type tag_type;
if (type == &g_sym_Tag) {
@@ -1076,7 +1078,7 @@ bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
case TAG_BLOCK: *dest = &tag->data.block; return true;
case TAG_BOOL: *dest = &tag->data.bool; return true;
case TAG_CALL: *dest = &tag->data.call; return true;
- case TAG_CFN: *dest = &tag->data.cfn; return true;
+ case TAG_CALLABLE: *dest = &tag->data.callable; return true;
case TAG_CHARACTER: *dest = &tag->data.character; return true;
case TAG_COMPLEX: *dest = &tag->data.complex; return true;
case TAG_COW: *dest = &tag->data.cow; return true;
@@ -1084,7 +1086,6 @@ bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
case TAG_F64: *dest = &tag->data.f64; return true;
case TAG_F128: *dest = &tag->data.f128; return true;
case TAG_FACT: *dest = &tag->data.fact; return true;
- case TAG_FN: *dest = &tag->data.fn; return true;
case TAG_IDENT: *dest = &tag->data.ident; return true;
case TAG_INTEGER: *dest = &tag->data.integer; return true;
case TAG_SW: *dest = &tag->data.sw; return true;
@@ -1167,9 +1168,15 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
return true;
}
goto invalid_cast;
- case TAG_CFN:
- if (type == &g_sym_Cfn) {
- *dest = &tag->data.cfn;
+ case TAG_CALLABLE:
+ if (type == &g_sym_Callable ||
+ (type == &g_sym_Cfn &&
+ tag->data.callable &&
+ tag->data.callable->type == CALLABLE_CFN) ||
+ (type == &g_sym_Fn &&
+ tag->data.callable
+ tag->data.callable->type == CALLABLE_FN)) {
+ *dest = &tag->data.callable;
return true;
}
goto invalid_cast;
@@ -1216,12 +1223,6 @@ bool tag_to_ffi_pointer (s_tag *tag, const s_sym *type, void **dest)
return true;
}
goto invalid_cast;
- case TAG_FN:
- if (type == &g_sym_Fn) {
- *dest = &tag->data.fn;
- return true;
- }
- goto invalid_cast;
case TAG_IDENT:
if (type == &g_sym_Ident) {
*dest = &tag->data.ident;
@@ -1450,7 +1451,7 @@ bool tag_to_pointer (s_tag *tag, const s_sym *type, void **dest)
case TAG_BLOCK: *dest = &tag->data.block; return true;
case TAG_BOOL: *dest = &tag->data.bool; return true;
case TAG_CALL: *dest = &tag->data.call; return true;
- case TAG_CFN: *dest = &tag->data.cfn; return true;
+ case TAG_CALLABLE: *dest = &tag->data.callable; return true;
case TAG_CHARACTER: *dest = &tag->data.character; return true;
case TAG_COMPLEX: *dest = &tag->data.complex; return true;
case TAG_COW: *dest = &tag->data.cow; return true;
@@ -1458,7 +1459,6 @@ bool tag_to_pointer (s_tag *tag, const s_sym *type, void **dest)
case TAG_F64: *dest = &tag->data.f64; return true;
case TAG_F128: *dest = &tag->data.f128; return true;
case TAG_FACT: *dest = &tag->data.fact; return true;
- case TAG_FN: *dest = &tag->data.fn; return true;
case TAG_IDENT: *dest = &tag->data.ident; return true;
case TAG_INTEGER: *dest = &tag->data.integer; return true;
case TAG_LIST: *dest = &tag->data.list; return true;
@@ -1518,50 +1518,61 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
assert(tag);
assert(dest);
switch (tag->type) {
- case TAG_VOID: *dest = &g_sym_Void; return dest;
+ case TAG_VOID: *dest = &g_sym_Void; return dest;
case TAG_ARRAY:
*dest = tag->data.array.array_type;
return dest;
- case TAG_BLOCK: *dest = &g_sym_Block; return dest;
- case TAG_BOOL: *dest = &g_sym_Bool; return dest;
- case TAG_CALL: *dest = &g_sym_Call; return dest;
- case TAG_CFN: *dest = &g_sym_Cfn; return dest;
- case TAG_CHARACTER: *dest = &g_sym_Character; return dest;
- case TAG_COMPLEX: *dest = &g_sym_Complex; return dest;
- case TAG_COW: *dest = &g_sym_Cow; return dest;
- case TAG_F32: *dest = &g_sym_F32; return dest;
- case TAG_F64: *dest = &g_sym_F64; return dest;
- case TAG_F128: *dest = &g_sym_F128; return dest;
- case TAG_FACT: *dest = &g_sym_Fact; return dest;
- case TAG_FN: *dest = &g_sym_Fn; return dest;
- case TAG_IDENT: *dest = &g_sym_Ident; return dest;
- case TAG_INTEGER: *dest = &g_sym_Integer; return dest;
- case TAG_SW: *dest = &g_sym_Sw; return dest;
- case TAG_S64: *dest = &g_sym_S64; return dest;
- case TAG_S32: *dest = &g_sym_S32; return dest;
- case TAG_S16: *dest = &g_sym_S16; return dest;
- case TAG_S8: *dest = &g_sym_S8; return dest;
- case TAG_U8: *dest = &g_sym_U8; return dest;
- case TAG_U16: *dest = &g_sym_U16; return dest;
- case TAG_U32: *dest = &g_sym_U32; return dest;
- case TAG_U64: *dest = &g_sym_U64; return dest;
- case TAG_UW: *dest = &g_sym_Uw; return dest;
- case TAG_LIST: *dest = &g_sym_List; return dest;
- case TAG_MAP: *dest = &g_sym_Map; return dest;
- case TAG_PTAG: *dest = &g_sym_Ptag; return dest;
- case TAG_PTR: *dest = &g_sym_Ptr; return dest;
- case TAG_PTR_FREE: *dest = &g_sym_PtrFree; return dest;
- case TAG_QUOTE: *dest = &g_sym_Quote; return dest;
- case TAG_RATIO: *dest = &g_sym_Ratio; return dest;
- case TAG_STR: *dest = &g_sym_Str; return dest;
- case TAG_STRUCT: *dest = tag->data.struct_.type->module;
- return dest;
- case TAG_STRUCT_TYPE: *dest = &g_sym_StructType; return dest;
- case TAG_SYM: *dest = &g_sym_Sym; return dest;
- case TAG_TIME: *dest = &g_sym_Time; return dest;
- case TAG_TUPLE: *dest = &g_sym_Tuple; return dest;
- case TAG_UNQUOTE: *dest = &g_sym_Unquote; return dest;
- case TAG_VAR: *dest = &g_sym_Var; return dest;
+ case TAG_BLOCK: *dest = &g_sym_Block; return dest;
+ case TAG_BOOL: *dest = &g_sym_Bool; return dest;
+ case TAG_CALL: *dest = &g_sym_Call; return dest;
+ case TAG_CALLABLE:
+ if (tag->data.callable) {
+ switch (tag->data.callable->type) {
+ case CALLABLE_FN: *dest = &g_sym_Fn; return dest;
+ case CALLABLE_CFN: *dest = &g_sym_Cfn; return dest;
+ case CALLABLE_VOID:
+ err_puts("tag_type: CALLABLE_VOID");
+ assert(! "tag_type: CALLABLE_VOID");
+ return NULL;
+ }
+ }
+ *dest = &g_sym_Callable;
+ return dest;
+ case TAG_CHARACTER: *dest = &g_sym_Character; return dest;
+ case TAG_COMPLEX: *dest = &g_sym_Complex; return dest;
+ case TAG_COW: *dest = &g_sym_Cow; return dest;
+ case TAG_F32: *dest = &g_sym_F32; return dest;
+ case TAG_F64: *dest = &g_sym_F64; return dest;
+ case TAG_F128: *dest = &g_sym_F128; return dest;
+ case TAG_FACT: *dest = &g_sym_Fact; return dest;
+ case TAG_IDENT: *dest = &g_sym_Ident; return dest;
+ case TAG_INTEGER: *dest = &g_sym_Integer; return dest;
+ case TAG_SW: *dest = &g_sym_Sw; return dest;
+ case TAG_S64: *dest = &g_sym_S64; return dest;
+ case TAG_S32: *dest = &g_sym_S32; return dest;
+ case TAG_S16: *dest = &g_sym_S16; return dest;
+ case TAG_S8: *dest = &g_sym_S8; return dest;
+ case TAG_U8: *dest = &g_sym_U8; return dest;
+ case TAG_U16: *dest = &g_sym_U16; return dest;
+ case TAG_U32: *dest = &g_sym_U32; return dest;
+ case TAG_U64: *dest = &g_sym_U64; return dest;
+ case TAG_UW: *dest = &g_sym_Uw; return dest;
+ case TAG_LIST: *dest = &g_sym_List; return dest;
+ case TAG_MAP: *dest = &g_sym_Map; return dest;
+ case TAG_PTAG: *dest = &g_sym_Ptag; return dest;
+ case TAG_PTR: *dest = &g_sym_Ptr; return dest;
+ case TAG_PTR_FREE: *dest = &g_sym_PtrFree; return dest;
+ case TAG_QUOTE: *dest = &g_sym_Quote; return dest;
+ case TAG_RATIO: *dest = &g_sym_Ratio; return dest;
+ case TAG_STR: *dest = &g_sym_Str; return dest;
+ case TAG_STRUCT: *dest = tag->data.struct_.type->module;
+ return dest;
+ case TAG_STRUCT_TYPE: *dest = &g_sym_StructType; return dest;
+ case TAG_SYM: *dest = &g_sym_Sym; return dest;
+ case TAG_TIME: *dest = &g_sym_Time; return dest;
+ case TAG_TUPLE: *dest = &g_sym_Tuple; return dest;
+ case TAG_UNQUOTE: *dest = &g_sym_Unquote; return dest;
+ case TAG_VAR: *dest = &g_sym_Var; return dest;
}
err_puts("tag_type: invalid tag type");
assert(! "tag_type: invalid tag type");
diff --git a/libkc3/tag.h b/libkc3/tag.h
index aaaa71a..57986f4 100644
--- a/libkc3/tag.h
+++ b/libkc3/tag.h
@@ -55,7 +55,7 @@ bool tag_is_struct (const s_tag *tag, const s_sym *module);
bool * tag_is_unbound_var (const s_tag *tag, bool *dest);
bool tag_is_zero(const s_tag *tag);
s8 tag_number_compare (const s_tag *a, const s_tag *b);
-const s_tag * tag_resolve_cow (const s_tag *tag);
+s_tag * tag_resolve_cow (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);
@@ -73,8 +73,8 @@ s_tag * tag_integer_cast_to_u64 (const s_tag *tag, s_tag *dest);
s_tag * tag_integer_cast_to_u8 (const s_tag *tag, s_tag *dest);
s_tag * tag_integer_reduce (s_tag *tag);
s_tag * tag_list_1 (s_tag *tag, const char *p);
-bool tag_to_const_pointer (const s_tag *tag, const s_sym *type,
- const void **dest);
+bool tag_to_const_pointer (s_tag *tag, const s_sym *type,
+ void **dest);
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);
diff --git a/libkc3/tag_init.c b/libkc3/tag_init.c
index 3a47dd6..ab336d8 100644
--- a/libkc3/tag_init.c
+++ b/libkc3/tag_init.c
@@ -17,6 +17,7 @@
#include "buf_inspect.h"
#include "buf_parse.h"
#include "call.h"
+#include "callable.h"
#include "cfn.h"
#include "compare.h"
#include "env.h"
@@ -135,17 +136,6 @@ s_tag * tag_init_f128 (s_tag *tag, f128 f)
return tag;
}
-s_tag * tag_init_fn_copy (s_tag *tag, const s_fn *fn)
-{
- s_tag tmp = {0};
- assert(tag);
- tmp.type = TAG_FN;
- if (! fn_init_copy(&tmp.data.fn, fn))
- return NULL;
- *tag = tmp;
- return tag;
-}
-
s_tag * tag_init_ident (s_tag *tag, const s_ident *ident)
{
s_tag tmp = {0};
@@ -757,20 +747,6 @@ s_tag * tag_new_f128 (f128 f)
return tag;
}
-s_tag * tag_new_fn_copy (const s_fn *fn)
-{
- s_tag *tag;
- tag = alloc(sizeof(s_tag));
- if (! tag)
- return NULL;
- tag->type = TAG_FN;
- if (! fn_init_copy(&tag->data.fn, fn)) {
- free(tag);
- return NULL;
- }
- return tag;
-}
-
s_tag * tag_new_ident (const s_ident *ident)
{
s_tag *tag;
@@ -1484,18 +1460,6 @@ s_tag * tag_f128 (s_tag *tag, f128 f)
return tag;
}
-s_tag * tag_fn_copy (s_tag *tag, const s_fn *fn)
-{
- s_tag tmp = {0};
- assert(tag);
- tag_clean(tag);
- tmp.type = TAG_FN;
- if (! fn_init_copy(&tmp.data.fn, fn))
- return NULL;
- *tag = tmp;
- return tag;
-}
-
s_tag * tag_ident (s_tag *tag, const s_ident *ident)
{
s_tag tmp = {0};
diff --git a/libkc3/tag_init.h b/libkc3/tag_init.h
index 76c81d4..8f10847 100644
--- a/libkc3/tag_init.h
+++ b/libkc3/tag_init.h
@@ -22,12 +22,11 @@ s_tag * tag_init_array_copy (s_tag *tag, const s_array *a);
s_tag * tag_init_bool (s_tag *tag, bool b);
s_tag * tag_init_call (s_tag *tag);
s_tag * tag_init_character (s_tag *tag, character c);
-s_tag * tag_init_copy (s_tag *tag, const s_tag *src);
+s_tag * tag_init_copy (s_tag *tag, s_tag *src);
s_tag * tag_init_complex (s_tag *tag, s_complex *c);
s_tag * tag_init_f32 (s_tag *tag, f32 f);
s_tag * tag_init_f64 (s_tag *tag, f64 f);
s_tag * tag_init_f128 (s_tag *tag, f128 f);
-s_tag * tag_init_fn_copy (s_tag *tag, const s_fn *fn);
s_tag * tag_init_ident (s_tag *tag, const s_ident *ident);
s_tag * tag_init_ident_1 (s_tag *tag, const char *p);
s_tag * tag_init_integer_1 (s_tag *tag, const char *p);
@@ -94,12 +93,11 @@ s_tag * tag_new_array_copy (const s_array *a);
s_tag * tag_new_bool (bool b);
s_tag * tag_new_call (void);
s_tag * tag_new_character (character c);
-s_tag * tag_new_copy (const s_tag *src);
+s_tag * tag_new_copy (s_tag *src);
s_tag * tag_new_complex (s_complex *c);
s_tag * tag_new_f32 (f32 f);
s_tag * tag_new_f64 (f64 f);
s_tag * tag_new_f128 (f128 f);
-s_tag * tag_new_fn_copy (const s_fn *fn);
s_tag * tag_new_ident (const s_ident *ident);
s_tag * tag_new_ident_1 (const char *p);
s_tag * tag_new_integer_1 (const char *p);
@@ -160,12 +158,11 @@ s_tag * tag_array_copy (s_tag *tag, const s_array *a);
s_tag * tag_bool (s_tag *tag, bool b);
s_tag * tag_call (s_tag *tag);
s_tag * tag_character (s_tag *tag, character c);
-s_tag * tag_copy (s_tag *tag, const s_tag *src);
+s_tag * tag_copy (s_tag *tag, s_tag *src);
s_tag * tag_complex (s_tag *tag, s_complex *c);
s_tag * tag_f32 (s_tag *tag, f32 f);
s_tag * tag_f64 (s_tag *tag, f64 f);
s_tag * tag_f128 (s_tag *tag, f128 f);
-s_tag * tag_fn_copy (s_tag *tag, const s_fn *fn);
s_tag * tag_ident (s_tag *tag, const s_ident *ident);
s_tag * tag_ident_1 (s_tag *tag, const char *p);
s_tag * tag_integer_1 (s_tag *tag, const char *p);
diff --git a/libkc3/tag_init.rb b/libkc3/tag_init.rb
index 81fe094..a25da5d 100644
--- a/libkc3/tag_init.rb
+++ b/libkc3/tag_init.rb
@@ -304,7 +304,7 @@ class TagInitList
TagInit.new("character", "TAG_CHARACTER", :init_mode_direct,
[Arg.new("character", "c")]),
TagInitProto.new("copy", nil, :init_mode_none,
- [Arg.new("const s_tag *", "src")]),
+ [Arg.new("s_tag *", "src")]),
TagInit.new("complex", "TAG_COMPLEX", :init_mode_direct,
[Arg.new("s_complex *", "c")]),
TagInit.new("f32", "TAG_F32", :init_mode_direct,
@@ -313,8 +313,8 @@ class TagInitList
[Arg.new("f64", "f")]),
TagInit.new("f128", "TAG_F128", :init_mode_direct,
[Arg.new("f128", "f")]),
- TagInit.new("fn", "copy", "TAG_FN", :init_mode_init,
- [Arg.new("const s_fn *", "fn")]),
+ #TagInit.new("fn", "copy", "TAG_FN", :init_mode_init,
+ # [Arg.new("const s_fn *", "fn")]),
TagInit.new("ident", "TAG_IDENT", :init_mode_direct,
[Arg.new("const s_ident *", "ident")]),
TagInit1.new("ident", "1", "TAG_IDENT", :init_mode_init),
@@ -530,6 +530,7 @@ tag_init_c.content = <<EOF
#include "buf_inspect.h"
#include "buf_parse.h"
#include "call.h"
+#include "callable.h"
#include "cfn.h"
#include "compare.h"
#include "env.h"
@@ -585,6 +586,7 @@ list_init_c.content = <<EOF
#include "buf_inspect.h"
#include "buf_parse.h"
#include "call.h"
+#include "callable.h"
#include "cfn.h"
#include "compare.h"
#include "env.h"
diff --git a/libkc3/tag_type.c b/libkc3/tag_type.c
index 681e075..38e24cc 100644
--- a/libkc3/tag_type.c
+++ b/libkc3/tag_type.c
@@ -25,7 +25,7 @@ bool tag_type_size (e_tag_type type, uw *dest)
case TAG_BLOCK: *dest = sizeof(s_block); return true;
case TAG_BOOL: *dest = sizeof(bool); return true;
case TAG_CALL: *dest = sizeof(s_call); return true;
- case TAG_CFN: *dest = sizeof(s_cfn); return true;
+ case TAG_CALLABLE: *dest = sizeof(p_callable); return true;
case TAG_CHARACTER: *dest = sizeof(character); return true;
case TAG_COMPLEX: *dest = sizeof(s_complex *); return true;
case TAG_COW: *dest = sizeof(s_cow *); return true;
@@ -33,7 +33,6 @@ bool tag_type_size (e_tag_type type, uw *dest)
case TAG_F64: *dest = sizeof(f64); return true;
case TAG_F128: *dest = sizeof(f128); return true;
case TAG_FACT: *dest = sizeof(s_fact); return true;
- case TAG_FN: *dest = sizeof(s_fn); return true;
case TAG_IDENT: *dest = sizeof(s_ident); return true;
case TAG_INTEGER: *dest = sizeof(s_integer); return true;
case TAG_SW: *dest = sizeof(sw); return true;
@@ -74,7 +73,7 @@ bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
case TAG_BLOCK: *dest = &ffi_type_pointer; return true;
case TAG_BOOL: *dest = &ffi_type_uint8; return true;
case TAG_CALL: *dest = &ffi_type_pointer; return true;
- case TAG_CFN: *dest = &ffi_type_pointer; return true;
+ case TAG_CALLABLE: *dest = &ffi_type_pointer; return true;
case TAG_CHARACTER: *dest = &ffi_type_uint32; return true;
case TAG_COMPLEX: *dest = &ffi_type_pointer; return true;
case TAG_COW: *dest = &ffi_type_pointer; return true;
@@ -82,7 +81,6 @@ bool tag_type_to_ffi_type (e_tag_type type, ffi_type **dest)
case TAG_F64: *dest = &ffi_type_double; return true;
case TAG_F128: *dest = &ffi_type_longdouble; return true;
case TAG_FACT: *dest = &ffi_type_pointer; return true;
- case TAG_FN: *dest = &ffi_type_pointer; return true;
case TAG_IDENT: *dest = &ffi_type_pointer; return true;
case TAG_INTEGER: *dest = &ffi_type_pointer; return true;
case TAG_LIST: *dest = &ffi_type_pointer; return true;
@@ -125,7 +123,7 @@ const char * tag_type_to_string (e_tag_type tag_type)
case TAG_BLOCK: return "Block";
case TAG_BOOL: return "Bool";
case TAG_CALL: return "Call";
- case TAG_CFN: return "Cfn";
+ case TAG_CALLABLE: return "Callable";
case TAG_CHARACTER: return "Character";
case TAG_COMPLEX: return "Complex";
case TAG_COW: return "Cow";
@@ -133,7 +131,6 @@ const char * tag_type_to_string (e_tag_type tag_type)
case TAG_F64: return "F64";
case TAG_F128: return "F128";
case TAG_FACT: return "Fact";
- case TAG_FN: return "Fn";
case TAG_IDENT: return "Ident";
case TAG_INTEGER: return "Integer";
case TAG_SW: return "Sw";
diff --git a/libkc3/types.h b/libkc3/types.h
index ea77d6c..709d105 100644
--- a/libkc3/types.h
+++ b/libkc3/types.h
@@ -85,6 +85,12 @@ typedef enum {
} e_bool;
typedef enum {
+ CALLABLE_VOID = 0,
+ CALLABLE_CFN,
+ CALLABLE_FN
+} e_callable_type;
+
+typedef enum {
FACT_ACTION_ADD,
FACT_ACTION_REMOVE,
FACT_ACTION_REPLACE
@@ -96,7 +102,7 @@ typedef enum {
TAG_BLOCK,
TAG_BOOL,
TAG_CALL,
- TAG_CFN,
+ TAG_CALLABLE,
TAG_CHARACTER,
TAG_COMPLEX,
TAG_COW,
@@ -104,7 +110,6 @@ typedef enum {
TAG_F64,
TAG_F128,
TAG_FACT,
- TAG_FN,
TAG_INTEGER,
TAG_RATIO,
TAG_SW,
@@ -145,6 +150,7 @@ typedef struct buf_fd s_buf_fd;
typedef struct buf_rw s_buf_rw;
typedef struct buf_save s_buf_save;
typedef struct call s_call;
+typedef struct callable s_callable;
typedef struct cfn s_cfn;
typedef struct complex s_complex;
typedef struct cow s_cow;
@@ -195,19 +201,20 @@ typedef struct unwind_protect s_unwind_protect;
typedef struct var s_var;
/* unions */
-typedef union ptr_ u_ptr;
-typedef union ptr_w u_ptr_w;
-typedef union tag_data u_tag_data;
-typedef union tag_type u_tag_type;
+typedef union callable_data u_callable_data;
+typedef union ptr_ u_ptr;
+typedef union ptr_w u_ptr_w;
+typedef union tag_data u_tag_data;
/* typedefs */
-typedef u32 character;
-typedef s_tag **p_facts_spec;
-typedef s_tag *t_facts_spec[];
-typedef SHA1_CTX t_hash;
-typedef const s_sym *p_sym;
-typedef const s_tag *p_tag;
-typedef u64 t_skiplist_height;
+typedef s_callable * p_callable;
+typedef u32 character;
+typedef s_tag ** p_facts_spec;
+typedef s_tag * t_facts_spec[];
+typedef SHA1_CTX t_hash;
+typedef const s_sym *p_sym;
+typedef const s_tag *p_tag;
+typedef u64 t_skiplist_height;
/* function typedefs */
typedef void (* f_clean) (void *x);
@@ -249,9 +256,9 @@ struct cow {
};
struct fact {
- const s_tag *subject;
- const s_tag *predicate;
- const s_tag *object;
+ s_tag *subject;
+ s_tag *predicate;
+ s_tag *object;
uw id; /* serial id */
};
@@ -322,7 +329,7 @@ struct struct_ {
void *data;
bool free_data;
s_tag *tag;
- const s_struct_type *type;
+ s_struct_type *type;
};
struct sym_list {
@@ -382,7 +389,7 @@ struct buf {
struct facts_spec_cursor {
p_facts_spec spec;
- const s_tag *subject;
+ s_tag *subject;
uw pos;
};
@@ -434,15 +441,14 @@ struct buf_rw {
};
struct call {
- /* key */
s_ident ident;
s_list *arguments;
- /* value */
- s_cfn *cfn;
- s_fn *fn;
+ p_callable callable;
};
struct cfn {
+ bool macro;
+ bool special_operator;
const s_sym *name;
union {
void (*f) (void);
@@ -453,15 +459,14 @@ struct cfn {
bool arg_result;
s_list *arg_types;
ffi_cif cif;
- bool macro;
- bool special_operator;
+ bool ready;
};
struct fn {
- s_fn_clause *clauses;
bool macro;
bool special_operator;
s_ident ident;
+ s_fn_clause *clauses;
const s_sym *module;
s_frame *frame;
};
@@ -499,14 +504,25 @@ struct array {
const s_sym *element_type;
};
+union callable_data {
+ s_cfn cfn;
+ s_fn fn;
+};
+
/* 5 */
+struct callable {
+ e_callable_type type;
+ sw reference_count;
+ u_callable_data data;
+};
+
union tag_data {
s_array array;
s_block block;
bool bool;
s_call call;
- s_cfn cfn;
+ p_callable callable;
character character;
s_complex *complex;
s_cow *cow;
@@ -514,7 +530,6 @@ union tag_data {
f64 f64;
f128 f128;
s_fact fact;
- s_fn fn;
s_ident ident;
s_integer integer;
s_list *list;
@@ -656,7 +671,7 @@ TYPEDEF_SET_CURSOR(fact);
#define TYPEDEF_SKIPLIST_NODE(name, type) \
typedef struct skiplist_node__##name { \
- const type name; \
+ type name; \
u8 height; \
} s_skiplist_node__##name
@@ -727,7 +742,7 @@ struct env {
struct facts_with_cursor_level {
s_facts_cursor cursor;
- const s_fact *fact;
+ s_fact *fact;
p_facts_spec spec;
};