diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 25f1471..bc67562 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -694,7 +694,8 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
break;
}
result += r;
- tag_init_call(right, &tmp2);
+ tag_init_call(right);
+ right->data.call = tmp2;
if ((r = buf_ignore_spaces_but_newline(buf)) < 0)
break;
result += r;
@@ -718,7 +719,8 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence)
tmp3.ident = op;
tmp3.arguments->tag = *left;
list_next(tmp3.arguments)->tag = *right;
- tag_init_call(left, &tmp3);
+ tag_init_call(left);
+ left->data.call = tmp3;
}
call_clean(dest);
*dest = tmp;
diff --git a/libc3/cfn.c b/libc3/cfn.c
index 6b8cb68..8f2fc54 100644
--- a/libc3/cfn.c
+++ b/libc3/cfn.c
@@ -20,6 +20,7 @@
#include "str.h"
#include "sym.h"
#include "tag.h"
+#include "tag_type.h"
#include "type.h"
s_tag * cfn_tag_init (s_tag *tag, const s_sym *type);
diff --git a/libc3/f32.c b/libc3/f32.c
index d41b968..d2693ec 100644
--- a/libc3/f32.c
+++ b/libc3/f32.c
@@ -14,6 +14,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "f32.h"
f32 f32_cast (s_tag *tag)
@@ -77,7 +78,7 @@ f32 f32_cast (s_tag *tag)
return 0;
ko:
warnx("f32_cast: cannot cast %s to f32",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/f64.c b/libc3/f64.c
index 3e24354..4135def 100644
--- a/libc3/f64.c
+++ b/libc3/f64.c
@@ -15,6 +15,7 @@
#include <stdlib.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "f64.h"
f64 f64_cast (s_tag *tag)
@@ -78,7 +79,7 @@ f64 f64_cast (s_tag *tag)
return 0;
ko:
warnx("f64_cast: cannot cast %s to f64",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/gen.mk b/libc3/gen.mk
index 785f0a8..9026e40 100644
--- a/libc3/gen.mk
+++ b/libc3/gen.mk
@@ -71,6 +71,7 @@ GENERATED_FILES = \
buf_parse_u32.c buf_parse_u32.h \
buf_parse_u64.c buf_parse_u64.h \
buf_parse_uw.c buf_parse_uw.h \
+ list_init.h \
set__fact.c set__fact.h \
set__tag.c set__tag.h \
set_cursor__fact.c set_cursor__fact.h \
@@ -80,10 +81,14 @@ GENERATED_FILES = \
skiplist__fact.c skiplist__fact.h \
skiplist_node__fact.c skiplist_node__fact.h \
s8.c s8.h s16.c s16.h s32.c s32.h s64.c s64.h sw.c sw.h \
+ tag_init.h \
u8.c u8.h u16.c u16.h u32.c u32.h u64.c u64.h uw.c uw.h
gen: ${GENERATED_FILES}
+list_init.h tag_init.h: tag_init.h.rb
+ ruby tag_init.h.rb
+
SED_BITS_8 = sed \
-e 's/_BITS[$$]/8/g' \
-e 's/_bits[$$]/8/g'
diff --git a/libc3/integer.c b/libc3/integer.c
index ad79153..ae47cdf 100644
--- a/libc3/integer.c
+++ b/libc3/integer.c
@@ -18,6 +18,7 @@
#include "compare.h"
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
s_integer * integer_abs (const s_integer *a, s_integer *dest)
{
@@ -165,12 +166,12 @@ s_integer * integer_cast (const s_tag *tag, s_integer *dest)
case TAG_VAR:
goto ko;
}
- assert(! "u8_cast: unknown tag type");
- errx(1, "u8_cast: unknown tag type: %d", tag->type);
+ assert(! "integer_cast: unknown tag type");
+ errx(1, "integer_cast: unknown tag type: %d", tag->type);
return 0;
ko:
- warnx("u8_cast: cannot cast %s to u8",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ warnx("integer_cast: cannot cast %s to integer",
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/list.c b/libc3/list.c
index 3545044..e28861a 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -76,6 +76,14 @@ s_list * list_init (s_list *list, s_list *next)
return list;
}
+s_list * list_init_1 (s_list *list, const s8 *p, s_list *next)
+{
+ assert(list);
+ tag_init_1(&list->tag, p);
+ tag_init_list(&list->next, next);
+ return list;
+}
+
/* FIXME: does not work on circular lists */
s_list ** list_init_copy (s_list **list, const s_list **src)
{
@@ -159,7 +167,7 @@ s_list * list_new (s_list *next)
return list_init(dest, next);
}
-s_list * list_new_1 (const char *p)
+s_list * list_new_eval (const s8 *p)
{
s_buf buf;
s_list *list;
diff --git a/libc3/list.h b/libc3/list.h
index 12667d7..855c6d5 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -22,19 +22,22 @@
#include <stdarg.h>
#include <stdio.h>
#include "hash.h"
-#include "types.h"
+#include "list_init.h"
/* Stack-allocation functions, call list_clean after use. */
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 s8 *p, s_list *next);
s_list ** list_init_copy (s_list **list, const s_list **src);
-s_list * list_init_copy_tag (s_list *list, const s_tag *tag, s_list *next);
+s_list * list_init_copy_tag (s_list *list, const s_tag *tag,
+ s_list *next);
+s_list * list_init_eval (s_list *list, const s8 *p);
/* Heap-allocation functions, call list_delete after use */
s_list * list_delete (s_list *list);
void list_delete_all (s_list *list);
s_list * list_new (s_list *next);
-s_list * list_new_1 (const s8 *p);
+s_list * list_new_eval (const s8 *p);
s_list * list_new_f64 (f64 x, s_list *next);
s_list * list_new_copy (const s_tag *tag, s_list *next);
s_list * list_new_list (s_list *list, s_list *next);
@@ -54,4 +57,6 @@ s_str * list_inspect (const s_list *list, s_str *dest);
/* Operators */
s_list ** list_remove_void (s_list **list);
+/*#include "list_init.h"*/
+
#endif /* LIBC3_LIST_H */
diff --git a/libc3/list_init.h b/libc3/list_init.h
new file mode 100644
index 0000000..5ad281a
--- /dev/null
+++ b/libc3/list_init.h
@@ -0,0 +1,136 @@
+/* c3
+ * Copyright 2022,2023 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 LIBC3_LIST_INIT_H
+#define LIBC3_LIST_INIT_H
+
+#include "types.h"
+
+/* Stack-allocation compatible functions, call list_clean after use. */
+s_list * list_init_array (s_list *list, const s_sym *type,
+ uw dimension, const uw *dimensions,
+ s_list *next);
+s_list * list_init_bool (s_list *list, bool b, s_list *next);
+s_list * list_init_call (s_list *list, s_list *next);
+s_list * list_init_character (s_list *list, character 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_ident (s_list *list, const s_ident *ident,
+ s_list *next);
+s_list * list_init_ident_1 (s_list *list, const s8 *p, s_list *next);
+s_list * list_init_integer_copy (s_list *list, const s_integer *i,
+ s_list *next);
+s_list * list_init_integer_1 (s_list *list, const s8 *p, s_list *next);
+s_list * list_init_integer_zero (s_list *list, s_list *next);
+
+
+s_list * list_init_map (s_list *list, uw count, s_list *next);
+s_list * list_init_map_1 (s_list *list, const s8 *p, s_list *next);
+s_list * list_init_s8 (s_list *list, s8 i, s_list *next);
+s_list * list_init_s16 (s_list *list, s16 i, s_list *next);
+s_list * list_init_s32 (s_list *list, s32 i, s_list *next);
+s_list * list_init_s64 (s_list *list, s64 i, s_list *next);
+s_list * list_init_str (s_list *list, s8 *p_free, uw size, const s8 *p,
+ s_list *next);
+s_list * list_init_str_1 (s_list *list, s8 *p_free, const s8 *p,
+ s_list *next);
+s_list * list_init_sw (s_list *list, sw i, s_list *next);
+s_list * list_init_sym (s_list *list, const s_sym *sym, s_list *next);
+s_list * list_init_tuple (s_list *list, uw count, s_list *next);
+s_list * list_init_tuple_2 (s_list *list, const s_tag *a,
+ const s_tag *b, s_list *next);
+s_list * list_init_time (s_list *list, s_list *next);
+s_list * list_init_u8 (s_list *list, u8 i, s_list *next);
+s_list * list_init_u16 (s_list *list, u16 i, s_list *next);
+s_list * list_init_u32 (s_list *list, u32 i, s_list *next);
+s_list * list_init_u64 (s_list *list, u64 i, s_list *next);
+s_list * list_init_uw (s_list *list, uw i, s_list *next);
+s_list * list_init_var (s_list *list, s_list *next);
+s_list * list_init_void (s_list *list, s_list *next);
+
+/* Heap-allocation functions, call tag_delete after use. */
+s_list * list_new_array (const s_sym *type, uw dimension,
+ const uw *dimensions, s_list *next);
+s_list * list_new_bool (bool b, s_list *next);
+s_list * list_new_call (s_list *next);
+s_list * list_new_character (character 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_ident (const s_ident *ident, s_list *next);
+s_list * list_new_ident_1 (const s8 *p, s_list *next);
+s_list * list_new_integer_copy (const s_integer *i, s_list *next);
+s_list * list_new_integer_1 (const s8 *p, s_list *next);
+s_list * list_new_integer_zero (s_list *next);
+
+
+s_list * list_new_map (uw count, s_list *next);
+s_list * list_new_map_1 (const s8 *p, s_list *next);
+s_list * list_new_s8 (s8 i, s_list *next);
+s_list * list_new_s16 (s16 i, s_list *next);
+s_list * list_new_s32 (s32 i, s_list *next);
+s_list * list_new_s64 (s64 i, s_list *next);
+s_list * list_new_str (s8 *p_free, uw size, const s8 *p, s_list *next);
+s_list * list_new_str_1 (s8 *p_free, const s8 *p, s_list *next);
+s_list * list_new_sw (sw i, s_list *next);
+s_list * list_new_sym (const s_sym *sym, s_list *next);
+s_list * list_new_tuple (uw count, s_list *next);
+s_list * list_new_tuple_2 (const s_tag *a, const s_tag *b,
+ s_list *next);
+s_list * list_new_time (s_list *next);
+s_list * list_new_u8 (u8 i, s_list *next);
+s_list * list_new_u16 (u16 i, s_list *next);
+s_list * list_new_u32 (u32 i, s_list *next);
+s_list * list_new_u64 (u64 i, s_list *next);
+s_list * list_new_uw (uw i, s_list *next);
+s_list * list_new_var (s_list *next);
+s_list * list_new_void (s_list *next);
+
+/* Setters. */
+s_list * list_array (s_list *list, const s_sym *type, uw dimension,
+ const uw *dimensions);
+s_list * list_bool (s_list *list, bool b);
+s_list * list_call (s_list *list);
+s_list * list_character (s_list *list, character c);
+
+s_list * list_f32 (s_list *list, f32 f);
+s_list * list_f64 (s_list *list, f64 f);
+s_list * list_ident (s_list *list, const s_ident *ident);
+s_list * list_ident_1 (s_list *list, const s8 *p);
+s_list * list_integer_copy (s_list *list, const s_integer *i);
+s_list * list_integer_1 (s_list *list, const s8 *p);
+s_list * list_integer_zero (s_list *list);
+
+
+s_list * list_map (s_list *list, uw count);
+s_list * list_map_1 (s_list *list, const s8 *p);
+s_list * list_s8 (s_list *list, s8 i);
+s_list * list_s16 (s_list *list, s16 i);
+s_list * list_s32 (s_list *list, s32 i);
+s_list * list_s64 (s_list *list, s64 i);
+s_list * list_str (s_list *list, s8 *p_free, uw size, const s8 *p);
+s_list * list_str_1 (s_list *list, s8 *p_free, const s8 *p);
+s_list * list_sw (s_list *list, sw i);
+s_list * list_sym (s_list *list, const s_sym *sym);
+s_list * list_tuple (s_list *list, uw count);
+s_list * list_tuple_2 (s_list *list, const s_tag *a, const s_tag *b);
+s_list * list_time (s_list *list);
+s_list * list_u8 (s_list *list, u8 i);
+s_list * list_u16 (s_list *list, u16 i);
+s_list * list_u32 (s_list *list, u32 i);
+s_list * list_u64 (s_list *list, u64 i);
+s_list * list_uw (s_list *list, uw i);
+s_list * list_var (s_list *list);
+s_list * list_void (s_list *list);
+
+#endif /* LIBC3_LIST_INIT_H */
diff --git a/libc3/s.c.in b/libc3/s.c.in
index 3aba9d8..e2098d3 100644
--- a/libc3/s.c.in
+++ b/libc3/s.c.in
@@ -15,6 +15,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "s_bits$.h"
s_bits$ * s_bits$_cast (s_tag *tag, s_bits$ *dest)
@@ -94,7 +95,7 @@ s_bits$ * s_bits$_cast (s_tag *tag, s_bits$ *dest)
return 0;
ko:
warnx("s_bits$_cast: cannot cast %s to s_bits$",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/s16.c b/libc3/s16.c
index e9feb3e..09720b9 100644
--- a/libc3/s16.c
+++ b/libc3/s16.c
@@ -15,6 +15,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "s16.h"
s16 * s16_cast (s_tag *tag, s16 *dest)
@@ -94,7 +95,7 @@ s16 * s16_cast (s_tag *tag, s16 *dest)
return 0;
ko:
warnx("s16_cast: cannot cast %s to s16",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/s32.c b/libc3/s32.c
index 343e105..7d11ac3 100644
--- a/libc3/s32.c
+++ b/libc3/s32.c
@@ -15,6 +15,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "s32.h"
s32 * s32_cast (s_tag *tag, s32 *dest)
@@ -94,7 +95,7 @@ s32 * s32_cast (s_tag *tag, s32 *dest)
return 0;
ko:
warnx("s32_cast: cannot cast %s to s32",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/s64.c b/libc3/s64.c
index 3d28bd6..f97d2c3 100644
--- a/libc3/s64.c
+++ b/libc3/s64.c
@@ -15,6 +15,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "s64.h"
s64 * s64_cast (s_tag *tag, s64 *dest)
@@ -94,7 +95,7 @@ s64 * s64_cast (s_tag *tag, s64 *dest)
return 0;
ko:
warnx("s64_cast: cannot cast %s to s64",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/s8.c b/libc3/s8.c
index 0e457f1..e43d5e6 100644
--- a/libc3/s8.c
+++ b/libc3/s8.c
@@ -15,6 +15,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "s8.h"
s8 * s8_cast (s_tag *tag, s8 *dest)
@@ -94,7 +95,7 @@ s8 * s8_cast (s_tag *tag, s8 *dest)
return 0;
ko:
warnx("s8_cast: cannot cast %s to s8",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/sources.mk b/libc3/sources.mk
index c304bc6..c5b4084 100644
--- a/libc3/sources.mk
+++ b/libc3/sources.mk
@@ -101,6 +101,7 @@ HEADERS = \
integer.h \
io.h \
list.h \
+ list_init.h \
log.h \
map.h \
module.h \
@@ -123,9 +124,12 @@ HEADERS = \
skiplist__fact.h \
skiplist_node__fact.h \
str.h \
+ struct.h \
sw.h \
sym.h \
tag.h \
+ tag_init.h \
+ tag_type.h \
time.h \
tuple.h \
type.h \
@@ -267,11 +271,13 @@ SOURCES = \
tag_bor.c \
tag_bxor.c \
tag_div.c \
+ tag_init.c \
tag_mod.c \
tag_mul.c \
tag_shift_left.c \
tag_shift_right.c \
tag_sub.c \
+ tag_type.c \
time.c \
tuple.c \
type.c \
@@ -412,11 +418,13 @@ LO_SOURCES = \
tag_bor.c \
tag_bxor.c \
tag_div.c \
+ tag_init.c \
tag_mod.c \
tag_mul.c \
tag_shift_left.c \
tag_shift_right.c \
tag_sub.c \
+ tag_type.c \
time.c \
tuple.c \
type.c \
diff --git a/libc3/sources.sh b/libc3/sources.sh
index 439d3ed..5f55045 100644
--- a/libc3/sources.sh
+++ b/libc3/sources.sh
@@ -1,4 +1,4 @@
# sources.sh generated by update_sources
-HEADERS='abs.h arg.h array.h binding.h bool.h buf.h buf_file.h buf_inspect.h buf_inspect_s16.h buf_inspect_s16_binary.h buf_inspect_s16_decimal.h buf_inspect_s16_hexadecimal.h buf_inspect_s16_octal.h buf_inspect_s32.h buf_inspect_s32_binary.h buf_inspect_s32_decimal.h buf_inspect_s32_hexadecimal.h buf_inspect_s32_octal.h buf_inspect_s64.h buf_inspect_s64_binary.h buf_inspect_s64_decimal.h buf_inspect_s64_hexadecimal.h buf_inspect_s64_octal.h buf_inspect_s8.h buf_inspect_s8_binary.h buf_inspect_s8_decimal.h buf_inspect_s8_hexadecimal.h buf_inspect_s8_octal.h buf_inspect_sw.h buf_inspect_sw_binary.h buf_inspect_sw_decimal.h buf_inspect_sw_hexadecimal.h buf_inspect_sw_octal.h buf_inspect_u16.h buf_inspect_u16_binary.h buf_inspect_u16_decimal.h buf_inspect_u16_hexadecimal.h buf_inspect_u16_octal.h buf_inspect_u32.h buf_inspect_u32_binary.h buf_inspect_u32_decimal.h buf_inspect_u32_hexadecimal.h buf_inspect_u32_octal.h buf_inspect_u64.h buf_inspect_u64_binary.h buf_inspect_u64_decimal.h buf_inspect_u64_hexadecimal.h buf_inspect_u64_octal.h buf_inspect_u8.h buf_inspect_u8_binary.h buf_inspect_u8_decimal.h buf_inspect_u8_hexadecimal.h buf_inspect_u8_octal.h buf_inspect_uw.h buf_inspect_uw_binary.h buf_inspect_uw_decimal.h buf_inspect_uw_hexadecimal.h buf_inspect_uw_octal.h buf_parse.h buf_parse_s16.h buf_parse_s32.h buf_parse_s64.h buf_parse_s8.h buf_parse_sw.h buf_parse_u16.h buf_parse_u32.h buf_parse_u64.h buf_parse_u8.h buf_parse_uw.h buf_save.h c3.h c3_main.h call.h ceiling.h cfn.h character.h compare.h config.h env.h error.h error_handler.h eval.h f32.h f64.h fact.h facts.h facts_cursor.h facts_spec.h facts_spec_cursor.h facts_with.h facts_with_cursor.h file.h float.h fn.h fn_clause.h frame.h hash.h ident.h integer.h io.h list.h log.h map.h module.h operator.h ptag.h quote.h s16.h s32.h s64.h s8.h sequence.h set__fact.h set__tag.h set_cursor__fact.h set_cursor__tag.h set_item__fact.h set_item__tag.h sha1.h sign.h skiplist__fact.h skiplist_node__fact.h str.h sw.h sym.h tag.h time.h tuple.h type.h types.h u16.h u32.h u64.h u8.h ucd.h uw.h var.h '
-SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c log.c map.c module.c operator.c ptag.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c '
-LO_SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c log.c map.c module.c operator.c ptag.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c ../libtommath/bn_cutoffs.c ../libtommath/bn_mp_2expt.c ../libtommath/bn_mp_abs.c ../libtommath/bn_mp_add.c ../libtommath/bn_mp_add_d.c ../libtommath/bn_mp_and.c ../libtommath/bn_mp_clamp.c ../libtommath/bn_mp_clear.c ../libtommath/bn_mp_clear_multi.c ../libtommath/bn_mp_cmp.c ../libtommath/bn_mp_cmp_d.c ../libtommath/bn_mp_cmp_mag.c ../libtommath/bn_mp_cnt_lsb.c ../libtommath/bn_mp_complement.c ../libtommath/bn_mp_copy.c ../libtommath/bn_mp_count_bits.c ../libtommath/bn_mp_div.c ../libtommath/bn_mp_div_2.c ../libtommath/bn_mp_div_2d.c ../libtommath/bn_mp_div_3.c ../libtommath/bn_mp_div_d.c ../libtommath/bn_mp_dr_is_modulus.c ../libtommath/bn_mp_dr_reduce.c ../libtommath/bn_mp_dr_setup.c ../libtommath/bn_mp_error_to_string.c ../libtommath/bn_mp_exch.c ../libtommath/bn_mp_exptmod.c ../libtommath/bn_mp_gcd.c ../libtommath/bn_mp_get_double.c ../libtommath/bn_mp_get_i32.c ../libtommath/bn_mp_get_i64.c ../libtommath/bn_mp_get_mag_u32.c ../libtommath/bn_mp_get_mag_u64.c ../libtommath/bn_mp_grow.c ../libtommath/bn_mp_init.c ../libtommath/bn_mp_init_copy.c ../libtommath/bn_mp_init_multi.c ../libtommath/bn_mp_init_size.c ../libtommath/bn_mp_invmod.c ../libtommath/bn_mp_lcm.c ../libtommath/bn_mp_lshd.c ../libtommath/bn_mp_mod.c ../libtommath/bn_mp_mod_2d.c ../libtommath/bn_mp_montgomery_calc_normalization.c ../libtommath/bn_mp_montgomery_reduce.c ../libtommath/bn_mp_montgomery_setup.c ../libtommath/bn_mp_mul.c ../libtommath/bn_mp_mul_2.c ../libtommath/bn_mp_mul_2d.c ../libtommath/bn_mp_mul_d.c ../libtommath/bn_mp_mulmod.c ../libtommath/bn_mp_neg.c ../libtommath/bn_mp_or.c ../libtommath/bn_mp_radix_size.c ../libtommath/bn_mp_reduce.c ../libtommath/bn_mp_reduce_2k.c ../libtommath/bn_mp_reduce_2k_l.c ../libtommath/bn_mp_reduce_2k_setup.c ../libtommath/bn_mp_reduce_2k_setup_l.c ../libtommath/bn_mp_reduce_is_2k.c ../libtommath/bn_mp_reduce_is_2k_l.c ../libtommath/bn_mp_reduce_setup.c ../libtommath/bn_mp_rshd.c ../libtommath/bn_mp_set.c ../libtommath/bn_mp_set_double.c ../libtommath/bn_mp_set_i32.c ../libtommath/bn_mp_set_i64.c ../libtommath/bn_mp_set_l.c ../libtommath/bn_mp_set_u32.c ../libtommath/bn_mp_set_u64.c ../libtommath/bn_mp_set_ul.c ../libtommath/bn_mp_sqr.c ../libtommath/bn_mp_sqrt.c ../libtommath/bn_mp_sub.c ../libtommath/bn_mp_sub_d.c ../libtommath/bn_mp_xor.c ../libtommath/bn_mp_zero.c ../libtommath/bn_s_mp_add.c ../libtommath/bn_s_mp_balance_mul.c ../libtommath/bn_s_mp_exptmod.c ../libtommath/bn_s_mp_exptmod_fast.c ../libtommath/bn_s_mp_invmod_fast.c ../libtommath/bn_s_mp_invmod_slow.c ../libtommath/bn_s_mp_karatsuba_mul.c ../libtommath/bn_s_mp_karatsuba_sqr.c ../libtommath/bn_s_mp_montgomery_reduce_fast.c ../libtommath/bn_s_mp_mul_digs.c ../libtommath/bn_s_mp_mul_digs_fast.c ../libtommath/bn_s_mp_mul_high_digs.c ../libtommath/bn_s_mp_mul_high_digs_fast.c ../libtommath/bn_s_mp_rand_platform.c ../libtommath/bn_s_mp_sqr.c ../libtommath/bn_s_mp_sqr_fast.c ../libtommath/bn_s_mp_sub.c ../libtommath/bn_s_mp_toom_mul.c ../libtommath/bn_s_mp_toom_sqr.c '
+HEADERS='abs.h arg.h array.h binding.h bool.h buf.h buf_file.h buf_inspect.h buf_inspect_s16.h buf_inspect_s16_binary.h buf_inspect_s16_decimal.h buf_inspect_s16_hexadecimal.h buf_inspect_s16_octal.h buf_inspect_s32.h buf_inspect_s32_binary.h buf_inspect_s32_decimal.h buf_inspect_s32_hexadecimal.h buf_inspect_s32_octal.h buf_inspect_s64.h buf_inspect_s64_binary.h buf_inspect_s64_decimal.h buf_inspect_s64_hexadecimal.h buf_inspect_s64_octal.h buf_inspect_s8.h buf_inspect_s8_binary.h buf_inspect_s8_decimal.h buf_inspect_s8_hexadecimal.h buf_inspect_s8_octal.h buf_inspect_sw.h buf_inspect_sw_binary.h buf_inspect_sw_decimal.h buf_inspect_sw_hexadecimal.h buf_inspect_sw_octal.h buf_inspect_u16.h buf_inspect_u16_binary.h buf_inspect_u16_decimal.h buf_inspect_u16_hexadecimal.h buf_inspect_u16_octal.h buf_inspect_u32.h buf_inspect_u32_binary.h buf_inspect_u32_decimal.h buf_inspect_u32_hexadecimal.h buf_inspect_u32_octal.h buf_inspect_u64.h buf_inspect_u64_binary.h buf_inspect_u64_decimal.h buf_inspect_u64_hexadecimal.h buf_inspect_u64_octal.h buf_inspect_u8.h buf_inspect_u8_binary.h buf_inspect_u8_decimal.h buf_inspect_u8_hexadecimal.h buf_inspect_u8_octal.h buf_inspect_uw.h buf_inspect_uw_binary.h buf_inspect_uw_decimal.h buf_inspect_uw_hexadecimal.h buf_inspect_uw_octal.h buf_parse.h buf_parse_s16.h buf_parse_s32.h buf_parse_s64.h buf_parse_s8.h buf_parse_sw.h buf_parse_u16.h buf_parse_u32.h buf_parse_u64.h buf_parse_u8.h buf_parse_uw.h buf_save.h c3.h c3_main.h call.h ceiling.h cfn.h character.h compare.h config.h env.h error.h error_handler.h eval.h f32.h f64.h fact.h facts.h facts_cursor.h facts_spec.h facts_spec_cursor.h facts_with.h facts_with_cursor.h file.h float.h fn.h fn_clause.h frame.h hash.h ident.h integer.h io.h list.h list_init.h log.h map.h module.h operator.h ptag.h quote.h s16.h s32.h s64.h s8.h sequence.h set__fact.h set__tag.h set_cursor__fact.h set_cursor__tag.h set_item__fact.h set_item__tag.h sha1.h sign.h skiplist__fact.h skiplist_node__fact.h str.h struct.h sw.h sym.h tag.h tag_init.h tag_type.h time.h tuple.h type.h types.h u16.h u32.h u64.h u8.h ucd.h uw.h var.h '
+SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c log.c map.c module.c operator.c ptag.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_init.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c tag_type.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c '
+LO_SOURCES='abs.c arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_inspect_s16.c buf_inspect_s16_binary.c buf_inspect_s16_decimal.c buf_inspect_s16_hexadecimal.c buf_inspect_s16_octal.c buf_inspect_s32.c buf_inspect_s32_binary.c buf_inspect_s32_decimal.c buf_inspect_s32_hexadecimal.c buf_inspect_s32_octal.c buf_inspect_s64.c buf_inspect_s64_binary.c buf_inspect_s64_decimal.c buf_inspect_s64_hexadecimal.c buf_inspect_s64_octal.c buf_inspect_s8.c buf_inspect_s8_binary.c buf_inspect_s8_decimal.c buf_inspect_s8_hexadecimal.c buf_inspect_s8_octal.c buf_inspect_sw.c buf_inspect_sw_binary.c buf_inspect_sw_decimal.c buf_inspect_sw_hexadecimal.c buf_inspect_sw_octal.c buf_inspect_u16.c buf_inspect_u16_binary.c buf_inspect_u16_decimal.c buf_inspect_u16_hexadecimal.c buf_inspect_u16_octal.c buf_inspect_u32.c buf_inspect_u32_binary.c buf_inspect_u32_decimal.c buf_inspect_u32_hexadecimal.c buf_inspect_u32_octal.c buf_inspect_u64.c buf_inspect_u64_binary.c buf_inspect_u64_decimal.c buf_inspect_u64_hexadecimal.c buf_inspect_u64_octal.c buf_inspect_u8.c buf_inspect_u8_binary.c buf_inspect_u8_decimal.c buf_inspect_u8_hexadecimal.c buf_inspect_u8_octal.c buf_inspect_uw.c buf_inspect_uw_binary.c buf_inspect_uw_decimal.c buf_inspect_uw_hexadecimal.c buf_inspect_uw_octal.c buf_parse.c buf_parse_s16.c buf_parse_s32.c buf_parse_s64.c buf_parse_s8.c buf_parse_sw.c buf_parse_u16.c buf_parse_u32.c buf_parse_u64.c buf_parse_u8.c buf_parse_uw.c buf_save.c c3.c call.c ceiling.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c f32.c f64.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c file.c fn.c fn_clause.c frame.c hash.c ident.c integer.c io.c license.c list.c log.c map.c module.c operator.c ptag.c quote.c s16.c s32.c s64.c s8.c sequence.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c sign.c skiplist__fact.c skiplist_node__fact.c str.c sw.c sym.c tag.c tag_add.c tag_band.c tag_bor.c tag_bxor.c tag_div.c tag_init.c tag_mod.c tag_mul.c tag_shift_left.c tag_shift_right.c tag_sub.c tag_type.c time.c tuple.c type.c u16.c u32.c u64.c u8.c ucd.c uw.c var.c ../libtommath/bn_cutoffs.c ../libtommath/bn_mp_2expt.c ../libtommath/bn_mp_abs.c ../libtommath/bn_mp_add.c ../libtommath/bn_mp_add_d.c ../libtommath/bn_mp_and.c ../libtommath/bn_mp_clamp.c ../libtommath/bn_mp_clear.c ../libtommath/bn_mp_clear_multi.c ../libtommath/bn_mp_cmp.c ../libtommath/bn_mp_cmp_d.c ../libtommath/bn_mp_cmp_mag.c ../libtommath/bn_mp_cnt_lsb.c ../libtommath/bn_mp_complement.c ../libtommath/bn_mp_copy.c ../libtommath/bn_mp_count_bits.c ../libtommath/bn_mp_div.c ../libtommath/bn_mp_div_2.c ../libtommath/bn_mp_div_2d.c ../libtommath/bn_mp_div_3.c ../libtommath/bn_mp_div_d.c ../libtommath/bn_mp_dr_is_modulus.c ../libtommath/bn_mp_dr_reduce.c ../libtommath/bn_mp_dr_setup.c ../libtommath/bn_mp_error_to_string.c ../libtommath/bn_mp_exch.c ../libtommath/bn_mp_exptmod.c ../libtommath/bn_mp_gcd.c ../libtommath/bn_mp_get_double.c ../libtommath/bn_mp_get_i32.c ../libtommath/bn_mp_get_i64.c ../libtommath/bn_mp_get_mag_u32.c ../libtommath/bn_mp_get_mag_u64.c ../libtommath/bn_mp_grow.c ../libtommath/bn_mp_init.c ../libtommath/bn_mp_init_copy.c ../libtommath/bn_mp_init_multi.c ../libtommath/bn_mp_init_size.c ../libtommath/bn_mp_invmod.c ../libtommath/bn_mp_lcm.c ../libtommath/bn_mp_lshd.c ../libtommath/bn_mp_mod.c ../libtommath/bn_mp_mod_2d.c ../libtommath/bn_mp_montgomery_calc_normalization.c ../libtommath/bn_mp_montgomery_reduce.c ../libtommath/bn_mp_montgomery_setup.c ../libtommath/bn_mp_mul.c ../libtommath/bn_mp_mul_2.c ../libtommath/bn_mp_mul_2d.c ../libtommath/bn_mp_mul_d.c ../libtommath/bn_mp_mulmod.c ../libtommath/bn_mp_neg.c ../libtommath/bn_mp_or.c ../libtommath/bn_mp_radix_size.c ../libtommath/bn_mp_reduce.c ../libtommath/bn_mp_reduce_2k.c ../libtommath/bn_mp_reduce_2k_l.c ../libtommath/bn_mp_reduce_2k_setup.c ../libtommath/bn_mp_reduce_2k_setup_l.c ../libtommath/bn_mp_reduce_is_2k.c ../libtommath/bn_mp_reduce_is_2k_l.c ../libtommath/bn_mp_reduce_setup.c ../libtommath/bn_mp_rshd.c ../libtommath/bn_mp_set.c ../libtommath/bn_mp_set_double.c ../libtommath/bn_mp_set_i32.c ../libtommath/bn_mp_set_i64.c ../libtommath/bn_mp_set_l.c ../libtommath/bn_mp_set_u32.c ../libtommath/bn_mp_set_u64.c ../libtommath/bn_mp_set_ul.c ../libtommath/bn_mp_sqr.c ../libtommath/bn_mp_sqrt.c ../libtommath/bn_mp_sub.c ../libtommath/bn_mp_sub_d.c ../libtommath/bn_mp_xor.c ../libtommath/bn_mp_zero.c ../libtommath/bn_s_mp_add.c ../libtommath/bn_s_mp_balance_mul.c ../libtommath/bn_s_mp_exptmod.c ../libtommath/bn_s_mp_exptmod_fast.c ../libtommath/bn_s_mp_invmod_fast.c ../libtommath/bn_s_mp_invmod_slow.c ../libtommath/bn_s_mp_karatsuba_mul.c ../libtommath/bn_s_mp_karatsuba_sqr.c ../libtommath/bn_s_mp_montgomery_reduce_fast.c ../libtommath/bn_s_mp_mul_digs.c ../libtommath/bn_s_mp_mul_digs_fast.c ../libtommath/bn_s_mp_mul_high_digs.c ../libtommath/bn_s_mp_mul_high_digs_fast.c ../libtommath/bn_s_mp_rand_platform.c ../libtommath/bn_s_mp_sqr.c ../libtommath/bn_s_mp_sqr_fast.c ../libtommath/bn_s_mp_sub.c ../libtommath/bn_s_mp_toom_mul.c ../libtommath/bn_s_mp_toom_sqr.c '
diff --git a/libc3/struct.h b/libc3/struct.h
new file mode 100644
index 0000000..2b82808
--- /dev/null
+++ b/libc3/struct.h
@@ -0,0 +1,190 @@
+/* c3
+ * Copyright 2022,2023 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.
+ */
+/**
+ * @file tag.h
+ * @brief Struct type %Module{key: value, ...}
+ *
+ * Structure to represent a C structure.
+ */
+#ifndef LIBC3_TAG_H
+#define LIBC3_TAG_H
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "types.h"
+
+#define TAG_FIRST (&g_tag_first)
+#define TAG_LAST (&g_tag_last)
+
+extern s_tag g_tag_first;
+extern s_tag g_tag_last;
+
+/* Stack allocation compatible functions */
+void tag_clean (s_tag *tag);
+s_tag * tag_init (s_tag *tag);
+s_tag * tag_init_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
+ const uw *dimensions);
+s_tag * tag_init_bool (s_tag *tag, bool p);
+s_tag * tag_init_call (s_tag *tag, const s_call *call);
+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_ident (s_tag *tag, const s_ident *ident);
+s_tag * tag_init_ident_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_integer (s_tag *tag, const s_integer *i);
+s_tag * tag_init_integer_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_integer_zero (s_tag *tag);
+s_tag * tag_init_list (s_tag *tag, s_list *list);
+s_tag * tag_init_list_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_map (s_tag *tag, uw count);
+s_tag * tag_init_map_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_str (s_tag *tag, s8 *free, uw size, const s8 *p);
+s_tag * tag_init_str_1 (s_tag *tag, s8 *free, const s8 *p);
+s_tag * tag_init_sym (s_tag *tag, const s_sym *p);
+s_tag * tag_init_sym_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_time (s_tag *tag);
+s_tag * tag_init_tuple (s_tag *tag, uw count);
+s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b);
+s_tag * tag_init_var (s_tag *tag);
+s_tag * tag_init_void (s_tag *tag);
+
+/* Numbers */
+s_tag * tag_init_f32 (s_tag *tag, f32 f);
+s_tag * tag_init_f64 (s_tag *tag, f64 f);
+s_tag * tag_init_s8 (s_tag *tag, s8 i);
+s_tag * tag_init_s16 (s_tag *tag, s16 i);
+s_tag * tag_init_s32 (s_tag *tag, s32 i);
+s_tag * tag_init_s64 (s_tag *tag, s64 i);
+s_tag * tag_init_sw (s_tag *tag, sw i);
+s_tag * tag_init_u8 (s_tag *tag, u8 i);
+s_tag * tag_init_u16 (s_tag *tag, u16 i);
+s_tag * tag_init_u32 (s_tag *tag, u32 i);
+s_tag * tag_init_u64 (s_tag *tag, u64 i);
+s_tag * tag_init_uw (s_tag *tag, uw i);
+
+/* Constructors, call tag_delete after use */
+s_tag * tag_new (void);
+s_tag * tag_new_1 (const s8 *p);
+s_tag * tag_new_array (const s_sym *type, uw dimension,
+ const uw *dimensions);
+s_tag * tag_new_bool (bool p);
+s_tag * tag_new_character (character c);
+s_tag * tag_new_copy (const s_tag *src);
+s_tag * tag_new_sym (const s_sym *sym);
+s_tag * tag_new_f32 (f32 f);
+s_tag * tag_new_f64 (f64 f);
+s_tag * tag_new_s8 (s8 i);
+s_tag * tag_new_s16 (s16 i);
+s_tag * tag_new_s32 (s32 i);
+s_tag * tag_new_s64 (s64 i);
+s_tag * tag_new_str (s8 *free, uw size, const s8 *p);
+s_tag * tag_new_tuple_2 (s_tag *a, s_tag *b);
+s_tag * tag_new_u8 (u8 i);
+s_tag * tag_new_u16 (u16 i);
+s_tag * tag_new_u32 (u32 i);
+s_tag * tag_new_u64 (u64 i);
+s_tag * tag_new_var (void);
+
+/* Destructor */
+void tag_delete (s_tag *tag);
+
+/* Observers */
+u64 tag_hash_u64 (const s_tag *tag);
+uw tag_hash_uw (const s_tag *tag);
+s_str * tag_inspect (const s_tag *tag, s_str *dest);
+bool tag_ident_is_bound (const s_tag *tag);
+bool tag_is_bound_var (const s_tag *tag);
+bool tag_is_number (const s_tag *tag);
+bool tag_is_unbound_var (const s_tag *tag);
+s8 tag_number_compare (const s_tag *a, const s_tag *b);
+sw tag_size (const s_tag *tag);
+void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
+ffi_type tag_to_ffi_type(const s_tag *tag);
+void * tag_to_pointer (s_tag *tag, const s_sym *type);
+const s_sym ** tag_type (const s_tag *tag, const s_sym **type);
+sw tag_type_size (e_tag_type type);
+f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
+f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type);
+f_buf_parse tag_type_to_buf_parse (e_tag_type type);
+const s8 * tag_type_to_string (e_tag_type type);
+const s_sym * tag_type_to_sym (e_tag_type tag_type);
+
+/* Modifiers */
+s_tag * tag_1 (s_tag *tag, const s8 *p);
+s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
+ const uw *dimensions);
+s_tag * tag_bool (s_tag *tag, bool p);
+s_tag * tag_cast_integer_to_s16 (s_tag *tag);
+s_tag * tag_cast_integer_to_s32 (s_tag *tag);
+s_tag * tag_cast_integer_to_s64 (s_tag *tag);
+s_tag * tag_cast_integer_to_s8 (s_tag *tag);
+s_tag * tag_cast_integer_to_u16 (s_tag *tag);
+s_tag * tag_cast_integer_to_u32 (s_tag *tag);
+s_tag * tag_cast_integer_to_u64 (s_tag *tag);
+s_tag * tag_cast_integer_to_u8 (s_tag *tag);
+s_tag * tag_character (s_tag *tag, character c);
+s_tag * tag_f32 (s_tag *tag, f32 f);
+s_tag * tag_f64 (s_tag *tag, f64 f);
+s_tag * tag_ident (s_tag *tag, const s_ident *ident);
+s_tag * tag_ident_1 (s_tag *tag, const s8 *p);
+s_tag * tag_integer (s_tag *tag, const s_integer *x);
+s_tag * tag_integer_1 (s_tag *tag, const s8 *p);
+s_tag * tag_integer_reduce (s_tag *tag);
+s_tag * tag_list (s_tag *tag, s_list *list);
+s_tag * tag_list_1 (s_tag *tag, const s8 *p);
+s_tag * tag_map (s_tag *tag, uw count);
+s_tag * tag_map_1 (s_tag *tag, const s8 *p);
+s_tag * tag_s16 (s_tag *tag, s16 i);
+s_tag * tag_s32 (s_tag *tag, s32 i);
+s_tag * tag_s64 (s_tag *tag, s64 i);
+s_tag * tag_s8 (s_tag *tag, s8 i);
+s_tag * tag_str (s_tag *tag, s8 *free, uw size, const s8 *p);
+s_tag * tag_str_1 (s_tag *tag, s8 *free, const s8 *p);
+s_tag * tag_sym (s_tag *tag, const s_sym *p);
+s_tag * tag_sym_1 (s_tag *tag, const s8 *p);
+s_tag * tag_tuple (s_tag *tag, uw count);
+s_tag * tag_tuple_2 (s_tag *tag, s_tag *a, s_tag *b);
+s_tag * tag_u16 (s_tag *tag, u16 i);
+s_tag * tag_u32 (s_tag *tag, u32 i);
+s_tag * tag_u64 (s_tag *tag, u64 i);
+s_tag * tag_u8 (s_tag *tag, u8 i);
+s_tag * tag_var (s_tag *tag);
+s_tag * tag_void (s_tag *tag);
+
+/* operators */
+s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest);
+bool * tag_and (const s_tag *a, const s_tag *b, bool *dest);
+s_tag * tag_band (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_bnot (const s_tag *tag, s_tag *dest);
+s_tag * tag_bor (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_brackets (s_tag *tag, const s_tag *address, s_tag *dest);
+s_tag * tag_bxor (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest);
+bool * tag_lt (const s_tag *a, const s_tag *b, bool *dest);
+bool * tag_lte (const s_tag *a, const s_tag *b, bool *dest);
+bool * tag_gt (const s_tag *a, const s_tag *b, bool *dest);
+bool * tag_gte (const s_tag *a, const s_tag *b, bool *dest);
+bool * tag_eq (const s_tag *a, const s_tag *b, bool *dest);
+s_tag * tag_equal (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_mod (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_mul (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_neg (const s_tag *tag, s_tag *dest);
+bool * tag_not (const s_tag *tag, bool *dest);
+bool * tag_not_eq (const s_tag *a, const s_tag *b, bool *dest);
+bool * tag_or (const s_tag *a, const s_tag *b, bool *dest);
+s_tag * tag_paren (const s_tag *tag, s_tag *dest);
+s_tag * tag_shift_left (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_shift_right (const s_tag *a, const s_tag *b, s_tag *dest);
+s_tag * tag_sub (const s_tag *a, const s_tag *b, s_tag *dest);
+
+#endif /* LIBC3_TAG_H */
diff --git a/libc3/sw.c b/libc3/sw.c
index 645bfb0..7edc3e7 100644
--- a/libc3/sw.c
+++ b/libc3/sw.c
@@ -15,6 +15,7 @@
#include <err.h>
#include "integer.h"
#include "tag.h"
+#include "tag_type.h"
#include "sw.h"
sw * sw_cast (s_tag *tag, sw *dest)
@@ -94,7 +95,7 @@ sw * sw_cast (s_tag *tag, sw *dest)
return 0;
ko:
warnx("sw_cast: cannot cast %s to sw",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/tag.c b/libc3/tag.c
index 4d7ccef..15a3129 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -34,6 +34,7 @@
#include "quote.h"
#include "str.h"
#include "tag.h"
+#include "tag_type.h"
#include "time.h"
#include "tuple.h"
@@ -449,16 +450,6 @@ s_tag * tag_init_bool (s_tag *tag, bool b)
return tag;
}
-s_tag * tag_init_call (s_tag *tag, const s_call *call)
-{
- assert(tag);
- assert(call);
- bzero(tag, sizeof(s_tag));
- tag->type = TAG_CALL;
- tag->data.call = *call;
- return tag;
-}
-
s_tag * tag_init_character (s_tag *tag, character c)
{
assert(tag);
@@ -503,7 +494,7 @@ s_tag * tag_init_ident_1 (s_tag *tag, const s8 *p)
ident_init_1(&tag->data.ident, p);
return tag;
}
-
+/*
s_tag * tag_init_integer (s_tag *tag, const s_integer *i)
{
assert(tag);
@@ -512,6 +503,7 @@ s_tag * tag_init_integer (s_tag *tag, const s_integer *i)
integer_init_copy(&tag->data.integer, i);
return tag;
}
+*/
s_tag * tag_init_integer_1 (s_tag *tag, const s8 *p)
{
@@ -566,6 +558,7 @@ s_tag * tag_init_list (s_tag *tag, s_list *list)
return tag;
}
+/*
s_tag * tag_init_list_1 (s_tag *tag, const s8 *p)
{
s_buf buf;
@@ -582,6 +575,7 @@ s_tag * tag_init_list_1 (s_tag *tag, const s8 *p)
buf_clean(&buf);
return tag;
}
+*/
s_tag * tag_init_map (s_tag *tag, uw count)
{
@@ -791,18 +785,18 @@ s_str * tag_inspect (const s_tag *tag, s_str *dest)
return buf_to_str(&buf, dest);
}
-s_tag * tag_integer (s_tag *tag, const s_integer *x)
+s_tag * tag_integer_1 (s_tag *tag, const s8 *p)
{
assert(tag);
tag_clean(tag);
- return tag_init_integer(tag, x);
+ return tag_init_integer_1(tag, p);
}
-s_tag * tag_integer_1 (s_tag *tag, const s8 *p)
+s_tag * tag_integer_copy (s_tag *tag, const s_integer *x)
{
assert(tag);
tag_clean(tag);
- return tag_init_integer_1(tag, p);
+ return tag_init_integer_copy(tag, x);
}
s_tag * tag_integer_reduce (s_tag *tag)
@@ -876,12 +870,14 @@ s_tag * tag_list (s_tag *tag, s_list *x)
return tag_init_list(tag, x);
}
+/*
s_tag * tag_list_1 (s_tag *tag, const s8 *p)
{
assert(tag);
tag_clean(tag);
return tag_init_list_1(tag, p);
}
+*/
bool * tag_lt (const s_tag *a, const s_tag *b, bool *dest)
{
@@ -907,6 +903,7 @@ s_tag * tag_map (s_tag *tag, uw count)
return tag_init_map(tag, count);
}
+/*
s_tag * tag_map_1 (s_tag *tag, const s8 *p)
{
assert(tag);
@@ -914,7 +911,7 @@ s_tag * tag_map_1 (s_tag *tag, const s8 *p)
tag_clean(tag);
return tag_init_map_1(tag, p);
}
-
+*/
s_tag * tag_neg (const s_tag *tag, s_tag *result)
{
@@ -1293,7 +1290,7 @@ void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type)
return NULL;
invalid_type:
warnx("tag_to_ffi_pointer: cannot cast %s to %s",
- tag_type_to_sym(tag->type)->str.ptr.ps8,
+ tag_type_to_string(tag->type),
type->str.ptr.ps8);
return NULL;
}
@@ -1305,7 +1302,7 @@ void * tag_to_pointer (s_tag *tag, const s_sym *type)
if (tag->type != tag_type) {
assert(! "tag_to_pointer: cannot cast");
errx(1, "tag_to_pointer: cannot cast %s to %s",
- tag_type_to_sym(tag->type)->str.ptr.ps8,
+ tag_type_to_string(tag->type),
type->str.ptr.ps8);
return NULL;
}
@@ -1378,7 +1375,7 @@ void * tag_to_pointer (s_tag *tag, const s_sym *type)
return NULL;
invalid_type:
warnx("tag_to_pointer: cannot cast %s to %s",
- tag_type_to_sym(tag->type)->str.ptr.ps8,
+ tag_type_to_string(tag->type),
type->str.ptr.ps8);
return NULL;
@@ -1391,7 +1388,7 @@ s_tag * tag_tuple (s_tag *tag, uw count)
return tag_init_tuple(tag, count);
}
-s_tag * tag_tuple_2 (s_tag *tag, s_tag *a, s_tag *b)
+s_tag * tag_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
{
assert(tag);
tag_clean(tag);
@@ -1406,411 +1403,6 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
return dest;
}
-sw tag_type_size (e_tag_type type)
-{
- switch (type) {
- case TAG_VOID:
- return 0;
- case TAG_ARRAY:
- assert(! "tag_type_size: TAG_ARRAY: not implemented");
- errx(1, "tag_type_size: TAG_ARRAY: not implemented");
- return -1;
- case TAG_BOOL:
- return sizeof(bool);
- case TAG_CALL:
- return sizeof(s_call);
- case TAG_CFN:
- return sizeof(s_cfn);
- case TAG_CHARACTER:
- return sizeof(character);
- case TAG_F32:
- return sizeof(f32);
- case TAG_F64:
- return sizeof(f64);
- case TAG_FACT:
- return sizeof(s_fact);
- case TAG_FN:
- return sizeof(s_fn);
- case TAG_IDENT:
- return sizeof(s_ident);
- case TAG_INTEGER:
- return sizeof(s_integer);
- case TAG_SW:
- return sizeof(sw);
- case TAG_S64:
- return sizeof(s64);
- case TAG_S32:
- return sizeof(s32);
- case TAG_S16:
- return sizeof(s16);
- case TAG_S8:
- return sizeof(s8);
- case TAG_U8:
- return sizeof(u8);
- case TAG_U16:
- return sizeof(u16);
- case TAG_U32:
- return sizeof(u32);
- case TAG_U64:
- return sizeof(u64);
- case TAG_UW:
- return sizeof(uw);
- case TAG_LIST:
- return sizeof(s_list *);
- case TAG_MAP:
- return sizeof(s_map);
- case TAG_PTAG:
- return sizeof(p_tag);
- case TAG_PTR:
- return sizeof(void *);
- case TAG_QUOTE:
- return sizeof(s_quote);
- case TAG_STR:
- return sizeof(s_str);
- case TAG_SYM:
- return sizeof(s_sym *);
- case TAG_TUPLE:
- return sizeof(s_tuple);
- case TAG_VAR:
- return sizeof(s_tag);
- }
- assert(! "tag_type_size: invalid tag type");
- errx(1, "tag_type_size: invalid tag type: %d", type);
- return -1;
-}
-
-f_buf_inspect tag_type_to_buf_inspect (e_tag_type type)
-{
- switch (type) {
- case TAG_VOID:
- return (f_buf_inspect) buf_inspect_void;
- case TAG_ARRAY:
- case TAG_BOOL:
- return (f_buf_inspect) buf_inspect_bool;
- case TAG_CALL:
- return (f_buf_inspect) buf_inspect_call;
- case TAG_CFN:
- return (f_buf_inspect) buf_inspect_cfn;
- case TAG_CHARACTER:
- return (f_buf_inspect) buf_inspect_character;
- case TAG_F32:
- return (f_buf_inspect) buf_inspect_f32;
- case TAG_F64:
- return (f_buf_inspect) buf_inspect_f64;
- case TAG_FACT:
- return (f_buf_inspect) buf_inspect_fact;
- case TAG_FN:
- return (f_buf_inspect) buf_inspect_fn;
- case TAG_IDENT:
- return (f_buf_inspect) buf_inspect_ident;
- case TAG_INTEGER:
- return (f_buf_inspect) buf_inspect_integer;
- case TAG_SW:
- return (f_buf_inspect) buf_inspect_sw;
- case TAG_S64:
- return (f_buf_inspect) buf_inspect_s64;
- case TAG_S32:
- return (f_buf_inspect) buf_inspect_s32;
- case TAG_S16:
- return (f_buf_inspect) buf_inspect_s16;
- case TAG_S8:
- return (f_buf_inspect) buf_inspect_s8;
- case TAG_U8:
- return (f_buf_inspect) buf_inspect_u8;
- case TAG_U16:
- return (f_buf_inspect) buf_inspect_u16;
- case TAG_U32:
- return (f_buf_inspect) buf_inspect_u32;
- case TAG_U64:
- return (f_buf_inspect) buf_inspect_u64;
- case TAG_UW:
- return (f_buf_inspect) buf_inspect_uw;
- case TAG_LIST:
- return (f_buf_inspect) buf_inspect_list;
- case TAG_MAP:
- return (f_buf_inspect) buf_inspect_map;
- case TAG_PTAG:
- return (f_buf_inspect) buf_inspect_ptag;
- case TAG_PTR:
- return (f_buf_inspect) buf_inspect_ptr;
- case TAG_QUOTE:
- return (f_buf_inspect) buf_inspect_quote;
- case TAG_STR:
- return (f_buf_inspect) buf_inspect_str;
- case TAG_SYM:
- return (f_buf_inspect) buf_inspect_sym;
- case TAG_TUPLE:
- return (f_buf_inspect) buf_inspect_tuple;
- case TAG_VAR:
- return (f_buf_inspect) buf_inspect_var;
- }
- assert(! "buf_inspect: unknown tag type");
- errx(1, "buf_inspect: unknown tag type");
- return NULL;
-}
-
-f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type)
-{
- switch (type) {
- case TAG_VOID:
- return (f_buf_inspect_size) buf_inspect_void_size;
- case TAG_ARRAY:
- return (f_buf_inspect_size) buf_inspect_array_size;
- case TAG_BOOL:
- return (f_buf_inspect_size) buf_inspect_bool_size;
- case TAG_CALL:
- return (f_buf_inspect_size) buf_inspect_call_size;
- case TAG_CFN:
- return (f_buf_inspect_size) buf_inspect_cfn_size;
- case TAG_CHARACTER:
- return (f_buf_inspect_size) buf_inspect_character_size;
- case TAG_F32:
- return (f_buf_inspect_size) buf_inspect_f32_size;
- case TAG_F64:
- return (f_buf_inspect_size) buf_inspect_f64_size;
- case TAG_FACT:
- return (f_buf_inspect_size) buf_inspect_fact_size;
- case TAG_FN:
- return (f_buf_inspect_size) buf_inspect_fn_size;
- case TAG_IDENT:
- return (f_buf_inspect_size) buf_inspect_ident_size;
- case TAG_INTEGER:
- return (f_buf_inspect_size) buf_inspect_integer_size;
- case TAG_SW:
- return (f_buf_inspect_size) buf_inspect_sw_size;
- case TAG_S64:
- return (f_buf_inspect_size) buf_inspect_s64_size;
- case TAG_S32:
- return (f_buf_inspect_size) buf_inspect_s32_size;
- case TAG_S16:
- return (f_buf_inspect_size) buf_inspect_s16_size;
- case TAG_S8:
- return (f_buf_inspect_size) buf_inspect_s8_size;
- case TAG_U8:
- return (f_buf_inspect_size) buf_inspect_u8_size;
- case TAG_U16:
- return (f_buf_inspect_size) buf_inspect_u16_size;
- case TAG_U32:
- return (f_buf_inspect_size) buf_inspect_u32_size;
- case TAG_U64:
- return (f_buf_inspect_size) buf_inspect_u64_size;
- case TAG_UW:
- return (f_buf_inspect_size) buf_inspect_uw_size;
- case TAG_LIST:
- return (f_buf_inspect_size) buf_inspect_list_size;
- case TAG_MAP:
- return (f_buf_inspect_size) buf_inspect_map_size;
- case TAG_PTAG:
- return (f_buf_inspect_size) buf_inspect_ptag_size;
- case TAG_PTR:
- return (f_buf_inspect_size) buf_inspect_ptr_size;
- case TAG_QUOTE:
- return (f_buf_inspect_size) buf_inspect_quote_size;
- case TAG_STR:
- return (f_buf_inspect_size) buf_inspect_str_size;
- case TAG_SYM:
- return (f_buf_inspect_size) buf_inspect_sym_size;
- case TAG_TUPLE:
- return (f_buf_inspect_size) buf_inspect_tuple_size;
- case TAG_VAR:
- return (f_buf_inspect_size) buf_inspect_var_size;
- }
- assert(! "tag_type_to_buf_inspect_size: unknown tag type");
- errx(1, "tag_type_to_buf_inspect_size: unknown tag type");
- return NULL;
-}
-
-f_buf_parse tag_type_to_buf_parse (e_tag_type type)
-{
- switch (type) {
- case TAG_VOID:
- return (f_buf_parse) buf_parse_void;
- case TAG_ARRAY:
- return (f_buf_parse) buf_parse_array;
- case TAG_BOOL:
- return (f_buf_parse) buf_parse_bool;
- case TAG_CALL:
- return (f_buf_parse) buf_parse_call;
- case TAG_CFN:
- return (f_buf_parse) buf_parse_cfn;
- case TAG_CHARACTER:
- return (f_buf_parse) buf_parse_character;
- case TAG_F32:
- return (f_buf_parse) buf_parse_f32;
- case TAG_F64:
- return (f_buf_parse) buf_parse_f64;
- case TAG_FACT:
- return (f_buf_parse) buf_parse_fact;
- case TAG_FN:
- return (f_buf_parse) buf_parse_fn;
- case TAG_IDENT:
- return (f_buf_parse) buf_parse_ident;
- case TAG_INTEGER:
- return (f_buf_parse) buf_parse_integer;
- case TAG_SW:
- return (f_buf_parse) buf_parse_sw;
- case TAG_S64:
- return (f_buf_parse) buf_parse_s64;
- case TAG_S32:
- return (f_buf_parse) buf_parse_s32;
- case TAG_S16:
- return (f_buf_parse) buf_parse_s16;
- case TAG_S8:
- return (f_buf_parse) buf_parse_s8;
- case TAG_U8:
- return (f_buf_parse) buf_parse_u8;
- case TAG_U16:
- return (f_buf_parse) buf_parse_u16;
- case TAG_U32:
- return (f_buf_parse) buf_parse_u32;
- case TAG_U64:
- return (f_buf_parse) buf_parse_u64;
- case TAG_UW:
- return (f_buf_parse) buf_parse_uw;
- case TAG_LIST:
- return (f_buf_parse) buf_parse_list;
- case TAG_MAP:
- return (f_buf_parse) buf_parse_map;
- case TAG_PTAG:
- return (f_buf_parse) buf_parse_ptag;
- case TAG_PTR:
- return (f_buf_parse) buf_parse_ptr;
- case TAG_QUOTE:
- return (f_buf_parse) buf_parse_quote;
- case TAG_STR:
- return (f_buf_parse) buf_parse_str;
- case TAG_SYM:
- return (f_buf_parse) buf_parse_sym;
- case TAG_TUPLE:
- return (f_buf_parse) buf_parse_tuple;
- case TAG_VAR:
- return (f_buf_parse) buf_parse_var;
- }
- assert(! "tag_type_to_buf_parse: invalid tag type");
- err(1, "tag_type_to_buf_parse: invalid tag type");
- return NULL;
-}
-
-ffi_type * tag_type_to_ffi_type (e_tag_type type)
-{
- switch (type) {
- case TAG_ARRAY:
- return &ffi_type_pointer;
- case TAG_BOOL:
- return &ffi_type_uint8;
- case TAG_CALL:
- return &ffi_type_pointer;
- case TAG_CFN:
- return &ffi_type_pointer;
- case TAG_CHARACTER:
- return &ffi_type_schar;
- case TAG_F32:
- return &ffi_type_float;
- case TAG_F64:
- return &ffi_type_double;
- case TAG_FACT:
- return &ffi_type_pointer;
- case TAG_FN:
- return &ffi_type_pointer;
- case TAG_IDENT:
- return &ffi_type_pointer;
- case TAG_INTEGER:
- return &ffi_type_sint;
- case TAG_LIST:
- return &ffi_type_pointer;
- case TAG_MAP:
- return &ffi_type_pointer;
- case TAG_PTAG:
- return &ffi_type_pointer;
- case TAG_PTR:
- return &ffi_type_pointer;
- case TAG_QUOTE:
- return &ffi_type_pointer;
- case TAG_S8:
- return &ffi_type_sint8;
- case TAG_S16:
- return &ffi_type_sint16;
- case TAG_S32:
- return &ffi_type_sint32;
- case TAG_S64:
- return &ffi_type_sint64;
- case TAG_SW:
- return &ffi_type_slong;
- case TAG_STR:
- return &ffi_type_pointer;
- case TAG_SYM:
- return &ffi_type_pointer;
- case TAG_TUPLE:
- return &ffi_type_pointer;
- case TAG_U8:
- return &ffi_type_uint8;
- case TAG_U16:
- return &ffi_type_uint16;
- case TAG_U32:
- return &ffi_type_uint32;
- case TAG_U64:
- return &ffi_type_uint64;
- case TAG_UW:
- return &ffi_type_ulong;
- case TAG_VAR:
- return &ffi_type_pointer;
- case TAG_VOID:
- return &ffi_type_void;
- }
- assert(! "tag_type_to_ffi_type: unknown tag type");
- errx(1, "tag_type_to_ffi_type: unknown tag type");
- return &ffi_type_void;
-}
-
-const s8 * tag_type_to_string (e_tag_type type)
-{
- const s_sym *sym;
- if (! (sym = tag_type_to_sym(type)))
- return NULL;
- return sym->str.ptr.ps8;
-}
-
-
-const s_sym * tag_type_to_sym (e_tag_type tag_type)
-{
- switch (tag_type) {
- case TAG_VOID: return sym_1("Void");
- case TAG_ARRAY: return sym_1("Array");
- case TAG_BOOL: return sym_1("Bool");
- case TAG_CALL: return sym_1("Call");
- case TAG_CFN: return sym_1("Cfn");
- case TAG_CHARACTER: return sym_1("Character");
- case TAG_F32: return sym_1("F32");
- case TAG_F64: return sym_1("F64");
- case TAG_FACT: return sym_1("Fact");
- case TAG_FN: return sym_1("Fn");
- case TAG_IDENT: return sym_1("Ident");
- case TAG_INTEGER: return sym_1("Integer");
- case TAG_SW: return sym_1("Sw");
- case TAG_S64: return sym_1("S64");
- case TAG_S32: return sym_1("S32");
- case TAG_S16: return sym_1("S16");
- case TAG_S8: return sym_1("S8");
- case TAG_U8: return sym_1("U8");
- case TAG_U16: return sym_1("U16");
- case TAG_U32: return sym_1("U32");
- case TAG_U64: return sym_1("U64");
- case TAG_UW: return sym_1("Uw");
- case TAG_LIST: return sym_1("List");
- case TAG_MAP: return sym_1("Map");
- case TAG_PTAG: return sym_1("Ptag");
- case TAG_PTR: return sym_1("Void*");
- case TAG_QUOTE: return sym_1("Quote");
- case TAG_STR: return sym_1("Str");
- case TAG_SYM: return sym_1("Sym");
- case TAG_TUPLE: return sym_1("Tuple");
- case TAG_VAR: return sym_1("Var");
- }
- assert(! "tag_type_to_sym: invalid tag type");
- errx(1, "tag_type_to_sym: invalid tag type: %d", tag_type);
- return NULL;
-}
-
s_tag * tag_u8 (s_tag *tag, u8 x)
{
assert(tag);
diff --git a/libc3/tag.h b/libc3/tag.h
index 8a9e1aa..ac9321f 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -21,7 +21,8 @@
#include <stdarg.h>
#include <stdio.h>
-#include "types.h"
+#include "tag_init.h"
+#include "tag_type.h"
#define TAG_FIRST (&g_tag_first)
#define TAG_LAST (&g_tag_last)
@@ -29,139 +30,44 @@
extern s_tag g_tag_first;
extern s_tag g_tag_last;
-/* Stack allocation compatible functions */
+/* Stack-allocation compatible functions, call tag_clean after use. */
void tag_clean (s_tag *tag);
s_tag * tag_init (s_tag *tag);
s_tag * tag_init_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
- const uw *dimensions);
-s_tag * tag_init_bool (s_tag *tag, bool p);
-s_tag * tag_init_call (s_tag *tag, const s_call *call);
-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_ident (s_tag *tag, const s_ident *ident);
-s_tag * tag_init_ident_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_integer (s_tag *tag, const s_integer *i);
-s_tag * tag_init_integer_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_integer_zero (s_tag *tag);
-s_tag * tag_init_list (s_tag *tag, s_list *list);
-s_tag * tag_init_list_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_map (s_tag *tag, uw count);
-s_tag * tag_init_map_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_str (s_tag *tag, s8 *free, uw size, const s8 *p);
-s_tag * tag_init_str_1 (s_tag *tag, s8 *free, const s8 *p);
-s_tag * tag_init_sym (s_tag *tag, const s_sym *p);
-s_tag * tag_init_sym_1 (s_tag *tag, const s8 *p);
-s_tag * tag_init_time (s_tag *tag);
-s_tag * tag_init_tuple (s_tag *tag, uw count);
-s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b);
-s_tag * tag_init_var (s_tag *tag);
-s_tag * tag_init_void (s_tag *tag);
-/* Numbers */
-s_tag * tag_init_f32 (s_tag *tag, f32 f);
-s_tag * tag_init_f64 (s_tag *tag, f64 f);
-s_tag * tag_init_s8 (s_tag *tag, s8 i);
-s_tag * tag_init_s16 (s_tag *tag, s16 i);
-s_tag * tag_init_s32 (s_tag *tag, s32 i);
-s_tag * tag_init_s64 (s_tag *tag, s64 i);
-s_tag * tag_init_sw (s_tag *tag, sw i);
-s_tag * tag_init_u8 (s_tag *tag, u8 i);
-s_tag * tag_init_u16 (s_tag *tag, u16 i);
-s_tag * tag_init_u32 (s_tag *tag, u32 i);
-s_tag * tag_init_u64 (s_tag *tag, u64 i);
-s_tag * tag_init_uw (s_tag *tag, uw i);
-
-/* Constructors, call tag_delete after use */
+/* Heap-allocation functions, call tag_delete after use. */
+void tag_delete (s_tag *tag);
s_tag * tag_new (void);
s_tag * tag_new_1 (const s8 *p);
-s_tag * tag_new_array (const s_sym *type, uw dimension,
- const uw *dimensions);
-s_tag * tag_new_bool (bool p);
-s_tag * tag_new_character (character c);
-s_tag * tag_new_copy (const s_tag *src);
-s_tag * tag_new_sym (const s_sym *sym);
-s_tag * tag_new_f32 (f32 f);
-s_tag * tag_new_f64 (f64 f);
-s_tag * tag_new_s8 (s8 i);
-s_tag * tag_new_s16 (s16 i);
-s_tag * tag_new_s32 (s32 i);
-s_tag * tag_new_s64 (s64 i);
-s_tag * tag_new_str (s8 *free, uw size, const s8 *p);
-s_tag * tag_new_tuple_2 (s_tag *a, s_tag *b);
-s_tag * tag_new_u8 (u8 i);
-s_tag * tag_new_u16 (u16 i);
-s_tag * tag_new_u32 (u32 i);
-s_tag * tag_new_u64 (u64 i);
-s_tag * tag_new_var (void);
-
-/* Destructor */
-void tag_delete (s_tag *tag);
/* Observers */
-u64 tag_hash_u64 (const s_tag *tag);
-uw tag_hash_uw (const s_tag *tag);
-s_str * tag_inspect (const s_tag *tag, s_str *dest);
-bool tag_ident_is_bound (const s_tag *tag);
-bool tag_is_bound_var (const s_tag *tag);
-bool tag_is_number (const s_tag *tag);
-bool tag_is_unbound_var (const s_tag *tag);
-s8 tag_number_compare (const s_tag *a, const s_tag *b);
-sw tag_size (const s_tag *tag);
-void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
-ffi_type tag_to_ffi_type(const s_tag *tag);
-void * tag_to_pointer (s_tag *tag, const s_sym *type);
-const s_sym ** tag_type (const s_tag *tag, const s_sym **type);
-sw tag_type_size (e_tag_type type);
-f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
-f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type);
-f_buf_parse tag_type_to_buf_parse (e_tag_type type);
-const s8 * tag_type_to_string (e_tag_type type);
-const s_sym * tag_type_to_sym (e_tag_type tag_type);
+u64 tag_hash_u64 (const s_tag *tag);
+uw tag_hash_uw (const s_tag *tag);
+s_str * tag_inspect (const s_tag *tag, s_str *dest);
+bool tag_ident_is_bound (const s_tag *tag);
+bool tag_is_bound_var (const s_tag *tag);
+bool tag_is_number (const s_tag *tag);
+bool tag_is_unbound_var (const s_tag *tag);
+s8 tag_number_compare (const s_tag *a, const s_tag *b);
+sw tag_size (const s_tag *tag);
+ffi_type tag_to_ffi_type(const s_tag *tag);
+const s_sym ** tag_type (const s_tag *tag, const s_sym **type);
-/* Modifiers */
+/* Operators. */
s_tag * tag_1 (s_tag *tag, const s8 *p);
-s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
- const uw *dimensions);
-s_tag * tag_bool (s_tag *tag, bool p);
-s_tag * tag_cast_integer_to_s16 (s_tag *tag);
-s_tag * tag_cast_integer_to_s32 (s_tag *tag);
-s_tag * tag_cast_integer_to_s64 (s_tag *tag);
-s_tag * tag_cast_integer_to_s8 (s_tag *tag);
-s_tag * tag_cast_integer_to_u16 (s_tag *tag);
-s_tag * tag_cast_integer_to_u32 (s_tag *tag);
-s_tag * tag_cast_integer_to_u64 (s_tag *tag);
-s_tag * tag_cast_integer_to_u8 (s_tag *tag);
-s_tag * tag_character (s_tag *tag, character c);
-s_tag * tag_f32 (s_tag *tag, f32 f);
-s_tag * tag_f64 (s_tag *tag, f64 f);
-s_tag * tag_ident (s_tag *tag, const s_ident *ident);
-s_tag * tag_ident_1 (s_tag *tag, const s8 *p);
-s_tag * tag_integer (s_tag *tag, const s_integer *x);
-s_tag * tag_integer_1 (s_tag *tag, const s8 *p);
+s_tag * tag_integer_cast_to_s16 (const s_tag *tag, s_tag *dest);
+s_tag * tag_integer_cast_to_s32 (const s_tag *tag, s_tag *dest);
+s_tag * tag_integer_cast_to_s64 (const s_tag *tag, s_tag *dest);
+s_tag * tag_integer_cast_to_s8 (const s_tag *tag, s_tag *dest);
+s_tag * tag_integer_cast_to_u16 (const s_tag *tag, s_tag *dest);
+s_tag * tag_integer_cast_to_u32 (const s_tag *tag, s_tag *dest);
+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 (s_tag *tag, s_list *list);
-s_tag * tag_list_1 (s_tag *tag, const s8 *p);
-s_tag * tag_map (s_tag *tag, uw count);
-s_tag * tag_map_1 (s_tag *tag, const s8 *p);
-s_tag * tag_s16 (s_tag *tag, s16 i);
-s_tag * tag_s32 (s_tag *tag, s32 i);
-s_tag * tag_s64 (s_tag *tag, s64 i);
-s_tag * tag_s8 (s_tag *tag, s8 i);
-s_tag * tag_str (s_tag *tag, s8 *free, uw size, const s8 *p);
-s_tag * tag_str_1 (s_tag *tag, s8 *free, const s8 *p);
-s_tag * tag_sym (s_tag *tag, const s_sym *p);
-s_tag * tag_sym_1 (s_tag *tag, const s8 *p);
-s_tag * tag_tuple (s_tag *tag, uw count);
-s_tag * tag_tuple_2 (s_tag *tag, s_tag *a, s_tag *b);
-s_tag * tag_u16 (s_tag *tag, u16 i);
-s_tag * tag_u32 (s_tag *tag, u32 i);
-s_tag * tag_u64 (s_tag *tag, u64 i);
-s_tag * tag_u8 (s_tag *tag, u8 i);
-s_tag * tag_var (s_tag *tag);
-s_tag * tag_void (s_tag *tag);
+void * tag_to_ffi_pointer (s_tag *tag, const s_sym *type);
+void * tag_to_pointer (s_tag *tag, const s_sym *type);
-/* operators */
+/* C3 operators. */
s_tag * tag_add (const s_tag *a, const s_tag *b, s_tag *dest);
bool * tag_and (const s_tag *a, const s_tag *b, bool *dest);
s_tag * tag_band (const s_tag *a, const s_tag *b, s_tag *dest);
diff --git a/libc3/tag_div.c b/libc3/tag_div.c
index 0202994..c52d5b7 100644
--- a/libc3/tag_div.c
+++ b/libc3/tag_div.c
@@ -31,11 +31,8 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
case TAG_F64:
return tag_init_f64(dest, (f64) a->data.f32 / b->data.f64);
case TAG_INTEGER:
- integer_init_f32(&tmp, a->data.f32);
- integer_div(&tmp, &b->data.integer, &tmp);
- tag_init_integer(dest, &tmp);
- integer_clean(&tmp);
- return dest;
+ return tag_init_f32(dest, a->data.f32 /
+ integer_to_f32(&b->data.integer));
case TAG_S8:
return tag_init_f32(dest, a->data.f32 / (f32) b->data.s8);
case TAG_S16:
@@ -62,11 +59,8 @@ s_tag * tag_div (const s_tag *a, const s_tag *b, s_tag *dest)
case TAG_F64:
return tag_init_f64(dest, a->data.f64 / b->data.f64);
case TAG_INTEGER:
- integer_init_f64(&tmp, a->data.f64);
- integer_div(&tmp, &b->data.integer, &tmp);
- tag_init_integer(dest, &tmp);
- integer_clean(&tmp);
- return dest;
+ return tag_init_f64(dest, a->data.f64 /
+ integer_to_f64(&b->data.integer));
case TAG_S8:
return tag_init_f64(dest, a->data.f64 / (f64) b->data.s8);
case TAG_S16:
diff --git a/libc3/tag_init.c b/libc3/tag_init.c
new file mode 100644
index 0000000..fe5c68c
--- /dev/null
+++ b/libc3/tag_init.c
@@ -0,0 +1,1053 @@
+/* c3
+ * Copyright 2022,2023 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.
+ */
+#include <assert.h>
+#include <err.h>
+#include <string.h>
+#include "array.h"
+#include "buf.h"
+#include "buf_inspect.h"
+#include "buf_parse.h"
+#include "call.h"
+#include "cfn.h"
+#include "compare.h"
+#include "env.h"
+#include "fn.h"
+#include "frame.h"
+#include "hash.h"
+#include "ident.h"
+#include "integer.h"
+#include "list.h"
+#include "map.h"
+#include "quote.h"
+#include "str.h"
+#include "tag.h"
+#include "tag_init.h"
+#include "time.h"
+#include "tuple.h"
+
+s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
+ const uw *dimensions)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_ARRAY;
+ if (! array_init(&tmp.data.array, type, dimension, dimensions))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_bool (s_tag *tag, bool b)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_BOOL;
+ tmp.data.bool = b;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_call (s_tag *tag)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_CALL;
+ if (! call_init(&tmp.data.call))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_character (s_tag *tag, character c)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_CHARACTER;
+ tmp.data.character = c;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_f32 (s_tag *tag, f32 f)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_F32;
+ tmp.data.f32 = f;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_f64 (s_tag *tag, f64 f)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_F64;
+ tmp.data.f64 = f;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_ident (s_tag *tag, const s_ident *ident)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_IDENT;
+ tmp.data.ident = *ident;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_ident_1 (s_tag *tag, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_IDENT;
+ if (! ident_init_1(&tmp.data.ident, p))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_integer_copy (s_tag *tag, const s_integer *i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_INTEGER;
+ if (! integer_init_copy(&tmp.data.integer, i))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_integer_1 (s_tag *tag, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_INTEGER;
+ if (! integer_init_1(&tmp.data.integer, p))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_list_1 (s_tag *tag, const s8 *p, s_list *next)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_LIST;
+ if (! list_init_1(tmp.data.list, p, next))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_map (s_tag *tag, uw count)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_MAP;
+ if (! map_init(&tmp.data.map, count))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_map_1 (s_tag *tag, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_MAP;
+ if (! map_init_1(&tmp.data.map, p))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_s8 (s_tag *tag, s8 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_S8;
+ tmp.data.s8 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_s16 (s_tag *tag, s16 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_S16;
+ tmp.data.s16 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_s32 (s_tag *tag, s32 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_S32;
+ tmp.data.s32 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_s64 (s_tag *tag, s64 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_S64;
+ tmp.data.s64 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_str (s_tag *tag, s8 *p_free, uw size, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_STR;
+ if (! str_init(&tmp.data.str, p_free, size, p))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_str_1 (s_tag *tag, s8 *p_free, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_STR;
+ if (! str_init_1(&tmp.data.str, p_free, p))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_sw (s_tag *tag, sw i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_SW;
+ tmp.data.sw = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_sym (s_tag *tag, const s_sym *sym)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_SYM;
+ tmp.data.sym = sym;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_tuple (s_tag *tag, uw count)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_TUPLE;
+ if (! tuple_init(&tmp.data.tuple, count))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_TUPLE;
+ if (! tuple_init_2(&tmp.data.tuple, a, b))
+ return NULL;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_u8 (s_tag *tag, u8 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_U8;
+ tmp.data.u8 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_u16 (s_tag *tag, u16 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_U16;
+ tmp.data.u16 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_u32 (s_tag *tag, u32 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_U32;
+ tmp.data.u32 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_u64 (s_tag *tag, u64 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_U64;
+ tmp.data.u64 = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_uw (s_tag *tag, uw i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_UW;
+ tmp.data.uw = i;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_init_void (s_tag *tag)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tmp.type = TAG_VOID;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_new_array (const s_sym *type, uw dimension,
+ const uw *dimensions)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_array: calloc");
+ return NULL;
+ }
+ if (! array_init(&tag->data.array, type, dimension, dimensions)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_bool (bool b)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_bool: calloc");
+ return NULL;
+ }
+ tag->data.bool = b;
+ return tag;
+}
+
+s_tag * tag_new_call (void)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_call: calloc");
+ return NULL;
+ }
+ if (! call_init(&tag->data.call)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_character (character c)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_character: calloc");
+ return NULL;
+ }
+ tag->data.character = c;
+ return tag;
+}
+
+s_tag * tag_new_f32 (f32 f)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_f32: calloc");
+ return NULL;
+ }
+ tag->data.f32 = f;
+ return tag;
+}
+
+s_tag * tag_new_f64 (f64 f)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_f64: calloc");
+ return NULL;
+ }
+ tag->data.f64 = f;
+ return tag;
+}
+
+s_tag * tag_new_ident (const s_ident *ident)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_ident: calloc");
+ return NULL;
+ }
+ tag->data.ident = *ident;
+ return tag;
+}
+
+s_tag * tag_new_ident_1 (const s8 *p)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_ident_1: calloc");
+ return NULL;
+ }
+ if (! ident_init_1(&tag->data.ident, p)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_integer_copy (const s_integer *i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_integer_copy: calloc");
+ return NULL;
+ }
+ if (! integer_init_copy(&tag->data.integer, i)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_integer_1 (const s8 *p)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_integer_1: calloc");
+ return NULL;
+ }
+ if (! integer_init_1(&tag->data.integer, p)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_list_1 (const s8 *p, s_list *next)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_list_1: calloc");
+ return NULL;
+ }
+ if (! list_init_1(tag->data.list, p, next)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_map (uw count)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_map: calloc");
+ return NULL;
+ }
+ if (! map_init(&tag->data.map, count)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_map_1 (const s8 *p)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_map_1: calloc");
+ return NULL;
+ }
+ if (! map_init_1(&tag->data.map, p)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_s8 (s8 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_s8: calloc");
+ return NULL;
+ }
+ tag->data.s8 = i;
+ return tag;
+}
+
+s_tag * tag_new_s16 (s16 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_s16: calloc");
+ return NULL;
+ }
+ tag->data.s16 = i;
+ return tag;
+}
+
+s_tag * tag_new_s32 (s32 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_s32: calloc");
+ return NULL;
+ }
+ tag->data.s32 = i;
+ return tag;
+}
+
+s_tag * tag_new_s64 (s64 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_s64: calloc");
+ return NULL;
+ }
+ tag->data.s64 = i;
+ return tag;
+}
+
+s_tag * tag_new_str (s8 *p_free, uw size, const s8 *p)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_str: calloc");
+ return NULL;
+ }
+ if (! str_init(&tag->data.str, p_free, size, p)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_str_1 (s8 *p_free, const s8 *p)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_str_1: calloc");
+ return NULL;
+ }
+ if (! str_init_1(&tag->data.str, p_free, p)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_sw (sw i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_sw: calloc");
+ return NULL;
+ }
+ tag->data.sw = i;
+ return tag;
+}
+
+s_tag * tag_new_sym (const s_sym *sym)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_sym: calloc");
+ return NULL;
+ }
+ tag->data.sym = sym;
+ return tag;
+}
+
+s_tag * tag_new_tuple (uw count)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_tuple: calloc");
+ return NULL;
+ }
+ if (! tuple_init(&tag->data.tuple, count)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_tuple_2 (const s_tag *a, const s_tag *b)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_tuple_2: calloc");
+ return NULL;
+ }
+ if (! tuple_init_2(&tag->data.tuple, a, b)) {
+ free(tag);
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_new_u8 (u8 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_u8 : calloc");
+ return NULL;
+ }
+ tag->data.u8 = i;
+ return tag;
+}
+
+s_tag * tag_new_u16 (u16 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_u16: calloc");
+ return NULL;
+ }
+ tag->data.u16 = i;
+ return tag;
+}
+
+s_tag * tag_new_u32 (u32 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_u32: calloc");
+ return NULL;
+ }
+ tag->data.u32 = i;
+ return tag;
+}
+
+s_tag * tag_new_u64 (u64 i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_u64: calloc");
+ return NULL;
+ }
+ tag->data.u64 = i;
+ return tag;
+}
+
+s_tag * tag_new_uw (uw i)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_uw: calloc");
+ return NULL;
+ }
+ tag->data.uw = i;
+ return tag;
+}
+
+s_tag * tag_new_void (void)
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_void: calloc");
+ return NULL;
+ }
+ return tag;
+}
+
+s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
+ const uw *dimensions)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_ARRAY;
+ if (! array_init(&tmp.data.array, type, dimension, dimensions))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_bool (s_tag *tag, bool b)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_BOOL;
+ tmp.data.bool = b;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_call (s_tag *tag)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_CALL;
+ if (! call_init(&tmp.data.call))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_character (s_tag *tag, character c)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_CHARACTER;
+ tmp.data.character = c;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_f32 (s_tag *tag, f32 f)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_F32;
+ tmp.data.f32 = f;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_f64 (s_tag *tag, f64 f)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_F64;
+ tmp.data.f64 = f;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_ident (s_tag *tag, const s_ident *ident)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_IDENT;
+ tmp.data.ident = *ident;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_ident_1 (s_tag *tag, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_IDENT;
+ if (! ident_init_1(&tmp.data.ident, p))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_integer_copy (s_tag *tag, const s_integer *i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_INTEGER;
+ if (! integer_init_copy(&tmp.data.integer, i))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_integer_1 (s_tag *tag, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_INTEGER;
+ if (! integer_init_1(&tmp.data.integer, p))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_list_1 (s_tag *tag, const s8 *p, s_list *next)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_LIST;
+ if (! list_init_1(tmp.data.list, p, next))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_map (s_tag *tag, uw count)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_MAP;
+ if (! map_init(&tmp.data.map, count))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_map_1 (s_tag *tag, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_MAP;
+ if (! map_init_1(&tmp.data.map, p))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_s8 (s_tag *tag, s8 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_S8;
+ tmp.data.s8 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_s16 (s_tag *tag, s16 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_S16;
+ tmp.data.s16 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_s32 (s_tag *tag, s32 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_S32;
+ tmp.data.s32 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_s64 (s_tag *tag, s64 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_S64;
+ tmp.data.s64 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_str (s_tag *tag, s8 *p_free, uw size, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_STR;
+ if (! str_init(&tmp.data.str, p_free, size, p))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_str_1 (s_tag *tag, s8 *p_free, const s8 *p)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_STR;
+ if (! str_init_1(&tmp.data.str, p_free, p))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_sw (s_tag *tag, sw i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_SW;
+ tmp.data.sw = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_sym (s_tag *tag, const s_sym *sym)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_SYM;
+ tmp.data.sym = sym;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_tuple (s_tag *tag, uw count)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_TUPLE;
+ if (! tuple_init(&tmp.data.tuple, count))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_TUPLE;
+ if (! tuple_init_2(&tmp.data.tuple, a, b))
+ return NULL;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_u8 (s_tag *tag, u8 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_U8;
+ tmp.data.u8 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_u16 (s_tag *tag, u16 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_U16;
+ tmp.data.u16 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_u32 (s_tag *tag, u32 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_U32;
+ tmp.data.u32 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_u64 (s_tag *tag, u64 i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_U64;
+ tmp.data.u64 = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_uw (s_tag *tag, uw i)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_UW;
+ tmp.data.uw = i;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+
+s_tag * tag_void (s_tag *tag)
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ tmp.type = TAG_VOID;
+ *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
diff --git a/libc3/tag_init.h b/libc3/tag_init.h
new file mode 100644
index 0000000..c0ffec8
--- /dev/null
+++ b/libc3/tag_init.h
@@ -0,0 +1,129 @@
+/* c3
+ * Copyright 2022,2023 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 LIBC3_TAG_INIT_H
+#define LIBC3_TAG_INIT_H
+
+#include "types.h"
+
+/* Stack-allocation compatible functions, call tag_clean after use. */
+s_tag * tag_init_array (s_tag *tag, const s_sym *type, uw dimension,
+ const uw *dimensions);
+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_f32 (s_tag *tag, f32 f);
+s_tag * tag_init_f64 (s_tag *tag, f64 f);
+s_tag * tag_init_ident (s_tag *tag, const s_ident *ident);
+s_tag * tag_init_ident_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_integer_copy (s_tag *tag, const s_integer *i);
+s_tag * tag_init_integer_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_integer_zero (s_tag *tag);
+s_tag * tag_init_list (s_tag *tag, s_list *next);
+s_tag * tag_init_list_1 (s_tag *tag, const s8 *p, s_list *next);
+s_tag * tag_init_map (s_tag *tag, uw count);
+s_tag * tag_init_map_1 (s_tag *tag, const s8 *p);
+s_tag * tag_init_s8 (s_tag *tag, s8 i);
+s_tag * tag_init_s16 (s_tag *tag, s16 i);
+s_tag * tag_init_s32 (s_tag *tag, s32 i);
+s_tag * tag_init_s64 (s_tag *tag, s64 i);
+s_tag * tag_init_str (s_tag *tag, s8 *p_free, uw size, const s8 *p);
+s_tag * tag_init_str_1 (s_tag *tag, s8 *p_free, const s8 *p);
+s_tag * tag_init_sw (s_tag *tag, sw i);
+s_tag * tag_init_sym (s_tag *tag, const s_sym *sym);
+s_tag * tag_init_tuple (s_tag *tag, uw count);
+s_tag * tag_init_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b);
+s_tag * tag_init_time (s_tag *tag);
+s_tag * tag_init_u8 (s_tag *tag, u8 i);
+s_tag * tag_init_u16 (s_tag *tag, u16 i);
+s_tag * tag_init_u32 (s_tag *tag, u32 i);
+s_tag * tag_init_u64 (s_tag *tag, u64 i);
+s_tag * tag_init_uw (s_tag *tag, uw i);
+s_tag * tag_init_var (s_tag *tag);
+s_tag * tag_init_void (s_tag *tag);
+
+/* Heap-allocation functions, call tag_delete after use. */
+s_tag * tag_new_array (const s_sym *type, uw dimension,
+ const uw *dimensions);
+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_f32 (f32 f);
+s_tag * tag_new_f64 (f64 f);
+s_tag * tag_new_ident (const s_ident *ident);
+s_tag * tag_new_ident_1 (const s8 *p);
+s_tag * tag_new_integer_copy (const s_integer *i);
+s_tag * tag_new_integer_1 (const s8 *p);
+s_tag * tag_new_integer_zero (void);
+s_tag * tag_new_list (s_list *next);
+s_tag * tag_new_list_1 (const s8 *p, s_list *next);
+s_tag * tag_new_map (uw count);
+s_tag * tag_new_map_1 (const s8 *p);
+s_tag * tag_new_s8 (s8 i);
+s_tag * tag_new_s16 (s16 i);
+s_tag * tag_new_s32 (s32 i);
+s_tag * tag_new_s64 (s64 i);
+s_tag * tag_new_str (s8 *p_free, uw size, const s8 *p);
+s_tag * tag_new_str_1 (s8 *p_free, const s8 *p);
+s_tag * tag_new_sw (sw i);
+s_tag * tag_new_sym (const s_sym *sym);
+s_tag * tag_new_tuple (uw count);
+s_tag * tag_new_tuple_2 (const s_tag *a, const s_tag *b);
+s_tag * tag_new_time (void);
+s_tag * tag_new_u8 (u8 i);
+s_tag * tag_new_u16 (u16 i);
+s_tag * tag_new_u32 (u32 i);
+s_tag * tag_new_u64 (u64 i);
+s_tag * tag_new_uw (uw i);
+s_tag * tag_new_var (void);
+s_tag * tag_new_void (void);
+
+/* Setters. */
+s_tag * tag_array (s_tag *tag, const s_sym *type, uw dimension,
+ const uw *dimensions);
+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_f32 (s_tag *tag, f32 f);
+s_tag * tag_f64 (s_tag *tag, f64 f);
+s_tag * tag_ident (s_tag *tag, const s_ident *ident);
+s_tag * tag_ident_1 (s_tag *tag, const s8 *p);
+s_tag * tag_integer_copy (s_tag *tag, const s_integer *i);
+s_tag * tag_integer_1 (s_tag *tag, const s8 *p);
+s_tag * tag_integer_zero (s_tag *tag);
+s_tag * tag_list (s_tag *tag, s_list *next);
+s_tag * tag_list_1 (s_tag *tag, const s8 *p, s_list *next);
+s_tag * tag_map (s_tag *tag, uw count);
+s_tag * tag_map_1 (s_tag *tag, const s8 *p);
+s_tag * tag_s8 (s_tag *tag, s8 i);
+s_tag * tag_s16 (s_tag *tag, s16 i);
+s_tag * tag_s32 (s_tag *tag, s32 i);
+s_tag * tag_s64 (s_tag *tag, s64 i);
+s_tag * tag_str (s_tag *tag, s8 *p_free, uw size, const s8 *p);
+s_tag * tag_str_1 (s_tag *tag, s8 *p_free, const s8 *p);
+s_tag * tag_sw (s_tag *tag, sw i);
+s_tag * tag_sym (s_tag *tag, const s_sym *sym);
+s_tag * tag_tuple (s_tag *tag, uw count);
+s_tag * tag_tuple_2 (s_tag *tag, const s_tag *a, const s_tag *b);
+s_tag * tag_time (s_tag *tag);
+s_tag * tag_u8 (s_tag *tag, u8 i);
+s_tag * tag_u16 (s_tag *tag, u16 i);
+s_tag * tag_u32 (s_tag *tag, u32 i);
+s_tag * tag_u64 (s_tag *tag, u64 i);
+s_tag * tag_uw (s_tag *tag, uw i);
+s_tag * tag_var (s_tag *tag);
+s_tag * tag_void (s_tag *tag);
+
+#endif /* LIBC3_TAG_INIT_H */
diff --git a/libc3/tag_init.h.rb b/libc3/tag_init.h.rb
new file mode 100644
index 0000000..e2f3908
--- /dev/null
+++ b/libc3/tag_init.h.rb
@@ -0,0 +1,511 @@
+#!/usr/bin/env ruby
+
+class Arg
+ attr_reader :name
+ attr_reader :type
+ attr_reader :type_space
+
+ def initialize(type, name)
+ @type = type
+ @name = name
+ @type_space = type.match?(/\*$/) ? type : "#{type} "
+ end
+end
+
+class TagInit
+ attr_reader :args
+ attr_reader :args_list
+ attr_reader :args_proto
+ attr_reader :args_proto_comma
+ attr_reader :args_ptr
+ attr_reader :comma_args
+ attr_reader :comma_args_proto
+ attr_reader :first_arg_deref
+ attr_reader :init_mode
+ attr_reader :name
+ attr_reader :name_suffix
+ attr_reader :suffix
+ attr_reader :tag_type
+
+ def initialize(name, suffix = nil, tag_type, init_mode, args_list)
+ @name = name
+ @suffix = suffix ? "_#{suffix}" : nil
+ @tag_type = tag_type
+ @init_mode = init_mode
+ @args_list = args_list
+
+ @args = ""
+ @args_ptr = ""
+ @args_proto = ""
+ @comma_args = ""
+ @comma_args_proto = ""
+ @args_proto_comma = ""
+
+ @args_list.each do |arg|
+ @first_arg_deref ||= arg.type != "const s_sym *" &&
+ arg.type.match?(/\*$/) ?
+ "*#{arg.name}" : arg.name
+ @args = @args == "" ? arg.name : "#{@args}, #{arg.name}"
+ arg_ptr = "&#{arg.name}"
+ @args_ptr = @args_ptr == "" ? arg_ptr : "#{@args_ptr}, #{arg_ptr}"
+ arg_proto = "#{arg.type_space}#{arg.name}"
+ @args_proto = @args_proto == "" ? arg_proto :
+ "#{@args_proto}, #{arg_proto}"
+ @comma_args = "#{@comma_args}, #{arg.name}"
+ @comma_args_proto = "#{@comma_args_proto}, #{arg_proto}"
+ @args_proto_comma = "#{@args_proto_comma}#{arg_proto}, "
+ end
+
+ @args_proto = "void" if @args_proto == ""
+
+ @name_suffix = "#{name}#{@suffix}"
+end
+
+ def tag_proto
+ "s_tag * tag_#{name_suffix} (s_tag *tag#{comma_args_proto});"
+ end
+
+ def tag_init_proto
+ "s_tag * tag_init_#{name_suffix} (s_tag *tag#{comma_args_proto});"
+ end
+
+ def tag_new_proto
+ "s_tag * tag_new_#{name_suffix} (#{args_proto});"
+ end
+
+ def with_list?
+ ! ["1", "copy", "list"].include?(name)
+ end
+
+ def list_proto
+ if with_list?
+ "s_list * list_#{name_suffix} (s_list *list#{comma_args_proto});"
+ else
+ ""
+ end
+ end
+
+ def list_init_proto
+ if with_list?
+ "s_list * list_init_#{name_suffix} (s_list *list#{comma_args_proto}, s_list *next);"
+ else
+ ""
+ end
+ end
+
+ def list_new_proto
+ if with_list?
+ "s_list * list_new_#{name_suffix} (#{args_proto_comma}s_list *next);"
+ else
+ ""
+ end
+ end
+
+ def def_tag
+ <<EOF
+
+#{tag_proto[0..-2]}
+{
+ s_tag tmp = {0};
+ assert(tag);
+ tag_clean(tag);
+ #{tag_type ? "tmp.type = #{tag_type};\n" : ""}#{def_tag_init_init} *tag = tmp;
+ *tag = tmp;
+ return tag;
+}
+EOF
+ end
+
+ def def_tag_init
+ <<EOF
+
+#{tag_init_proto[0..-2]}
+{
+ s_tag tmp = {0};
+ assert(tag);
+ #{tag_type ? "tmp.type = #{tag_type};\n" : ""}#{def_tag_init_init} *tag = tmp;
+ return tag;
+}
+EOF
+ end
+
+ def def_tag_init_init
+ case init_mode
+ when :init_mode_none
+ ""
+ when :init_mode_init
+ " if (! #{name}_init#{suffix}(#{name == "list" ? "" : "&"}tmp.data.#{name}#{comma_args}))
+ return NULL;
+"
+ when :init_mode_direct
+ " tmp.data.#{name} = #{first_arg_deref};
+"
+ when :init_mode_buf_parse
+ " s_buf buf;
+ uw len;
+ sw r;
+ len = strlen(p);
+ if (! buf_init(&buf, false, len, p))
+ return NULL;
+ if ((r = buf_parse_#{name}(&buf, &tmp.data.#{name}) < 0)
+ return NULL;
+ else if (r != len) {
+ #{name}_clean(&tmp);
+ return NULL;
+ }
+"
+ else
+ raise "unknown init mode: #{init_mode}"
+ end
+ end
+
+ def def_tag_new
+ <<EOF
+
+#{tag_new_proto[0..-2]}
+{
+ s_tag *tag;
+ if (! (tag = calloc(1, sizeof(s_tag)))) {
+ warn("tag_new_#{name_suffix}: calloc");
+ return NULL;
+ }
+#{def_tag_new_init} return tag;
+}
+EOF
+ end
+
+ def def_tag_new_init
+ case init_mode
+ when :init_mode_none
+ ""
+ when :init_mode_init
+ " if (! #{name}_init#{suffix}(#{name == "list" ? "" : "&"}tag->data.#{name}#{comma_args})) {
+ free(tag);
+ return NULL;
+ }
+"
+ when :init_mode_direct
+ " tag->data.#{name} = #{first_arg_deref};
+"
+ when :init_mode_buf_parse
+ " s_buf buf;
+ uw len;
+ sw r;
+ len = strlen(p);
+ if (! buf_init(&buf, false, len, p))
+ return NULL;
+ if ((r = buf_parse_#{name}(&buf, &tmp.data.#{name}) < 0)
+ return NULL;
+ else if (r != len) {
+ #{name}_clean(&tmp);
+ return NULL;
+ }
+"
+ else
+ raise "unknown init mode: #{init_mode}"
+ end
+ end
+
+ def def_list_init
+ """
+"""
+ end
+end
+
+class TagInitProto < TagInit
+ def def_tag
+ ""
+ end
+
+ def def_tag_init
+ ""
+ end
+
+ def def_tag_new
+ ""
+ end
+
+ def def_list
+ ""
+ end
+
+ def def_list_init
+ ""
+ end
+
+ def def_list_new
+ ""
+ end
+end
+
+class TagInit1 < TagInit
+ def initialize(name, suffix, tag_type, init_mode = :init_mode_init,
+ args_list = [Arg.new("const s8 *", "p")])
+ super(name, suffix, tag_type, init_mode, args_list)
+ end
+end
+
+class FileUpdate
+ attr_reader :path
+ attr_accessor :content
+ attr_reader :content_old
+
+ def initialize(path)
+ @path = path
+ @content_old = (File.read(path) rescue "")
+ end
+
+ def commit
+ if @content != @content_old
+ puts @path
+ File.rename(@path, "#{@path}~") if File.exist?(@path)
+ File.write(@path, @content)
+ end
+ end
+end
+
+class TagInitList
+ attr_accessor :items
+
+ def self.all
+ new(
+ [TagInit.new("array", "TAG_ARRAY", :init_mode_init,
+ [Arg.new("const s_sym *", "type"),
+ Arg.new("uw", "dimension"),
+ Arg.new("const uw *", "dimensions")]),
+ TagInit.new("bool", "TAG_BOOL", :init_mode_direct,
+ [Arg.new("bool", "b")]),
+ TagInit.new("call", "TAG_CALL", :init_mode_init, []),
+ 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")]),
+ TagInit.new("f32", "TAG_F32", :init_mode_direct,
+ [Arg.new("f32", "f")]),
+ TagInit.new("f64", "TAG_F64", :init_mode_direct,
+ [Arg.new("f64", "f")]),
+ TagInit.new("ident", "TAG_IDENT", :init_mode_direct,
+ [Arg.new("const s_ident *", "ident")]),
+ TagInit1.new("ident", "1", "TAG_IDENT", :init_mode_init),
+ TagInit.new("integer", "copy", "TAG_INTEGER", :init_mode_init,
+ [Arg.new("const s_integer *", "i")]),
+ TagInit1.new("integer", "1", "TAG_INTEGER", :init_mode_init),
+ TagInitProto.new("integer_zero", "TAG_INTEGER", :init_mode_init,
+ []),
+ TagInitProto.new("list", "TAG_LIST", :init_mode_init,
+ [Arg.new("s_list *", "next")]),
+ TagInit1.new("list", "1", "TAG_LIST", :init_mode_init,
+ [Arg.new("const s8 *", "p"),
+ Arg.new("s_list *", "next")]),
+ TagInit.new("map", "TAG_MAP", :init_mode_init,
+ [Arg.new("uw", "count")]),
+ TagInit1.new("map", "1", "TAG_MAP", :init_mode_init),
+ TagInit.new("s8", "TAG_S8", :init_mode_direct,
+ [Arg.new("s8", "i")]),
+ TagInit.new("s16", "TAG_S16", :init_mode_direct,
+ [Arg.new("s16", "i")]),
+ TagInit.new("s32", "TAG_S32", :init_mode_direct,
+ [Arg.new("s32", "i")]),
+ TagInit.new("s64", "TAG_S64", :init_mode_direct,
+ [Arg.new("s64", "i")]),
+ TagInit.new("str", "TAG_STR", :init_mode_init,
+ [Arg.new("s8 *", "p_free"),
+ Arg.new("uw", "size"),
+ Arg.new("const s8 *", "p")]),
+ TagInit.new("str", "1", "TAG_STR", :init_mode_init,
+ [Arg.new("s8 *", "p_free"),
+ Arg.new("const s8 *", "p")]),
+ TagInit.new("sw", "TAG_SW", :init_mode_direct,
+ [Arg.new("sw", "i")]),
+ TagInit.new("sym", "TAG_SYM", :init_mode_direct,
+ [Arg.new("const s_sym *", "sym")]),
+ TagInit.new("tuple", "TAG_TUPLE", :init_mode_init,
+ [Arg.new("uw", "count")]),
+ TagInit.new("tuple", "2", "TAG_TUPLE", :init_mode_init,
+ [Arg.new("const s_tag *", "a"),
+ Arg.new("const s_tag *", "b")]),
+ TagInitProto.new("time", "TAG_TIME", :init_mode_none, []),
+ TagInit.new("u8 ", "TAG_U8", :init_mode_direct,
+ [Arg.new("u8", "i")]),
+ TagInit.new("u16", "TAG_U16", :init_mode_direct,
+ [Arg.new("u16", "i")]),
+ TagInit.new("u32", "TAG_U32", :init_mode_direct,
+ [Arg.new("u32", "i")]),
+ TagInit.new("u64", "TAG_U64", :init_mode_direct,
+ [Arg.new("u64", "i")]),
+ TagInit.new("uw", "TAG_UW", :init_mode_direct,
+ [Arg.new("uw", "i")]),
+ TagInitProto.new("var", "TAG_VAR", :init_mode_none, []),
+ TagInit.new("void", "TAG_VOID", :init_mode_none, [])])
+ end
+
+ def initialize(items)
+ @items = items
+ end
+
+ def tag_proto
+ protos = @items.map &:tag_proto
+ protos.join "\n"
+ end
+
+ def tag_init_proto
+ protos = @items.map &:tag_init_proto
+ protos.join "\n"
+ end
+
+ def tag_new_proto
+ protos = @items.map &:tag_new_proto
+ protos.join "\n"
+ end
+
+ def list_proto
+ protos = @items.map &:list_proto
+ protos.join "\n"
+ end
+
+ def list_init_proto
+ protos = @items.map &:list_init_proto
+ protos.join "\n"
+ end
+
+ def list_new_proto
+ protos = @items.map &:list_new_proto
+ protos.join "\n"
+ end
+
+ def def_tag
+ protos = @items.map &:def_tag
+ protos.join
+ end
+
+ def def_tag_init
+ protos = @items.map &:def_tag_init
+ protos.join
+ end
+
+ def def_tag_new
+ protos = @items.map &:def_tag_new
+ protos.join
+ end
+
+ def def_list
+ protos = @items.map &:def_list
+ protos.join
+ end
+
+ def def_list_init
+ protos = @items.map &:def_list_init
+ protos.join
+ end
+
+ def def_list_new
+ protos = @items.map &:def_list_new
+ protos.join
+ end
+end
+
+$license = File.read("../license.h").strip
+
+def h_header(name)
+ "#{$license}
+#ifndef #{name}
+#define #{name}
+
+#include \"types.h\""
+end
+
+def h_footer(name)
+ "#endif /* #{name} */"
+end
+
+class String
+ def c_word_wrap
+ lines = split("\n")
+ wrapped_lines = []
+ lines.each do |line|
+ rest = line
+ while rest.length > 72
+ space_pos = rest[0..71].rindex(/,\s/)
+ space_pos += 1 if space_pos
+ space_pos ||= rest[0..71].rindex(/[\*\s]/)
+ line1 = rest[0..space_pos]
+ rest = rest[(space_pos + 1)..(rest.length - 1)]
+ wrapped_lines += [line1]
+ index = line1.rindex(/[\(\{\[]/)
+ if index
+ paren_pos = index + 1
+ end
+ rest = paren_pos ? (" " * paren_pos + rest) : rest
+ end
+ wrapped_lines += [rest]
+ end
+ wrapped_lines.join("\n")
+ end
+end
+
+inits = TagInitList.all
+
+tag_init_c = FileUpdate.new("tag_init.c")
+tag_init_c.content = <<EOF
+#{$license}
+#include <assert.h>
+#include <err.h>
+#include <string.h>
+#include "array.h"
+#include "buf.h"
+#include "buf_inspect.h"
+#include "buf_parse.h"
+#include "call.h"
+#include "cfn.h"
+#include "compare.h"
+#include "env.h"
+#include "fn.h"
+#include "frame.h"
+#include "hash.h"
+#include "ident.h"
+#include "integer.h"
+#include "list.h"
+#include "map.h"
+#include "quote.h"
+#include "str.h"
+#include "tag.h"
+#include "tag_init.h"
+#include "time.h"
+#include "tuple.h"
+#{inits.def_tag_init.c_word_wrap}
+#{inits.def_tag_new.c_word_wrap}
+#{inits.def_tag.c_word_wrap}
+EOF
+tag_init_c.commit
+
+tag_init_h = FileUpdate.new("tag_init.h")
+tag_init_h.content = """#{h_header("LIBC3_TAG_INIT_H")}
+
+/* Stack-allocation compatible functions, call tag_clean after use. */
+#{inits.tag_init_proto.c_word_wrap}
+
+/* Heap-allocation functions, call tag_delete after use. */
+#{inits.tag_new_proto.c_word_wrap}
+
+/* Setters. */
+#{inits.tag_proto.c_word_wrap}
+
+#{h_footer("LIBC3_TAG_INIT_H")}
+"""
+tag_init_h.commit
+
+list_init_h = FileUpdate.new("list_init.h")
+list_init_h.content = """#{h_header("LIBC3_LIST_INIT_H")}
+
+/* Stack-allocation compatible functions, call list_clean after use. */
+#{inits.list_init_proto.c_word_wrap}
+
+/* Heap-allocation functions, call tag_delete after use. */
+#{inits.list_new_proto.c_word_wrap}
+
+/* Setters. */
+#{inits.list_proto.c_word_wrap}
+
+#{h_footer("LIBC3_LIST_INIT_H")}
+"""
+list_init_h.commit
diff --git a/libc3/tag_type.c b/libc3/tag_type.c
new file mode 100644
index 0000000..2dea490
--- /dev/null
+++ b/libc3/tag_type.c
@@ -0,0 +1,422 @@
+/* c3
+ * Copyright 2022,2023 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.
+ */
+#include <assert.h>
+#include <err.h>
+#include "buf_inspect.h"
+#include "buf_parse.h"
+#include "sym.h"
+#include "tag_type.h"
+
+sw tag_type_size (e_tag_type type)
+{
+ switch (type) {
+ case TAG_VOID:
+ return 0;
+ case TAG_ARRAY:
+ assert(! "tag_type_size: TAG_ARRAY: not implemented");
+ errx(1, "tag_type_size: TAG_ARRAY: not implemented");
+ return -1;
+ case TAG_BOOL:
+ return sizeof(bool);
+ case TAG_CALL:
+ return sizeof(s_call);
+ case TAG_CFN:
+ return sizeof(s_cfn);
+ case TAG_CHARACTER:
+ return sizeof(character);
+ case TAG_F32:
+ return sizeof(f32);
+ case TAG_F64:
+ return sizeof(f64);
+ case TAG_FACT:
+ return sizeof(s_fact);
+ case TAG_FN:
+ return sizeof(s_fn);
+ case TAG_IDENT:
+ return sizeof(s_ident);
+ case TAG_INTEGER:
+ return sizeof(s_integer);
+ case TAG_SW:
+ return sizeof(sw);
+ case TAG_S64:
+ return sizeof(s64);
+ case TAG_S32:
+ return sizeof(s32);
+ case TAG_S16:
+ return sizeof(s16);
+ case TAG_S8:
+ return sizeof(s8);
+ case TAG_U8:
+ return sizeof(u8);
+ case TAG_U16:
+ return sizeof(u16);
+ case TAG_U32:
+ return sizeof(u32);
+ case TAG_U64:
+ return sizeof(u64);
+ case TAG_UW:
+ return sizeof(uw);
+ case TAG_LIST:
+ return sizeof(s_list *);
+ case TAG_MAP:
+ return sizeof(s_map);
+ case TAG_PTAG:
+ return sizeof(p_tag);
+ case TAG_PTR:
+ return sizeof(void *);
+ case TAG_QUOTE:
+ return sizeof(s_quote);
+ case TAG_STR:
+ return sizeof(s_str);
+ case TAG_SYM:
+ return sizeof(s_sym *);
+ case TAG_TUPLE:
+ return sizeof(s_tuple);
+ case TAG_VAR:
+ return sizeof(s_tag);
+ }
+ assert(! "tag_type_size: invalid tag type");
+ errx(1, "tag_type_size: invalid tag type: %d", type);
+ return -1;
+}
+
+f_buf_inspect tag_type_to_buf_inspect (e_tag_type type)
+{
+ switch (type) {
+ case TAG_VOID:
+ return (f_buf_inspect) buf_inspect_void;
+ case TAG_ARRAY:
+ case TAG_BOOL:
+ return (f_buf_inspect) buf_inspect_bool;
+ case TAG_CALL:
+ return (f_buf_inspect) buf_inspect_call;
+ case TAG_CFN:
+ return (f_buf_inspect) buf_inspect_cfn;
+ case TAG_CHARACTER:
+ return (f_buf_inspect) buf_inspect_character;
+ case TAG_F32:
+ return (f_buf_inspect) buf_inspect_f32;
+ case TAG_F64:
+ return (f_buf_inspect) buf_inspect_f64;
+ case TAG_FACT:
+ return (f_buf_inspect) buf_inspect_fact;
+ case TAG_FN:
+ return (f_buf_inspect) buf_inspect_fn;
+ case TAG_IDENT:
+ return (f_buf_inspect) buf_inspect_ident;
+ case TAG_INTEGER:
+ return (f_buf_inspect) buf_inspect_integer;
+ case TAG_SW:
+ return (f_buf_inspect) buf_inspect_sw;
+ case TAG_S64:
+ return (f_buf_inspect) buf_inspect_s64;
+ case TAG_S32:
+ return (f_buf_inspect) buf_inspect_s32;
+ case TAG_S16:
+ return (f_buf_inspect) buf_inspect_s16;
+ case TAG_S8:
+ return (f_buf_inspect) buf_inspect_s8;
+ case TAG_U8:
+ return (f_buf_inspect) buf_inspect_u8;
+ case TAG_U16:
+ return (f_buf_inspect) buf_inspect_u16;
+ case TAG_U32:
+ return (f_buf_inspect) buf_inspect_u32;
+ case TAG_U64:
+ return (f_buf_inspect) buf_inspect_u64;
+ case TAG_UW:
+ return (f_buf_inspect) buf_inspect_uw;
+ case TAG_LIST:
+ return (f_buf_inspect) buf_inspect_list;
+ case TAG_MAP:
+ return (f_buf_inspect) buf_inspect_map;
+ case TAG_PTAG:
+ return (f_buf_inspect) buf_inspect_ptag;
+ case TAG_PTR:
+ return (f_buf_inspect) buf_inspect_ptr;
+ case TAG_QUOTE:
+ return (f_buf_inspect) buf_inspect_quote;
+ case TAG_STR:
+ return (f_buf_inspect) buf_inspect_str;
+ case TAG_SYM:
+ return (f_buf_inspect) buf_inspect_sym;
+ case TAG_TUPLE:
+ return (f_buf_inspect) buf_inspect_tuple;
+ case TAG_VAR:
+ return (f_buf_inspect) buf_inspect_var;
+ }
+ assert(! "buf_inspect: unknown tag type");
+ errx(1, "buf_inspect: unknown tag type");
+ return NULL;
+}
+
+f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type)
+{
+ switch (type) {
+ case TAG_VOID:
+ return (f_buf_inspect_size) buf_inspect_void_size;
+ case TAG_ARRAY:
+ return (f_buf_inspect_size) buf_inspect_array_size;
+ case TAG_BOOL:
+ return (f_buf_inspect_size) buf_inspect_bool_size;
+ case TAG_CALL:
+ return (f_buf_inspect_size) buf_inspect_call_size;
+ case TAG_CFN:
+ return (f_buf_inspect_size) buf_inspect_cfn_size;
+ case TAG_CHARACTER:
+ return (f_buf_inspect_size) buf_inspect_character_size;
+ case TAG_F32:
+ return (f_buf_inspect_size) buf_inspect_f32_size;
+ case TAG_F64:
+ return (f_buf_inspect_size) buf_inspect_f64_size;
+ case TAG_FACT:
+ return (f_buf_inspect_size) buf_inspect_fact_size;
+ case TAG_FN:
+ return (f_buf_inspect_size) buf_inspect_fn_size;
+ case TAG_IDENT:
+ return (f_buf_inspect_size) buf_inspect_ident_size;
+ case TAG_INTEGER:
+ return (f_buf_inspect_size) buf_inspect_integer_size;
+ case TAG_SW:
+ return (f_buf_inspect_size) buf_inspect_sw_size;
+ case TAG_S64:
+ return (f_buf_inspect_size) buf_inspect_s64_size;
+ case TAG_S32:
+ return (f_buf_inspect_size) buf_inspect_s32_size;
+ case TAG_S16:
+ return (f_buf_inspect_size) buf_inspect_s16_size;
+ case TAG_S8:
+ return (f_buf_inspect_size) buf_inspect_s8_size;
+ case TAG_U8:
+ return (f_buf_inspect_size) buf_inspect_u8_size;
+ case TAG_U16:
+ return (f_buf_inspect_size) buf_inspect_u16_size;
+ case TAG_U32:
+ return (f_buf_inspect_size) buf_inspect_u32_size;
+ case TAG_U64:
+ return (f_buf_inspect_size) buf_inspect_u64_size;
+ case TAG_UW:
+ return (f_buf_inspect_size) buf_inspect_uw_size;
+ case TAG_LIST:
+ return (f_buf_inspect_size) buf_inspect_list_size;
+ case TAG_MAP:
+ return (f_buf_inspect_size) buf_inspect_map_size;
+ case TAG_PTAG:
+ return (f_buf_inspect_size) buf_inspect_ptag_size;
+ case TAG_PTR:
+ return (f_buf_inspect_size) buf_inspect_ptr_size;
+ case TAG_QUOTE:
+ return (f_buf_inspect_size) buf_inspect_quote_size;
+ case TAG_STR:
+ return (f_buf_inspect_size) buf_inspect_str_size;
+ case TAG_SYM:
+ return (f_buf_inspect_size) buf_inspect_sym_size;
+ case TAG_TUPLE:
+ return (f_buf_inspect_size) buf_inspect_tuple_size;
+ case TAG_VAR:
+ return (f_buf_inspect_size) buf_inspect_var_size;
+ }
+ assert(! "tag_type_to_buf_inspect_size: unknown tag type");
+ errx(1, "tag_type_to_buf_inspect_size: unknown tag type");
+ return NULL;
+}
+
+f_buf_parse tag_type_to_buf_parse (e_tag_type type)
+{
+ switch (type) {
+ case TAG_VOID:
+ return (f_buf_parse) buf_parse_void;
+ case TAG_ARRAY:
+ return (f_buf_parse) buf_parse_array;
+ case TAG_BOOL:
+ return (f_buf_parse) buf_parse_bool;
+ case TAG_CALL:
+ return (f_buf_parse) buf_parse_call;
+ case TAG_CFN:
+ return (f_buf_parse) buf_parse_cfn;
+ case TAG_CHARACTER:
+ return (f_buf_parse) buf_parse_character;
+ case TAG_F32:
+ return (f_buf_parse) buf_parse_f32;
+ case TAG_F64:
+ return (f_buf_parse) buf_parse_f64;
+ case TAG_FACT:
+ return (f_buf_parse) buf_parse_fact;
+ case TAG_FN:
+ return (f_buf_parse) buf_parse_fn;
+ case TAG_IDENT:
+ return (f_buf_parse) buf_parse_ident;
+ case TAG_INTEGER:
+ return (f_buf_parse) buf_parse_integer;
+ case TAG_SW:
+ return (f_buf_parse) buf_parse_sw;
+ case TAG_S64:
+ return (f_buf_parse) buf_parse_s64;
+ case TAG_S32:
+ return (f_buf_parse) buf_parse_s32;
+ case TAG_S16:
+ return (f_buf_parse) buf_parse_s16;
+ case TAG_S8:
+ return (f_buf_parse) buf_parse_s8;
+ case TAG_U8:
+ return (f_buf_parse) buf_parse_u8;
+ case TAG_U16:
+ return (f_buf_parse) buf_parse_u16;
+ case TAG_U32:
+ return (f_buf_parse) buf_parse_u32;
+ case TAG_U64:
+ return (f_buf_parse) buf_parse_u64;
+ case TAG_UW:
+ return (f_buf_parse) buf_parse_uw;
+ case TAG_LIST:
+ return (f_buf_parse) buf_parse_list;
+ case TAG_MAP:
+ return (f_buf_parse) buf_parse_map;
+ case TAG_PTAG:
+ return (f_buf_parse) buf_parse_ptag;
+ case TAG_PTR:
+ return (f_buf_parse) buf_parse_ptr;
+ case TAG_QUOTE:
+ return (f_buf_parse) buf_parse_quote;
+ case TAG_STR:
+ return (f_buf_parse) buf_parse_str;
+ case TAG_SYM:
+ return (f_buf_parse) buf_parse_sym;
+ case TAG_TUPLE:
+ return (f_buf_parse) buf_parse_tuple;
+ case TAG_VAR:
+ return (f_buf_parse) buf_parse_var;
+ }
+ assert(! "tag_type_to_buf_parse: invalid tag type");
+ err(1, "tag_type_to_buf_parse: invalid tag type");
+ return NULL;
+}
+
+ffi_type * tag_type_to_ffi_type (e_tag_type type)
+{
+ switch (type) {
+ case TAG_ARRAY:
+ return &ffi_type_pointer;
+ case TAG_BOOL:
+ return &ffi_type_uint8;
+ case TAG_CALL:
+ return &ffi_type_pointer;
+ case TAG_CFN:
+ return &ffi_type_pointer;
+ case TAG_CHARACTER:
+ return &ffi_type_schar;
+ case TAG_F32:
+ return &ffi_type_float;
+ case TAG_F64:
+ return &ffi_type_double;
+ case TAG_FACT:
+ return &ffi_type_pointer;
+ case TAG_FN:
+ return &ffi_type_pointer;
+ case TAG_IDENT:
+ return &ffi_type_pointer;
+ case TAG_INTEGER:
+ return &ffi_type_sint;
+ case TAG_LIST:
+ return &ffi_type_pointer;
+ case TAG_MAP:
+ return &ffi_type_pointer;
+ case TAG_PTAG:
+ return &ffi_type_pointer;
+ case TAG_PTR:
+ return &ffi_type_pointer;
+ case TAG_QUOTE:
+ return &ffi_type_pointer;
+ case TAG_S8:
+ return &ffi_type_sint8;
+ case TAG_S16:
+ return &ffi_type_sint16;
+ case TAG_S32:
+ return &ffi_type_sint32;
+ case TAG_S64:
+ return &ffi_type_sint64;
+ case TAG_SW:
+ return &ffi_type_slong;
+ case TAG_STR:
+ return &ffi_type_pointer;
+ case TAG_SYM:
+ return &ffi_type_pointer;
+ case TAG_TUPLE:
+ return &ffi_type_pointer;
+ case TAG_U8:
+ return &ffi_type_uint8;
+ case TAG_U16:
+ return &ffi_type_uint16;
+ case TAG_U32:
+ return &ffi_type_uint32;
+ case TAG_U64:
+ return &ffi_type_uint64;
+ case TAG_UW:
+ return &ffi_type_ulong;
+ case TAG_VAR:
+ return &ffi_type_pointer;
+ case TAG_VOID:
+ return &ffi_type_void;
+ }
+ assert(! "tag_type_to_ffi_type: unknown tag type");
+ errx(1, "tag_type_to_ffi_type: unknown tag type");
+ return &ffi_type_void;
+}
+
+const s8 * tag_type_to_string (e_tag_type type)
+{
+ const s_sym *sym;
+ if (! (sym = tag_type_to_sym(type)))
+ return NULL;
+ return sym->str.ptr.ps8;
+}
+
+const s_sym * tag_type_to_sym (e_tag_type tag_type)
+{
+ switch (tag_type) {
+ case TAG_VOID: return sym_1("Void");
+ case TAG_ARRAY: return sym_1("Array");
+ case TAG_BOOL: return sym_1("Bool");
+ case TAG_CALL: return sym_1("Call");
+ case TAG_CFN: return sym_1("Cfn");
+ case TAG_CHARACTER: return sym_1("Character");
+ case TAG_F32: return sym_1("F32");
+ case TAG_F64: return sym_1("F64");
+ case TAG_FACT: return sym_1("Fact");
+ case TAG_FN: return sym_1("Fn");
+ case TAG_IDENT: return sym_1("Ident");
+ case TAG_INTEGER: return sym_1("Integer");
+ case TAG_SW: return sym_1("Sw");
+ case TAG_S64: return sym_1("S64");
+ case TAG_S32: return sym_1("S32");
+ case TAG_S16: return sym_1("S16");
+ case TAG_S8: return sym_1("S8");
+ case TAG_U8: return sym_1("U8");
+ case TAG_U16: return sym_1("U16");
+ case TAG_U32: return sym_1("U32");
+ case TAG_U64: return sym_1("U64");
+ case TAG_UW: return sym_1("Uw");
+ case TAG_LIST: return sym_1("List");
+ case TAG_MAP: return sym_1("Map");
+ case TAG_PTAG: return sym_1("Ptag");
+ case TAG_PTR: return sym_1("Void*");
+ case TAG_QUOTE: return sym_1("Quote");
+ case TAG_STR: return sym_1("Str");
+ case TAG_SYM: return sym_1("Sym");
+ case TAG_TUPLE: return sym_1("Tuple");
+ case TAG_VAR: return sym_1("Var");
+ }
+ assert(! "tag_type_to_sym: invalid tag type");
+ errx(1, "tag_type_to_sym: invalid tag type: %d", tag_type);
+ return NULL;
+}
diff --git a/libc3/tag_type.h b/libc3/tag_type.h
new file mode 100644
index 0000000..9816f78
--- /dev/null
+++ b/libc3/tag_type.h
@@ -0,0 +1,31 @@
+/* c3
+ * Copyright 2022,2023 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.
+ */
+/**
+ * @file tag.h
+ * @brief Run-time type annotations enum.
+ *
+ * Enum for run-time tagged data types.
+ */
+#ifndef LIBC3_TAG_TYPE_H
+#define LIBC3_TAG_TYPE_H
+
+#include "types.h"
+
+sw tag_type_size (e_tag_type type);
+f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
+f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type);
+f_buf_parse tag_type_to_buf_parse (e_tag_type type);
+const s8 * tag_type_to_string (e_tag_type type);
+const s_sym * tag_type_to_sym (e_tag_type tag_type);
+
+#endif /* LIBC3_TAG_TYPE */
diff --git a/libc3/types.h b/libc3/types.h
index 3a11620..c046b83 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -226,15 +226,10 @@ struct frame {
s_frame *next;
};
-/* TODO: perfect hashing of keys with cookie */
struct map {
uw count;
s_tag *keys; /* sorted (see tag_compare) */
s_tag *values;
- /*
- uw *key_hash_table;
- uw key_hash_cookie;
- */
};
struct ptr {
@@ -258,12 +253,6 @@ struct quote {
s_tag *tag;
};
-struct struct_ {
- void *data;
- uw count;
- e_tag_type type;
-};
-
struct sym_list {
s_sym *sym;
s_sym_list *next;
@@ -328,6 +317,12 @@ struct str {
u_ptr ptr; /**< Pointer to memory. */
};
+struct struct_ {
+ s_map map;
+ const s_sym *module;
+ void **data;
+};
+
/* 3 */
struct call {
/* key */
diff --git a/libc3/u.c.in b/libc3/u.c.in
index 5c0388a..3884e48 100644
--- a/libc3/u.c.in
+++ b/libc3/u.c.in
@@ -94,7 +94,7 @@ u_bits$ * u_bits$_cast (s_tag *tag, u_bits$ *dest)
return 0;
ko:
warnx("u_bits$_cast: cannot cast %s to u_bits$",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/u16.c b/libc3/u16.c
index d1986ef..301fac6 100644
--- a/libc3/u16.c
+++ b/libc3/u16.c
@@ -94,7 +94,7 @@ u16 * u16_cast (s_tag *tag, u16 *dest)
return 0;
ko:
warnx("u16_cast: cannot cast %s to u16",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/u32.c b/libc3/u32.c
index 486b351..7edb5dd 100644
--- a/libc3/u32.c
+++ b/libc3/u32.c
@@ -94,7 +94,7 @@ u32 * u32_cast (s_tag *tag, u32 *dest)
return 0;
ko:
warnx("u32_cast: cannot cast %s to u32",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/u64.c b/libc3/u64.c
index ffe871f..07ace50 100644
--- a/libc3/u64.c
+++ b/libc3/u64.c
@@ -94,7 +94,7 @@ u64 * u64_cast (s_tag *tag, u64 *dest)
return 0;
ko:
warnx("u64_cast: cannot cast %s to u64",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/u8.c b/libc3/u8.c
index afd4ca9..8501bbf 100644
--- a/libc3/u8.c
+++ b/libc3/u8.c
@@ -94,7 +94,7 @@ u8 * u8_cast (s_tag *tag, u8 *dest)
return 0;
ko:
warnx("u8_cast: cannot cast %s to u8",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/uw.c b/libc3/uw.c
index 8c4626f..3304628 100644
--- a/libc3/uw.c
+++ b/libc3/uw.c
@@ -94,7 +94,7 @@ uw * uw_cast (s_tag *tag, uw *dest)
return 0;
ko:
warnx("uw_cast: cannot cast %s to uw",
- tag_type_to_sym(tag->type)->str.ptr.ps8);
+ tag_type_to_string(tag->type));
return 0;
}
diff --git a/libc3/window/cairo/demo/window_cairo_demo.c b/libc3/window/cairo/demo/window_cairo_demo.c
index 2f7acfc..90362ba 100644
--- a/libc3/window/cairo/demo/window_cairo_demo.c
+++ b/libc3/window/cairo/demo/window_cairo_demo.c
@@ -77,7 +77,7 @@ bool window_cairo_demo_load (s_window_cairo *window)
window_cairo_sequence_init(window->sequence, 8.0,
"01. Background rectangles",
bg_rect_load, bg_rect_render);
- window_cairo_sequence_init(window->sequence + 1, 30.0,
+ window_cairo_sequence_init(window->sequence + 1, 20.0,
"02. Lightspeed",
lightspeed_load, lightspeed_render);
if (! cairo_sprite_init(&g_toaster_sprite,
diff --git a/sources.mk b/sources.mk
index 254ba54..ed06394 100644
--- a/sources.mk
+++ b/sources.mk
@@ -95,6 +95,7 @@ C3_C_SOURCES = \
libc3/list.c \
libc3/buf_inspect_u64.c \
libc3/facts.h \
+ libc3/tag_type.h \
libc3/buf_inspect_u16_decimal.c \
libc3/tag_sub.c \
libc3/facts_with_cursor.c \
@@ -175,6 +176,7 @@ C3_C_SOURCES = \
libc3/buf_inspect_uw_binary.c \
libc3/buf_inspect_uw_decimal.h \
libc3/facts_spec_cursor.c \
+ libc3/tag_init.c \
libc3/u64.h \
libc3/buf_inspect_u_base.h.in \
libc3/buf_inspect_s32_octal.h \
@@ -211,6 +213,7 @@ C3_C_SOURCES = \
libc3/u32.c \
libc3/hash.c \
libc3/buf_file.h \
+ libc3/struct.h \
libc3/integer.c \
libc3/buf_inspect_u8.c \
libc3/facts_spec.c \
@@ -219,6 +222,7 @@ C3_C_SOURCES = \
libc3/tag_bxor.c \
libc3/s64.h \
libc3/buf_inspect_u16_decimal.h \
+ libc3/tag_type.c \
libc3/facts.c \
libc3/buf_inspect_u64.h \
libc3/buf_inspect_sw_decimal.h \
@@ -280,6 +284,7 @@ C3_C_SOURCES = \
libc3/window/cairo/xcb/window_cairo_xcb.c \
libc3/window/cairo/types.h \
libc3/window/cairo/window_cairo.c \
+ libc3/window/cairo/cairo_font.h \
libc3/window/cairo/cairo_png.h \
libc3/window/cairo/cairo_sprite.h \
libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c \
@@ -291,6 +296,7 @@ C3_C_SOURCES = \
libc3/window/cairo/quartz/xkbquartz.h \
libc3/window/cairo/quartz/window_cairo_quartz_view.h \
libc3/window/cairo/window_cairo.h \
+ libc3/window/cairo/cairo_font.c \
libc3/window/cairo/win32/demo/window_cairo_win32_demo.c \
libc3/window/cairo/win32/vk_to_xkbcommon.c \
libc3/window/cairo/win32/window_cairo_win32.h \
@@ -336,6 +342,7 @@ C3_C_SOURCES = \
libc3/error_handler.h \
libc3/u64.c \
libc3/buf_inspect_s32_octal.c \
+ libc3/tag_init.h \
libc3/tag_mul.c \
libc3/facts_spec_cursor.h \
libc3/buf_inspect_uw_decimal.c \
@@ -386,6 +393,7 @@ C3_C_SOURCES = \
libc3/set_cursor__tag.c \
libc3/set_cursor__fact.h \
libc3/buf.c \
+ libc3/list_init.h \
libc3/abs.c \
libc3/buf_parse_s64.h \
libc3/buf_inspect_s.c.in \
diff --git a/sources.sh b/sources.sh
index e793dde..3565be3 100644
--- a/sources.sh
+++ b/sources.sh
@@ -1,4 +1,4 @@
# sources.sh generated by update_sources
C3_CONFIGURES='c3c/configure c3s/configure c3s/update_sources ic3/configure ic3/update_sources libc3/configure libc3/update_sources libc3/window/configure libc3/window/update_sources libc3/window/cairo/demo/configure libc3/window/cairo/demo/update_sources libc3/window/cairo/xcb/demo/configure libc3/window/cairo/xcb/demo/update_sources libc3/window/cairo/xcb/configure libc3/window/cairo/xcb/update_sources libc3/window/cairo/configure libc3/window/cairo/update_sources libc3/window/cairo/quartz/demo/configure libc3/window/cairo/quartz/demo/update_sources libc3/window/cairo/quartz/configure libc3/window/cairo/quartz/update_sources libc3/window/cairo/win32/demo/configure libc3/window/cairo/win32/demo/update_sources libc3/window/cairo/win32/configure libc3/window/cairo/win32/update_sources libtommath/configure libtommath/update_sources test/configure test/update_sources ucd2c/configure '
C3_MAKEFILES='c3c/Makefile c3s/Makefile ic3/Makefile libc3/Makefile libc3/gen.mk libc3/window/Makefile libc3/window/cairo/demo/Makefile libc3/window/cairo/xcb/demo/Makefile libc3/window/cairo/xcb/Makefile libc3/window/cairo/Makefile libc3/window/cairo/quartz/demo/Makefile libc3/window/cairo/quartz/Makefile libc3/window/cairo/win32/demo/Makefile libc3/window/cairo/win32/Makefile libtommath/Makefile test/Makefile ucd2c/Makefile '
-C3_C_SOURCES='c3c/c3c.c c3s/buf_readline.c c3s/c3s.c c3s/buf_readline.h ic3/buf_linenoise.h ic3/ic3.c ic3/linenoise.c ic3/buf_linenoise.c libc3/buf_inspect_s_base.c.in libc3/type.h libc3/fact.c libc3/time.h libc3/fn.h libc3/s16.h libc3/buf_inspect_s8_octal.h libc3/log.c libc3/error.h libc3/buf_inspect_u64_octal.h libc3/set_item.h.in libc3/compare.c libc3/buf_inspect_s8_binary.h libc3/buf_inspect_uw_hexadecimal.h libc3/uw.c libc3/eval.c libc3/set__fact.c libc3/sym.h libc3/env.h libc3/cfn.c libc3/buf_inspect_u16_octal.h libc3/u.h.in libc3/buf_parse_s16.c libc3/s8.h libc3/quote.h libc3/buf_inspect_s32.h libc3/buf_inspect.c libc3/buf_parse_u.h.in libc3/skiplist_node__fact.h libc3/skiplist__fact.c libc3/tag_add.c libc3/buf_inspect_s32_hexadecimal.h libc3/ceiling.h libc3/list.c libc3/buf_inspect_u64.c libc3/facts.h libc3/buf_inspect_u16_decimal.c libc3/tag_sub.c libc3/facts_with_cursor.c libc3/buf_inspect_sw_decimal.c libc3/facts_cursor.c libc3/buf_inspect_u64_binary.h libc3/buf_inspect_sw_hexadecimal.h libc3/buf_inspect_s32_decimal.h libc3/u16.h libc3/buf_inspect_s64_octal.h libc3/buf_inspect_u8_binary.h libc3/buf_inspect_s8.h libc3/buf_inspect_s16_octal.h libc3/ucd.c libc3/buf_inspect_s16_binary.h libc3/tuple.c libc3/buf_inspect_uw_octal.h libc3/buf_parse_u8.c libc3/tag.h libc3/float.h libc3/buf_inspect_u_base.c.in libc3/buf_parse_u16.c libc3/buf_inspect_u16_hexadecimal.h libc3/buf_inspect_s8_decimal.c libc3/buf_inspect_u32.h libc3/array.c libc3/buf_parse_sw.h libc3/set.h.in libc3/s.c.in libc3/buf_parse_s.c.in libc3/map.h libc3/skiplist.h.in libc3/set__tag.h libc3/buf_inspect_s64.c libc3/io.c libc3/set_item__tag.c libc3/sequence.c libc3/types.h libc3/buf_inspect_uw.c libc3/buf_inspect_u32_binary.c libc3/buf_inspect_s64_decimal.h libc3/set_cursor.c.in libc3/ident.c libc3/buf_inspect_s64_hexadecimal.c libc3/bool.h libc3/s.h.in libc3/set.c.in libc3/skiplist.c.in libc3/operator.h libc3/fn_clause.h libc3/buf_parse_s.h.in libc3/buf_inspect_s16.c libc3/binding.c libc3/ptag.h libc3/buf_parse_s32.h libc3/tag_bor.c libc3/var.h libc3/tag_shift_left.c libc3/set_item__fact.h libc3/u8.c libc3/set_cursor.h.in libc3/f32.c libc3/buf_inspect_sw_octal.h libc3/c3.h libc3/arg.h libc3/buf_inspect_u8_hexadecimal.c libc3/buf_inspect_u32_hexadecimal.h libc3/buf_parse_u64.c libc3/module.c libc3/frame.h libc3/buf_inspect_s16_decimal.c libc3/file.h libc3/sw.h libc3/s32.c libc3/error_handler.c libc3/str.c libc3/buf_parse.h libc3/buf_inspect_uw_binary.c libc3/buf_inspect_uw_decimal.h libc3/facts_spec_cursor.c libc3/u64.h libc3/buf_inspect_u_base.h.in libc3/buf_inspect_s32_octal.h libc3/f64.h libc3/buf_inspect_u8_octal.h libc3/buf_inspect_s64_binary.c libc3/buf_inspect_u64_hexadecimal.c libc3/buf_inspect_u16_binary.c libc3/buf_save.h libc3/buf_inspect_u16.c libc3/buf_inspect_s8_hexadecimal.c libc3/u.c.in libc3/buf_inspect_sw.h libc3/facts_with.c libc3/buf_parse_u.c.in libc3/buf_parse_u32.h libc3/set_cursor__fact.c libc3/buf.h libc3/set_cursor__tag.h libc3/buf_inspect_s16_hexadecimal.h libc3/buf_inspect_u32_decimal.h libc3/buf_parse_uw.c libc3/buf_parse_s64.c libc3/abs.h libc3/buf_inspect_sw_binary.c libc3/buf_parse_s8.h libc3/call.h libc3/sign.c libc3/buf_inspect_u8_decimal.h libc3/character.h libc3/buf_inspect_u64_decimal.h libc3/buf_inspect_s_base.h.in libc3/buf_inspect_u32_octal.h libc3/u32.c libc3/hash.c libc3/buf_file.h libc3/integer.c libc3/buf_inspect_u8.c libc3/facts_spec.c libc3/buf_inspect_s32_binary.h libc3/set_item.c.in libc3/tag_bxor.c libc3/s64.h libc3/buf_inspect_u16_decimal.h libc3/facts.c libc3/buf_inspect_u64.h libc3/buf_inspect_sw_decimal.h libc3/facts_with_cursor.h libc3/skiplist_node__fact.c libc3/buf_inspect.h libc3/quote.c libc3/buf_inspect_s32.c libc3/skiplist_node.h.in libc3/s8.c libc3/buf_parse_s16.h libc3/list.h libc3/ceiling.c libc3/buf_inspect_s.h.in libc3/buf_inspect_s32_hexadecimal.c libc3/skiplist__fact.h libc3/uw.h libc3/buf_inspect_uw_hexadecimal.c libc3/buf_inspect_s8_binary.c libc3/tag_mod.c libc3/compare.h libc3/buf_inspect_u64_octal.c libc3/buf_inspect_u16_octal.c libc3/tag_band.c libc3/cfn.h libc3/env.c libc3/set__fact.h libc3/sym.c libc3/eval.h libc3/c3_main.h libc3/buf_inspect_s8_octal.c libc3/s16.c libc3/fn.c libc3/time.c libc3/fact.h libc3/type.c libc3/error.c libc3/log.h libc3/sequence.h libc3/set_item__tag.h libc3/io.h libc3/buf_inspect_s64.h libc3/buf_inspect_s64_hexadecimal.h libc3/window/types.h libc3/window/window.h libc3/window/cairo/demo/toasters.h libc3/window/cairo/demo/window_cairo_demo.c libc3/window/cairo/demo/lightspeed.h libc3/window/cairo/demo/flies.h libc3/window/cairo/demo/bg_rect.h libc3/window/cairo/demo/window_cairo_demo.h libc3/window/cairo/demo/toasters.c libc3/window/cairo/demo/lightspeed.c libc3/window/cairo/demo/flies.c libc3/window/cairo/demo/bg_rect.c libc3/window/cairo/xcb/demo/window_cairo_xcb_demo.c libc3/window/cairo/xcb/window_cairo_xcb.h libc3/window/cairo/xcb/config.h libc3/window/cairo/xcb/window_cairo_xcb.c libc3/window/cairo/types.h libc3/window/cairo/window_cairo.c libc3/window/cairo/cairo_png.h libc3/window/cairo/cairo_sprite.h libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c libc3/window/cairo/quartz/window_cairo_quartz_view_controller.h libc3/window/cairo/quartz/quartz_to_xkbcommon.c libc3/window/cairo/quartz/window_cairo_quartz.h libc3/window/cairo/quartz/window_cairo_quartz_app_delegate.h libc3/window/cairo/quartz/quartz_to_xkbcommon.h libc3/window/cairo/quartz/xkbquartz.h libc3/window/cairo/quartz/window_cairo_quartz_view.h libc3/window/cairo/window_cairo.h libc3/window/cairo/win32/demo/window_cairo_win32_demo.c libc3/window/cairo/win32/vk_to_xkbcommon.c libc3/window/cairo/win32/window_cairo_win32.h libc3/window/cairo/win32/vk_to_xkbcommon.h libc3/window/cairo/win32/window_cairo_win32.c libc3/window/cairo/cairo_sprite.c libc3/window/cairo/cairo_png.c libc3/window/window.c libc3/ident.h libc3/buf_inspect_s64_decimal.c libc3/buf_inspect_u32_binary.h libc3/buf_inspect_uw.h libc3/buf_inspect_u.c.in libc3/buf_parse_sw.c libc3/array.h libc3/buf_inspect_u32.c libc3/buf_inspect_s8_decimal.h libc3/buf_inspect_u16_hexadecimal.c libc3/buf_parse_u16.h libc3/set__tag.c libc3/map.c libc3/tag_shift_right.c libc3/tag.c libc3/buf_parse_u8.h libc3/buf_inspect_uw_octal.c libc3/buf_inspect_u8_binary.c libc3/tag_div.c libc3/buf_inspect_s64_octal.c libc3/u16.c libc3/buf_inspect_sw_hexadecimal.c libc3/buf_inspect_s32_decimal.c libc3/buf_inspect_u64_binary.c libc3/facts_cursor.h libc3/tuple.h libc3/buf_inspect_s16_binary.c libc3/ucd.h libc3/buf_inspect_s16_octal.c libc3/buf_inspect_s8.c libc3/sha1.h libc3/buf_inspect_uw_binary.h libc3/buf_parse.c libc3/str.h libc3/error_handler.h libc3/u64.c libc3/buf_inspect_s32_octal.c libc3/tag_mul.c libc3/facts_spec_cursor.h libc3/buf_inspect_uw_decimal.c libc3/sw.c libc3/file.c libc3/buf_inspect_s16_decimal.h libc3/frame.c libc3/s32.h libc3/c3.c libc3/f32.h libc3/buf_inspect_sw_octal.c libc3/u8.h libc3/set_item__fact.c libc3/var.c libc3/module.h libc3/license.c libc3/buf_inspect_u32_hexadecimal.c libc3/buf_parse_u64.h libc3/buf_inspect_u8_hexadecimal.h libc3/arg.c libc3/fn_clause.c libc3/operator.c libc3/bool.c libc3/buf_parse_s32.c libc3/ptag.c libc3/binding.h libc3/buf_inspect_u.h.in libc3/buf_inspect_s16.h libc3/integer.h libc3/buf_file.c libc3/s64.c libc3/buf_inspect_s32_binary.c libc3/buf_inspect_u8.h libc3/facts_spec.h libc3/buf_inspect_u8_decimal.c libc3/sign.h libc3/call.c libc3/buf_parse_s8.c libc3/buf_inspect_sw_binary.h libc3/hash.h libc3/u32.h libc3/buf_inspect_u32_octal.c libc3/character.c libc3/buf_inspect_u64_decimal.c libc3/buf_parse_uw.h libc3/buf_inspect_u32_decimal.c libc3/buf_inspect_s16_hexadecimal.c libc3/set_cursor__tag.c libc3/set_cursor__fact.h libc3/buf.c libc3/abs.c libc3/buf_parse_s64.h libc3/buf_inspect_s.c.in libc3/buf_inspect_s64_binary.h libc3/buf_inspect_u8_octal.c libc3/f64.c libc3/skiplist_node.c.in libc3/buf_parse_u32.c libc3/facts_with.h libc3/buf_inspect_sw.c libc3/buf_inspect_u16.h libc3/buf_inspect_s8_hexadecimal.h libc3/buf_inspect_u16_binary.h libc3/buf_inspect_u64_hexadecimal.h libc3/buf_save.c test/ident_test.c test/buf_parse_test_s16.c test/buf_inspect_test.c test/libc3_test.c test/fn_test.c test/buf_parse_test_u16.c test/str_test.c test/cfn_test.c test/character_test.c test/buf_parse_test_s8.c test/skiplist__fact_test.c test/sym_test.c test/tag_test.h test/buf_file_test.c test/bool_test.c test/fact_test.h test/buf_parse_test_u64.c test/compare_test.c test/facts_with_test.c test/array_test.c test/buf_parse_test.h test/test.h test/buf_parse_test_su.h test/env_test.c test/buf_parse_test_s64.c test/types_test.c test/hash_test.c test/call_test.c test/set__tag_test.c test/facts_test.c test/facts_cursor_test.c test/compare_test.h test/buf_parse_test_s32.c test/test.c test/buf_parse_test.c test/fact_test.c test/tag_test.c test/set__fact_test.c test/buf_parse_test_u32.c test/buf_test.c test/list_test.c test/buf_parse_test_u8.c test/tuple_test.c ucd2c/ucd.h ucd2c/ucd2c.c '
+C3_C_SOURCES='c3c/c3c.c c3s/buf_readline.c c3s/c3s.c c3s/buf_readline.h ic3/buf_linenoise.h ic3/ic3.c ic3/linenoise.c ic3/buf_linenoise.c libc3/buf_inspect_s_base.c.in libc3/type.h libc3/fact.c libc3/time.h libc3/fn.h libc3/s16.h libc3/buf_inspect_s8_octal.h libc3/log.c libc3/error.h libc3/buf_inspect_u64_octal.h libc3/set_item.h.in libc3/compare.c libc3/buf_inspect_s8_binary.h libc3/buf_inspect_uw_hexadecimal.h libc3/uw.c libc3/eval.c libc3/set__fact.c libc3/sym.h libc3/env.h libc3/cfn.c libc3/buf_inspect_u16_octal.h libc3/u.h.in libc3/buf_parse_s16.c libc3/s8.h libc3/quote.h libc3/buf_inspect_s32.h libc3/buf_inspect.c libc3/buf_parse_u.h.in libc3/skiplist_node__fact.h libc3/skiplist__fact.c libc3/tag_add.c libc3/buf_inspect_s32_hexadecimal.h libc3/ceiling.h libc3/list.c libc3/buf_inspect_u64.c libc3/facts.h libc3/tag_type.h libc3/buf_inspect_u16_decimal.c libc3/tag_sub.c libc3/facts_with_cursor.c libc3/buf_inspect_sw_decimal.c libc3/facts_cursor.c libc3/buf_inspect_u64_binary.h libc3/buf_inspect_sw_hexadecimal.h libc3/buf_inspect_s32_decimal.h libc3/u16.h libc3/buf_inspect_s64_octal.h libc3/buf_inspect_u8_binary.h libc3/buf_inspect_s8.h libc3/buf_inspect_s16_octal.h libc3/ucd.c libc3/buf_inspect_s16_binary.h libc3/tuple.c libc3/buf_inspect_uw_octal.h libc3/buf_parse_u8.c libc3/tag.h libc3/float.h libc3/buf_inspect_u_base.c.in libc3/buf_parse_u16.c libc3/buf_inspect_u16_hexadecimal.h libc3/buf_inspect_s8_decimal.c libc3/buf_inspect_u32.h libc3/array.c libc3/buf_parse_sw.h libc3/set.h.in libc3/s.c.in libc3/buf_parse_s.c.in libc3/map.h libc3/skiplist.h.in libc3/set__tag.h libc3/buf_inspect_s64.c libc3/io.c libc3/set_item__tag.c libc3/sequence.c libc3/types.h libc3/buf_inspect_uw.c libc3/buf_inspect_u32_binary.c libc3/buf_inspect_s64_decimal.h libc3/set_cursor.c.in libc3/ident.c libc3/buf_inspect_s64_hexadecimal.c libc3/bool.h libc3/s.h.in libc3/set.c.in libc3/skiplist.c.in libc3/operator.h libc3/fn_clause.h libc3/buf_parse_s.h.in libc3/buf_inspect_s16.c libc3/binding.c libc3/ptag.h libc3/buf_parse_s32.h libc3/tag_bor.c libc3/var.h libc3/tag_shift_left.c libc3/set_item__fact.h libc3/u8.c libc3/set_cursor.h.in libc3/f32.c libc3/buf_inspect_sw_octal.h libc3/c3.h libc3/arg.h libc3/buf_inspect_u8_hexadecimal.c libc3/buf_inspect_u32_hexadecimal.h libc3/buf_parse_u64.c libc3/module.c libc3/frame.h libc3/buf_inspect_s16_decimal.c libc3/file.h libc3/sw.h libc3/s32.c libc3/error_handler.c libc3/str.c libc3/buf_parse.h libc3/buf_inspect_uw_binary.c libc3/buf_inspect_uw_decimal.h libc3/facts_spec_cursor.c libc3/tag_init.c libc3/u64.h libc3/buf_inspect_u_base.h.in libc3/buf_inspect_s32_octal.h libc3/f64.h libc3/buf_inspect_u8_octal.h libc3/buf_inspect_s64_binary.c libc3/buf_inspect_u64_hexadecimal.c libc3/buf_inspect_u16_binary.c libc3/buf_save.h libc3/buf_inspect_u16.c libc3/buf_inspect_s8_hexadecimal.c libc3/u.c.in libc3/buf_inspect_sw.h libc3/facts_with.c libc3/buf_parse_u.c.in libc3/buf_parse_u32.h libc3/set_cursor__fact.c libc3/buf.h libc3/set_cursor__tag.h libc3/buf_inspect_s16_hexadecimal.h libc3/buf_inspect_u32_decimal.h libc3/buf_parse_uw.c libc3/buf_parse_s64.c libc3/abs.h libc3/buf_inspect_sw_binary.c libc3/buf_parse_s8.h libc3/call.h libc3/sign.c libc3/buf_inspect_u8_decimal.h libc3/character.h libc3/buf_inspect_u64_decimal.h libc3/buf_inspect_s_base.h.in libc3/buf_inspect_u32_octal.h libc3/u32.c libc3/hash.c libc3/buf_file.h libc3/struct.h libc3/integer.c libc3/buf_inspect_u8.c libc3/facts_spec.c libc3/buf_inspect_s32_binary.h libc3/set_item.c.in libc3/tag_bxor.c libc3/s64.h libc3/buf_inspect_u16_decimal.h libc3/tag_type.c libc3/facts.c libc3/buf_inspect_u64.h libc3/buf_inspect_sw_decimal.h libc3/facts_with_cursor.h libc3/skiplist_node__fact.c libc3/buf_inspect.h libc3/quote.c libc3/buf_inspect_s32.c libc3/skiplist_node.h.in libc3/s8.c libc3/buf_parse_s16.h libc3/list.h libc3/ceiling.c libc3/buf_inspect_s.h.in libc3/buf_inspect_s32_hexadecimal.c libc3/skiplist__fact.h libc3/uw.h libc3/buf_inspect_uw_hexadecimal.c libc3/buf_inspect_s8_binary.c libc3/tag_mod.c libc3/compare.h libc3/buf_inspect_u64_octal.c libc3/buf_inspect_u16_octal.c libc3/tag_band.c libc3/cfn.h libc3/env.c libc3/set__fact.h libc3/sym.c libc3/eval.h libc3/c3_main.h libc3/buf_inspect_s8_octal.c libc3/s16.c libc3/fn.c libc3/time.c libc3/fact.h libc3/type.c libc3/error.c libc3/log.h libc3/sequence.h libc3/set_item__tag.h libc3/io.h libc3/buf_inspect_s64.h libc3/buf_inspect_s64_hexadecimal.h libc3/window/types.h libc3/window/window.h libc3/window/cairo/demo/toasters.h libc3/window/cairo/demo/window_cairo_demo.c libc3/window/cairo/demo/lightspeed.h libc3/window/cairo/demo/flies.h libc3/window/cairo/demo/bg_rect.h libc3/window/cairo/demo/window_cairo_demo.h libc3/window/cairo/demo/toasters.c libc3/window/cairo/demo/lightspeed.c libc3/window/cairo/demo/flies.c libc3/window/cairo/demo/bg_rect.c libc3/window/cairo/xcb/demo/window_cairo_xcb_demo.c libc3/window/cairo/xcb/window_cairo_xcb.h libc3/window/cairo/xcb/config.h libc3/window/cairo/xcb/window_cairo_xcb.c libc3/window/cairo/types.h libc3/window/cairo/window_cairo.c libc3/window/cairo/cairo_font.h libc3/window/cairo/cairo_png.h libc3/window/cairo/cairo_sprite.h libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c libc3/window/cairo/quartz/window_cairo_quartz_view_controller.h libc3/window/cairo/quartz/quartz_to_xkbcommon.c libc3/window/cairo/quartz/window_cairo_quartz.h libc3/window/cairo/quartz/window_cairo_quartz_app_delegate.h libc3/window/cairo/quartz/quartz_to_xkbcommon.h libc3/window/cairo/quartz/xkbquartz.h libc3/window/cairo/quartz/window_cairo_quartz_view.h libc3/window/cairo/window_cairo.h libc3/window/cairo/cairo_font.c libc3/window/cairo/win32/demo/window_cairo_win32_demo.c libc3/window/cairo/win32/vk_to_xkbcommon.c libc3/window/cairo/win32/window_cairo_win32.h libc3/window/cairo/win32/vk_to_xkbcommon.h libc3/window/cairo/win32/window_cairo_win32.c libc3/window/cairo/cairo_sprite.c libc3/window/cairo/cairo_png.c libc3/window/window.c libc3/ident.h libc3/buf_inspect_s64_decimal.c libc3/buf_inspect_u32_binary.h libc3/buf_inspect_uw.h libc3/buf_inspect_u.c.in libc3/buf_parse_sw.c libc3/array.h libc3/buf_inspect_u32.c libc3/buf_inspect_s8_decimal.h libc3/buf_inspect_u16_hexadecimal.c libc3/buf_parse_u16.h libc3/set__tag.c libc3/map.c libc3/tag_shift_right.c libc3/tag.c libc3/buf_parse_u8.h libc3/buf_inspect_uw_octal.c libc3/buf_inspect_u8_binary.c libc3/tag_div.c libc3/buf_inspect_s64_octal.c libc3/u16.c libc3/buf_inspect_sw_hexadecimal.c libc3/buf_inspect_s32_decimal.c libc3/buf_inspect_u64_binary.c libc3/facts_cursor.h libc3/tuple.h libc3/buf_inspect_s16_binary.c libc3/ucd.h libc3/buf_inspect_s16_octal.c libc3/buf_inspect_s8.c libc3/sha1.h libc3/buf_inspect_uw_binary.h libc3/buf_parse.c libc3/str.h libc3/error_handler.h libc3/u64.c libc3/buf_inspect_s32_octal.c libc3/tag_init.h libc3/tag_mul.c libc3/facts_spec_cursor.h libc3/buf_inspect_uw_decimal.c libc3/sw.c libc3/file.c libc3/buf_inspect_s16_decimal.h libc3/frame.c libc3/s32.h libc3/c3.c libc3/f32.h libc3/buf_inspect_sw_octal.c libc3/u8.h libc3/set_item__fact.c libc3/var.c libc3/module.h libc3/license.c libc3/buf_inspect_u32_hexadecimal.c libc3/buf_parse_u64.h libc3/buf_inspect_u8_hexadecimal.h libc3/arg.c libc3/fn_clause.c libc3/operator.c libc3/bool.c libc3/buf_parse_s32.c libc3/ptag.c libc3/binding.h libc3/buf_inspect_u.h.in libc3/buf_inspect_s16.h libc3/integer.h libc3/buf_file.c libc3/s64.c libc3/buf_inspect_s32_binary.c libc3/buf_inspect_u8.h libc3/facts_spec.h libc3/buf_inspect_u8_decimal.c libc3/sign.h libc3/call.c libc3/buf_parse_s8.c libc3/buf_inspect_sw_binary.h libc3/hash.h libc3/u32.h libc3/buf_inspect_u32_octal.c libc3/character.c libc3/buf_inspect_u64_decimal.c libc3/buf_parse_uw.h libc3/buf_inspect_u32_decimal.c libc3/buf_inspect_s16_hexadecimal.c libc3/set_cursor__tag.c libc3/set_cursor__fact.h libc3/buf.c libc3/list_init.h libc3/abs.c libc3/buf_parse_s64.h libc3/buf_inspect_s.c.in libc3/buf_inspect_s64_binary.h libc3/buf_inspect_u8_octal.c libc3/f64.c libc3/skiplist_node.c.in libc3/buf_parse_u32.c libc3/facts_with.h libc3/buf_inspect_sw.c libc3/buf_inspect_u16.h libc3/buf_inspect_s8_hexadecimal.h libc3/buf_inspect_u16_binary.h libc3/buf_inspect_u64_hexadecimal.h libc3/buf_save.c test/ident_test.c test/buf_parse_test_s16.c test/buf_inspect_test.c test/libc3_test.c test/fn_test.c test/buf_parse_test_u16.c test/str_test.c test/cfn_test.c test/character_test.c test/buf_parse_test_s8.c test/skiplist__fact_test.c test/sym_test.c test/tag_test.h test/buf_file_test.c test/bool_test.c test/fact_test.h test/buf_parse_test_u64.c test/compare_test.c test/facts_with_test.c test/array_test.c test/buf_parse_test.h test/test.h test/buf_parse_test_su.h test/env_test.c test/buf_parse_test_s64.c test/types_test.c test/hash_test.c test/call_test.c test/set__tag_test.c test/facts_test.c test/facts_cursor_test.c test/compare_test.h test/buf_parse_test_s32.c test/test.c test/buf_parse_test.c test/fact_test.c test/tag_test.c test/set__fact_test.c test/buf_parse_test_u32.c test/buf_test.c test/list_test.c test/buf_parse_test_u8.c test/tuple_test.c ucd2c/ucd.h ucd2c/ucd2c.c '