diff --git a/README.md b/README.md
index 691238f..e1c67ec 100644
--- a/README.md
+++ b/README.md
@@ -97,6 +97,9 @@ Script interpreter. Under development.
- gaussian
- buf_sha256
- buf_popen
+ - tests
+ - `(-S8_MIN - S8_MAX) == 1`
+ - `UW_MAX == ((1 << 8 * sizeof(uw)) - 1)`
- DONE ci
- DONE c function call
- DONE infix operators
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 14e0075..9eb8de4 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -286,8 +286,8 @@ sw buf_parse_call_args_paren (s_buf *buf, s_call *dest)
if ((r = buf_parse_tag(buf, &tag)) <= 0)
goto restore;
result += r;
- *args = list_new(NULL);
- (*args)->tag = tag;
+ *args = list_new(NULL, NULL);
+ (*args)->tag = tag;
if ((r = buf_parse_comments(buf)) < 0)
goto restore;
result += r;
@@ -539,7 +539,7 @@ sw buf_parse_cfn_arg_types (s_buf *buf, s_list **dest)
result += r;
tail = &tmp;
while (1) {
- *tail = list_new(NULL);
+ *tail = list_new(NULL, NULL);
if ((r = buf_parse_tag_sym(buf, &(*tail)->tag)) <= 0)
goto restore;
result += r;
@@ -671,31 +671,26 @@ sw buf_parse_comments (s_buf *buf)
return r;
}
-sw buf_parse_digit (s_buf *buf, const s_str *bases, uw bases_count,
- u8 *dest)
+sw buf_parse_digit (s_buf *buf, const s_str *base, u8 *dest)
{
character c;
sw digit;
- uw i = 0;
sw r;
assert(buf);
assert(bases);
assert(bases_count);
if ((r = buf_peek_character_utf8(buf, &c)) <= 0)
return r;
- while (i < bases_count) {
- if ((digit = str_character_position(bases + i, c)) >= 0) {
- if (digit > 255) {
- assert(! "buf_parse_digit: digit overflow");
- errx(1, "buf_parse_digit: digit overflow: %ld", digit);
- return -1;
- }
- if ((r = buf_read_character_utf8(buf, &c)) <= 0)
- return r;
- *dest = digit;
- return r;
+ if ((digit = str_character_position(base, c)) >= 0) {
+ if (digit > 255) {
+ assert(! "buf_parse_digit: digit overflow");
+ errx(1, "buf_parse_digit: digit overflow: %ld", digit);
+ return -1;
}
- i++;
+ if ((r = buf_read_character_utf8(buf, &c)) <= 0)
+ return r;
+ *dest = digit;
+ return r;
}
return 0;
}
@@ -968,7 +963,7 @@ sw buf_parse_fn_algo (s_buf *buf, s_list **dest)
if (! r)
break;
result += r;
- *tail = list_new(NULL);
+ *tail = list_new(NULL, NULL);
(*tail)->tag = tag;
tail = &(*tail)->next.data.list;
if ((r = buf_ignore_spaces(buf)) < 0)
@@ -1023,7 +1018,7 @@ sw buf_parse_fn_pattern (s_buf *buf, s_list **dest)
if ((r = buf_parse_tag(buf, &tag)) <= 0)
goto restore;
result += r;
- *tail = list_new(NULL);
+ *tail = list_new(NULL, NULL);
(*tail)->tag = tag;
tail = &(*tail)->next.data.list;
if ((r = buf_ignore_spaces(buf)) < 0)
@@ -1363,7 +1358,7 @@ sw buf_parse_list (s_buf *buf, s_list **list)
}
*i = NULL;
while (1) {
- *i = list_new(NULL);
+ *i = list_new(NULL, NULL);
if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
goto restore;
result += r;
@@ -1512,13 +1507,8 @@ sw buf_parse_quote (s_buf *buf, s_quote *dest)
return r;
}
-sw buf_parse_s (s_buf *buf, u8 size, void *dest)
+sw buf_parse_s8 (s_buf *buf, s8 *dest)
{
- const s_str bases_bin[] = {{{NULL}, 2, {"01"}}};
- const s_str bases_oct[] = {{{NULL}, 8, {"01234567"}}};
- const s_str bases_dec[] = {{{NULL}, 10, {"0123456789"}}};
- const s_str bases_hex[] = {{{NULL}, 16, {"01234567890abcdef"}},
- {{NULL}, 16, {"01234567890ABCDEF"}}};
e_bool negative = false;
sw r;
sw result = 0;
@@ -1533,7 +1523,7 @@ sw buf_parse_s (s_buf *buf, u8 size, void *dest)
goto restore;
result += r;
if (r > 0) {
- if ((r = buf_parse_s_bases(buf, bases_bin, 1, negative, size,
+ if ((r = buf_parse_s8_base(buf, &g_c3_base_bin, negative,
dest)) <= 0)
goto restore;
result += r;
@@ -1543,7 +1533,7 @@ sw buf_parse_s (s_buf *buf, u8 size, void *dest)
goto restore;
result += r;
if (r > 0) {
- if ((r = buf_parse_s_bases(buf, bases_oct, 1, negative, size,
+ if ((r = buf_parse_s8_base(buf, &g_c3_base_oct, negative,
dest)) <= 0)
goto restore;
result += r;
@@ -1553,13 +1543,16 @@ sw buf_parse_s (s_buf *buf, u8 size, void *dest)
goto restore;
result += r;
if (r > 0) {
- if ((r = buf_parse_s_bases(buf, bases_hex, 2, negative, size,
- dest)) <= 0)
+ if ((r = buf_parse_s8_base(buf, g_c3_bases_hex, negative,
+ dest)) < 0)
+ goto restore;
+ if (! r && (r = buf_parse_s8_base(buf, g_c3_bases_hex + 1, negative,
+ dest)) <= 0)
goto restore;
result += r;
goto ok;
}
- if ((r = buf_parse_s_bases(buf, bases_dec, 1, negative, size,
+ if ((r = buf_parse_s8_base(buf, &g_c3_base_dec, negative,
dest)) <= 0)
goto restore;
result += r;
@@ -1573,56 +1566,46 @@ sw buf_parse_s (s_buf *buf, u8 size, void *dest)
return r;
}
-sw buf_parse_s_bases (s_buf *buf, const s_str *bases, uw bases_count,
- bool negative, u8 size, void *dest)
+sw buf_parse_s8_base (s_buf *buf, const s_str *base, bool negative,
+ s8 *dest)
{
u8 digit;
sw r;
sw radix;
sw result = 0;
s_buf_save save;
- s64 tmp = 0;
+ s8 tmp = 0;
assert(buf);
- assert(bases);
- assert(bases_count);
- assert(size);
- assert(size <= 8);
+ assert(base);
assert(dest);
- if (size > 8) {
- assert(! "buf_parse_s_bases: unsupported integer size");
- errx(1, "buf_parse_s_bases: unsupported integer size: %u", size);
- return -1;
- }
buf_save_init(buf, &save);
- if ((radix = str_length_utf8(bases)) < 2) {
- assert(! "buf_parse_s_bases: invalid radix");
- errx(1, "buf_parse_s_bases: invalid radix: %ld", radix);
+ radix = str_length_utf8(base);
+ if (radix < 2 || radix > S8_MAX) {
+ assert(! "buf_parse_s8_base: invalid radix");
+ errx(1, "buf_parse_s8_base: invalid radix: %ld", radix);
return -1;
}
- while ((r = buf_parse_digit(buf, bases, bases_count, &digit)) > 0) {
+ while ((r = buf_parse_digit(buf, base, &digit)) > 0) {
result += r;
if (digit >= radix) {
- assert(! "buf_parse_s_bases: digit not in radix");
- errx(1, "buf_parse_s_bases: digit not in radix: %u", digit);
+ assert(! "buf_parse_s8_base: digit not in radix");
+ errx(1, "buf_parse_s8_base: digit not in radix: %u", digit);
return -1;
}
- if (tmp > ((((s64) 1 << (size * 8 - 1)) - 1) +
- (s64) radix - 1) / (s64) radix) {
- warnx("buf_parse_s_bases: integer overflow");
+ if (tmp > ceiling_s8(S8_MAX, radix)) {
+ warnx("buf_parse_s8_base: integer overflow");
goto restore;
}
tmp *= radix;
- if (tmp > (s64) (1 << (size * 8 - 1)) - 1 - digit) {
- warnx("buf_parse_s_bases: integer overflow");
+ if (tmp > (s8) (S8_MAX - digit)) {
+ warnx("buf_parse_s8_base: integer overflow");
goto restore;
}
tmp += digit;
}
- if (negative && tmp)
- tmp = ! tmp - 1;
- /* XXX: lsb/msb */
- /* XXX: byte order */
- xxx;
+ if (negative)
+ tmp = -tmp;
+ *dest = tmp;
r = result;
goto clean;
restore:
@@ -1632,26 +1615,6 @@ sw buf_parse_s_bases (s_buf *buf, const s_str *bases, uw bases_count,
return r;
}
-sw buf_parse_s8 (s_buf *buf, s8 *dest)
-{
- return buf_parse_s(buf, 1, dest);
-}
-
-sw buf_parse_s16 (s_buf *buf, s16 *dest)
-{
- return buf_parse_s(buf, 2, dest);
-}
-
-sw buf_parse_s32 (s_buf *buf, s32 *dest)
-{
- return buf_parse_s(buf, 4, dest);
-}
-
-sw buf_parse_s64 (s_buf *buf, s64 *dest)
-{
- return buf_parse_s(buf, 8, dest);
-}
-
sw buf_parse_str (s_buf *buf, s_str *dest)
{
u8 b;
@@ -2167,7 +2130,7 @@ sw buf_parse_tuple (s_buf *buf, s_tuple *tuple)
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
result += r;
- *i = list_new(NULL);
+ *i = list_new(NULL, NULL);
if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
goto restore;
result += r;
@@ -2221,26 +2184,17 @@ sw buf_parse_tuple (s_buf *buf, s_tuple *tuple)
return r;
}
-sw buf_parse_u (s_buf *buf, u8 size, void *dest)
+sw buf_parse_u8 (s_buf *buf, u8 *dest)
{
- const s_str bases_bin[] = {{{NULL}, 2, {"01"}}};
- const s_str bases_oct[] = {{{NULL}, 8, {"01234567"}}};
- const s_str bases_dec[] = {{{NULL}, 10, {"0123456789"}}};
- const s_str bases_hex[] = {{{NULL}, 16, {"01234567890abcdef"}},
- {{NULL}, 16, {"01234567890ABCDEF"}}};
sw r;
sw result = 0;
s_buf_save save;
- assert(buf);
- assert(dest);
- assert(size);
buf_save_init(buf, &save);
if ((r = buf_read_1(buf, "0b")) < 0)
goto restore;
+ result += r;
if (r > 0) {
- result += r;
- if ((r = buf_parse_u_bases(buf, bases_bin, 1, size,
- dest)) <= 0)
+ if ((r = buf_parse_u8_base(buf, &g_c3_base_bin, dest)) <= 0)
goto restore;
result += r;
goto ok;
@@ -2249,8 +2203,7 @@ sw buf_parse_u (s_buf *buf, u8 size, void *dest)
goto restore;
result += r;
if (r > 0) {
- if ((r = buf_parse_u_bases(buf, bases_oct, 1, size,
- dest)) <= 0)
+ if ((r = buf_parse_u8_base(buf, &g_c3_base_oct, dest)) <= 0)
goto restore;
result += r;
goto ok;
@@ -2259,14 +2212,15 @@ sw buf_parse_u (s_buf *buf, u8 size, void *dest)
goto restore;
result += r;
if (r > 0) {
- if ((r = buf_parse_u_bases(buf, bases_hex, 2, size,
- dest)) <= 0)
+ if ((r = buf_parse_u8_base(buf, g_c3_bases_hex, dest)) < 0)
+ goto restore;
+ if (! r && (r = buf_parse_u8_base(buf, g_c3_bases_hex + 1,
+ dest)) <= 0)
goto restore;
result += r;
goto ok;
}
- if ((r = buf_parse_u_bases(buf, bases_dec, 1, size,
- dest)) <= 0)
+ if ((r = buf_parse_u8_base(buf, &g_c3_base_dec, dest)) <= 0)
goto restore;
result += r;
ok:
@@ -2279,54 +2233,43 @@ sw buf_parse_u (s_buf *buf, u8 size, void *dest)
return r;
}
-sw buf_parse_u_bases (s_buf *buf, const s_str *bases, uw bases_count,
- u8 size, void *dest)
+sw buf_parse_u8_base (s_buf *buf, const s_str *base, u8 *dest)
{
u8 digit;
sw r;
sw radix;
sw result = 0;
s_buf_save save;
- u64 tmp = 0;
+ u8 tmp = 0;
assert(buf);
- assert(bases);
- assert(bases_count);
- assert(size);
- assert(size <= 8);
+ assert(base);
assert(dest);
- if (size > 8) {
- assert(! "buf_parse_u_bases: unsupported integer size");
- errx(1, "buf_parse_u_bases: unsupported integer size: %u", size);
- return -1;
- }
buf_save_init(buf, &save);
- if ((radix = str_length_utf8(bases)) < 2) {
- assert(! "buf_parse_u_bases: invalid radix");
- errx(1, "buf_parse_u_bases: invalid radix: %ld", radix);
+ radix = str_length_utf8(base);
+ if (radix < 2 || radix > U8_MAX) {
+ assert(! "buf_parse_u8_base: invalid radix");
+ errx(1, "buf_parse_u8_base: invalid radix: %ld", radix);
return -1;
}
- while ((r = buf_parse_digit(buf, bases, bases_count, &digit)) > 0) {
+ while ((r = buf_parse_digit(buf, base, &digit)) > 0) {
result += r;
if (digit >= radix) {
- assert(! "buf_parse_u_bases: digit not in radix");
- errx(1, "buf_parse_u_bases: digit not in radix: %u", digit);
+ assert(! "buf_parse_u8_base: digit not in radix");
+ errx(1, "buf_parse_u8_base: digit not in radix: %u", digit);
return -1;
}
- if (tmp > ((((u64) 1 << (size * 8)) - 1) +
- (u64) radix - 1) / (u64) radix) {
- warnx("buf_parse_u_bases: integer overflow");
+ if (tmp > ceiling_u8(U8_MAX, radix)) {
+ warnx("buf_parse_u8_base: integer overflow");
goto restore;
}
tmp *= radix;
- if (tmp > (u64) (1 << (size * 8)) - 1 - digit) {
- warnx("buf_parse_u_bases: integer overflow");
+ if (tmp > (u8) (U8_MAX - digit)) {
+ warnx("buf_parse_u8_base: integer overflow");
goto restore;
}
tmp += digit;
}
- /* XXX: lsb/msb */
- /* XXX: byte order */
- xxx;
+ *dest = tmp;
r = result;
goto clean;
restore:
@@ -2336,26 +2279,6 @@ sw buf_parse_u_bases (s_buf *buf, const s_str *bases, uw bases_count,
return r;
}
-sw buf_parse_u8 (s_buf *buf, u8 *dest)
-{
- return buf_parse_u(buf, 1, dest);
-}
-
-sw buf_parse_u16 (s_buf *buf, u16 *dest)
-{
- return buf_parse_u(buf, 2, dest);
-}
-
-sw buf_parse_u32 (s_buf *buf, u32 *dest)
-{
- return buf_parse_u(buf, 4, dest);
-}
-
-sw buf_parse_u64 (s_buf *buf, u64 *dest)
-{
- return buf_parse_u(buf, 8, dest);
-}
-
sw buf_parse_u64_dec (s_buf *buf, u64 *dest)
{
sw r;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index e988173..6e677ba 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -39,8 +39,7 @@ sw buf_parse_call_op_rec (s_buf *buf, s_call *dest, u8 min_precedence);
sw buf_parse_cfn (s_buf *buf, s_cfn *dest);
sw buf_parse_character (s_buf *buf, character *dest);
sw buf_parse_comments (s_buf *buf);
-sw buf_parse_digit (s_buf *buf, const s_str *bases, uw bases_count,
- u8 *dest);
+sw buf_parse_digit (s_buf *buf, const s_str *base, u8 *dest);
sw buf_parse_digit_bin (s_buf *buf, u8 *dest);
sw buf_parse_digit_hex (s_buf *buf, u8 *dest);
sw buf_parse_digit_oct (s_buf *buf, u8 *dest);
@@ -65,13 +64,18 @@ sw buf_parse_module_name (s_buf *buf, const s_sym **dest);
sw buf_parse_new_tag (s_buf *buf, s_tag **dest);
sw buf_parse_ptag (s_buf *buf, p_tag *dest);
sw buf_parse_quote (s_buf *buf, s_quote *dest);
-sw buf_parse_s (s_buf *buf, u8 size, void *dest);
-sw buf_parse_s_bases (s_buf *buf, const s_str *bases, uw bases_count,
- bool negative, u8 size, void *dest);
sw buf_parse_s8 (s_buf *buf, s8 *dest);
+sw buf_parse_s8_base (s_buf *buf, const s_str *base, bool negative,
+ s8 *dest);
sw buf_parse_s16 (s_buf *buf, s16 *dest);
+sw buf_parse_s16_base (s_buf *buf, const s_str *base, bool negative,
+ s16 *dest);
sw buf_parse_s32 (s_buf *buf, s32 *dest);
+sw buf_parse_s32_base (s_buf *buf, const s_str *base, bool negative,
+ s32 *dest);
sw buf_parse_s64 (s_buf *buf, s64 *dest);
+sw buf_parse_s64_base (s_buf *buf, const s_str *base, bool negative,
+ s64 *dest);
sw buf_parse_str (s_buf *buf, s_str *dest);
sw buf_parse_str_character (s_buf *buf, character *dest);
sw buf_parse_str_character_unicode (s_buf *buf, character *dest);
@@ -96,14 +100,17 @@ sw buf_parse_tag_str_u8 (s_buf *buf, s_tag *dest);
sw buf_parse_tag_sym (s_buf *buf, s_tag *dest);
sw buf_parse_tag_tuple (s_buf *buf, s_tag *dest);
sw buf_parse_tuple (s_buf *buf, s_tuple *dest);
-sw buf_parse_u (s_buf *buf, u8 size, void *dest);
-sw buf_parse_u_bases (s_buf *buf, const s_str *bases, uw bases_count,
- u8 size, void *dest);
sw buf_parse_u8 (s_buf *buf, u8 *dest);
+sw buf_parse_u8_base (s_buf *buf, const s_str *base, u8 *dest);
sw buf_parse_u16 (s_buf *buf, u16 *dest);
+sw buf_parse_u16_base (s_buf *buf, const s_str *base, u16 *dest);
sw buf_parse_u32 (s_buf *buf, u32 *dest);
+sw buf_parse_u32_base (s_buf *buf, const s_str *base, u32 *dest);
sw buf_parse_u64 (s_buf *buf, u64 *dest);
+sw buf_parse_u64_base (s_buf *buf, const s_str *base, u64 *dest);
sw buf_parse_u64_hex (s_buf *buf, u64 *dest);
+sw buf_parse_uw (s_buf *buf, uw *dest);
+sw buf_parse_uw_base (s_buf *buf, const s_str *base, uw *dest);
sw buf_parse_var (s_buf *buf, void *dest);
sw buf_parse_void (s_buf *buf, void *dest);
diff --git a/libc3/c3.c b/libc3/c3.c
index a6e7df1..61fa657 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -16,6 +16,12 @@
#include <stdlib.h>
#include "c3.h"
+const s_str g_c3_base_bin = {{NULL}, 2, {"01"}};
+const s_str g_c3_base_oct = {{NULL}, 8, {"01234567"}};
+const s_str g_c3_base_dec = {{NULL}, 10, {"0123456789"}};
+const s_str g_c3_bases_hex[2] = {{{NULL}, 16, {"01234567890abcdef"}},
+ {{NULL}, 16, {"01234567890ABCDEF"}}};
+
void c3_break ()
{
assert(! "break");
diff --git a/libc3/c3.h b/libc3/c3.h
index bf186f4..5f3a97f 100644
--- a/libc3/c3.h
+++ b/libc3/c3.h
@@ -22,6 +22,7 @@
#include "buf_parse.h"
#include "buf_save.h"
#include "call.h"
+#include "ceiling.h"
#include "cfn.h"
#include "character.h"
#include "compare.h"
@@ -49,6 +50,11 @@
#define C3_EXT ".c3"
+extern const s_str g_c3_base_bin;
+extern const s_str g_c3_base_oct;
+extern const s_str g_c3_base_dec;
+extern const s_str g_c3_bases_hex[2];
+
/* stack-allocation compatible functions */
void c3_init (s_env *env);
void c3_clean (s_env *env);
diff --git a/libc3/call.c b/libc3/call.c
index 34ed58b..6dc03ec 100644
--- a/libc3/call.c
+++ b/libc3/call.c
@@ -57,7 +57,7 @@ s_call * call_init_op (s_call *call)
{
assert(call);
bzero(call, sizeof(s_call));
- call->arguments = list_new(list_new(NULL));
+ call->arguments = list_new(NULL, list_new(NULL, NULL));
return call;
}
diff --git a/libc3/ceiling.c b/libc3/ceiling.c
new file mode 100644
index 0000000..8b232d8
--- /dev/null
+++ b/libc3/ceiling.c
@@ -0,0 +1,30 @@
+/* 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 "ceiling.h"
+
+#define DEF_CEILING(type) \
+ type ceiling_ ## type (type a, type b) \
+ { \
+ return (a + (b - 1)) / b; \
+ } \
+
+DEF_CEILING(s8)
+DEF_CEILING(s16)
+DEF_CEILING(s32)
+DEF_CEILING(s64)
+DEF_CEILING(sw)
+DEF_CEILING(u8)
+DEF_CEILING(u16)
+DEF_CEILING(u32)
+DEF_CEILING(u64)
+DEF_CEILING(uw)
diff --git a/libc3/ceiling.h b/libc3/ceiling.h
new file mode 100644
index 0000000..2dbe3d5
--- /dev/null
+++ b/libc3/ceiling.h
@@ -0,0 +1,39 @@
+/* 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 ceiling.h
+ * @brief Mathematical ceiling
+ *
+ * Functions that return the ceiling of a number divided by another
+ * number.
+ */
+#ifndef CEILING_H
+#define CEILING_H
+
+#include "types.h"
+
+#define DEF_CEILING_PROTOTYPE(type) \
+ type ceiling_ ## type (type a, type b)
+
+DEF_CEILING_PROTOTYPE(s8);
+DEF_CEILING_PROTOTYPE(s16);
+DEF_CEILING_PROTOTYPE(s32);
+DEF_CEILING_PROTOTYPE(s64);
+DEF_CEILING_PROTOTYPE(sw);
+DEF_CEILING_PROTOTYPE(u8);
+DEF_CEILING_PROTOTYPE(u16);
+DEF_CEILING_PROTOTYPE(u32);
+DEF_CEILING_PROTOTYPE(u64);
+DEF_CEILING_PROTOTYPE(uw);
+
+#endif /* CEILING_H */
diff --git a/libc3/env.c b/libc3/env.c
index 07cde98..d88e352 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -150,7 +150,7 @@ bool env_eval_call_arguments (s_env *env, s_list *args, s_list **dest)
s_list *tmp;
tail = &tmp;
while (args) {
- *tail = list_new(NULL);
+ *tail = list_new(NULL, NULL);
if (! env_eval_tag(env, &args->tag, &(*tail)->tag)) {
list_delete_all(tmp);
err_puts("env_eval_call_arguments: invalid argument: ");
@@ -264,7 +264,7 @@ bool env_eval_equal_list (s_env *env, const s_list *a, const s_list *b,
goto ko;
if (! b)
goto ko;
- *t = list_new(NULL);
+ *t = list_new(NULL, NULL);
if (! env_eval_equal_tag(env, &a->tag, &b->tag, &(*t)->tag))
goto ko;
a_next = list_next(a);
diff --git a/libc3/list.c b/libc3/list.c
index c60a3f1..7cd6129 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -49,10 +49,10 @@ s_list * list_copy (const s_list *src, s_list **dest)
s_list *result = NULL;
*dest = NULL;
while (src) {
- *dest = list_new(NULL);
+ *dest = list_new(NULL, NULL);
+ tag_copy(&src->tag, &(*dest)->tag);
if (! result)
result = *dest;
- tag_copy(&src->tag, &(*dest)->tag);
if ((next = list_next(src))) {
src = next;
dest = &(*dest)->next.data.list;
@@ -82,10 +82,13 @@ void list_delete_all (s_list *list)
list = list_delete(list);
}
-s_list * list_init (s_list *list, s_list *next)
+s_list * list_init (s_list *list, const s_tag *tag, s_list *next)
{
assert(list);
- tag_init_void(&list->tag);
+ if (tag)
+ tag_copy(tag, &list->tag);
+ else
+ tag_init_void(&list->tag);
tag_init_list(&list->next, next);
return list;
}
@@ -127,11 +130,11 @@ s_list * list_next (const s_list *list)
}
}
-s_list * list_new (s_list *next)
+s_list * list_new (const s_tag *tag, s_list *next)
{
s_list *list;
list = calloc(1, sizeof(s_list));
if (! list)
errx(1, "list_new: out of memory");
- return list_init(list, next);
+ return list_init(list, tag, next);
}
diff --git a/libc3/list.h b/libc3/list.h
index 43be207..145f40d 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -25,12 +25,12 @@
#include "types.h"
/* Stack allocation compatible functions, do not use */
-s_list * list_init (s_list *list, s_list *next);
+s_list * list_init (s_list *list, const s_tag *tag, s_list *next);
void list_clean (s_list *list);
/* Constructors, call list_delete after use */
s_list * list_1 (const s8 *p);
-s_list * list_new (s_list *next);
+s_list * list_new (const s_tag *tag, s_list *next);
/* Destructor */
s_list * list_delete (s_list *list);
diff --git a/libc3/sources.mk b/libc3/sources.mk
index d92a8e0..dd5e7bf 100644
--- a/libc3/sources.mk
+++ b/libc3/sources.mk
@@ -13,6 +13,7 @@ HEADERS = \
c3.h \
c_types.h \
call.h \
+ ceiling.h \
cfn.h \
character.h \
compare.h \
@@ -68,6 +69,7 @@ SOURCES = \
buf_save.c \
c3.c \
call.c \
+ ceiling.c \
cfn.c \
character.c \
compare.c \
@@ -120,6 +122,7 @@ LO_SOURCES = \
buf_save.c \
c3.c \
call.c \
+ ceiling.c \
cfn.c \
character.c \
compare.c \
diff --git a/libc3/sources.sh b/libc3/sources.sh
index 2267d96..90c99b7 100644
--- a/libc3/sources.sh
+++ b/libc3/sources.sh
@@ -1,4 +1,4 @@
# sources.sh generated by update_sources
-HEADERS='arg.h array.h binding.h bool.h buf.h buf_file.h buf_inspect.h buf_parse.h buf_parse_c.h buf_save.h c3.h c_types.h call.h cfn.h character.h compare.h config.h env.h error.h error_handler.h eval.h fact.h facts.h facts_cursor.h facts_spec.h facts_spec_cursor.h facts_with.h facts_with_cursor.h fn.h frame.h hash.h ident.h integer.h io.h list.h log.h module.h operator.h quote.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 skiplist__fact.h skiplist_node__fact.h str.h sym.h tag.h tuple.h types.h ucd.h '
-SOURCES='arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_parse.c buf_parse_c.c buf_save.c c3.c call.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c fn.c frame.c hash.c ident.c integer.c io.c list.c log.c module.c operator.c quote.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c skiplist__fact.c skiplist_node__fact.c str.c sym.c tag.c tuple.c ucd.c '
-LO_SOURCES='arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_parse.c buf_parse_c.c buf_save.c c3.c call.c cfn.c character.c compare.c env.c error.c error_handler.c eval.c fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c fn.c frame.c hash.c ident.c integer.c io.c list.c log.c module.c operator.c quote.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c skiplist__fact.c skiplist_node__fact.c str.c sym.c tag.c tuple.c ucd.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_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_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='arg.h array.h binding.h bool.h buf.h buf_file.h buf_inspect.h buf_parse.h buf_parse_c.h buf_save.h c3.h c_types.h call.h ceiling.h cfn.h character.h compare.h config.h env.h error.h error_handler.h eval.h fact.h facts.h facts_cursor.h facts_spec.h facts_spec_cursor.h facts_with.h facts_with_cursor.h fn.h frame.h hash.h ident.h integer.h io.h list.h log.h module.h operator.h quote.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 skiplist__fact.h skiplist_node__fact.h str.h sym.h tag.h tuple.h types.h ucd.h '
+SOURCES='arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_parse.c buf_parse_c.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 fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c fn.c frame.c hash.c ident.c integer.c io.c list.c log.c module.c operator.c quote.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c skiplist__fact.c skiplist_node__fact.c str.c sym.c tag.c tuple.c ucd.c '
+LO_SOURCES='arg.c array.c binding.c bool.c buf.c buf_file.c buf_inspect.c buf_parse.c buf_parse_c.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 fact.c facts.c facts_cursor.c facts_spec.c facts_spec_cursor.c facts_with.c facts_with_cursor.c fn.c frame.c hash.c ident.c integer.c io.c list.c log.c module.c operator.c quote.c set__fact.c set__tag.c set_cursor__fact.c set_cursor__tag.c set_item__fact.c set_item__tag.c skiplist__fact.c skiplist_node__fact.c str.c sym.c tag.c tuple.c ucd.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_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_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/types.h b/libc3/types.h
index f7cb963..055b6a3 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -35,11 +35,23 @@ typedef uint32_t u32;
typedef unsigned long uw;
typedef uint64_t u64;
-#define S32_MAX LONG_MAX
-#define S64_MAX LLONG_MAX
-#define SW_MAX LONG_MAX
-#define U64_MAX ULLONG_MAX
-#define UW_MAX ULONG_MAX
+#define S8_MAX ((s8) ((1 << (8 * sizeof(s8) - 1)) - 1))
+#define S16_MAX ((s16) ((1 << (8 * sizeof(s16) - 1)) - 1))
+#define S32_MAX ((s32) ((1 << (8 * sizeof(s32) - 1)) - 1))
+#define S64_MAX ((s64) ((1 << (8 * sizeof(s64) - 1)) - 1))
+#define SW_MAX ((sw) ((1 << (8 * sizeof(sw) - 1)) - 1))
+
+#define S8_MIN ((s8) (1 << (8 * sizeof(s8))))
+#define S16_MIN ((s16) (1 << (8 * sizeof(s16))))
+#define S32_MIN ((s32) (1 << (8 * sizeof(s32))))
+#define S64_MIN ((s64) (1 << (8 * sizeof(s64))))
+#define SW_MIN ((sw) (1 << (8 * sizeof(sw))))
+
+#define U8_MAX ((u8) ((1 << 8 * sizeof(u8)) - 1))
+#define U16_MAX ((u16) ((1 << 8 * sizeof(u16)) - 1))
+#define U32_MAX ((u32) ((1 << 8 * sizeof(u32)) - 1))
+#define U64_MAX ((u64) ((1 << 8 * sizeof(u64)) - 1))
+#define UW_MAX ((uw) -1)
/* IEEE 754 floating point numbers. */
typedef float f32;
diff --git a/sources.mk b/sources.mk
index d1ad426..3d69859 100644
--- a/sources.mk
+++ b/sources.mk
@@ -49,8 +49,6 @@ C3_C_SOURCES = \
libc3/buf.h \
libc3/buf_file.c \
libc3/buf_file.h \
- libc3/buf_inspect.c \
- libc3/buf_inspect.h \
libc3/buf_parse_c.c \
libc3/buf_parse_c.h \
libc3/buf_save.c \
@@ -63,7 +61,6 @@ C3_C_SOURCES = \
libc3/set__fact.h \
libc3/set__fact.c \
libc3/set_cursor__fact.h \
- libc3/compare.c \
libc3/compare.h \
libc3/buf_save.h \
libc3/env.c \
@@ -113,7 +110,6 @@ C3_C_SOURCES = \
libc3/quote.h \
libc3/types.h \
libc3/eval.h \
- libc3/buf_parse.h \
libc3/cfn.c \
libc3/set.c.in \
libc3/set.h.in \
@@ -121,12 +117,16 @@ C3_C_SOURCES = \
libc3/set_cursor.h.in \
libc3/str.c \
libc3/eval.c \
+ libc3/buf_inspect.h \
+ libc3/ceiling.h \
+ libc3/ceiling.c \
libc3/set_item.c.in \
libc3/set_item.h.in \
libc3/fact.c \
libc3/skiplist.c.in \
libc3/operator.c \
libc3/operator.h \
+ libc3/buf_parse.c \
libc3/skiplist.h.in \
libc3/skiplist_node.c.in \
libc3/skiplist_node.h.in \
@@ -136,13 +136,15 @@ C3_C_SOURCES = \
libc3/tag.c \
libc3/c3.h \
libc3/facts.c \
+ libc3/buf_inspect.c \
+ libc3/buf_parse.h \
libc3/tuple.c \
libc3/tuple.h \
libc3/ucd.c \
libc3/ucd.h \
libc3/tag.h \
libc3/module.c \
- libc3/buf_parse.c \
+ libc3/compare.c \
libc3/cfn.h \
libc3/sha1.h \
test/bool_test.c \
@@ -175,6 +177,7 @@ C3_C_SOURCES = \
test/tag_test.h \
test/types_test.c \
test/compare_test.c \
+ test/cfn_test.c \
ucd2c/ucd.h \
ucd2c/ucd2c.c \
diff --git a/sources.sh b/sources.sh
index 11a11c7..f0c3b15 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 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 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.c ic3/buf_linenoise.h ic3/ic3.c ic3/linenoise.c libc3/arg.c libc3/arg.h libc3/binding.c libc3/binding.h libc3/bool.c libc3/bool.h libc3/set_item__tag.c libc3/skiplist_node__fact.c libc3/set__tag.c libc3/set_item__tag.h libc3/set__tag.h libc3/set_cursor__tag.h libc3/set_cursor__tag.c libc3/buf.c libc3/buf.h libc3/buf_file.c libc3/buf_file.h libc3/buf_inspect.c libc3/buf_inspect.h libc3/buf_parse_c.c libc3/buf_parse_c.h libc3/buf_save.c libc3/log.h libc3/skiplist_node__fact.h libc3/skiplist__fact.c libc3/skiplist__fact.h libc3/set_item__fact.h libc3/set_item__fact.c libc3/set__fact.h libc3/set__fact.c libc3/set_cursor__fact.h libc3/compare.c libc3/compare.h libc3/buf_save.h libc3/env.c libc3/env.h libc3/c_types.h libc3/call.c libc3/call.h libc3/log.c libc3/array.h libc3/error.c libc3/error.h libc3/error_handler.c libc3/error_handler.h libc3/io.c libc3/io.h libc3/fact.h libc3/character.c libc3/array.c libc3/facts.h libc3/facts_cursor.c libc3/facts_cursor.h libc3/facts_spec.c libc3/facts_spec.h libc3/facts_spec_cursor.c libc3/facts_spec_cursor.h libc3/character.h libc3/set_cursor__fact.c libc3/c3.c libc3/facts_with.c libc3/facts_with.h libc3/facts_with_cursor.c libc3/facts_with_cursor.h libc3/fn.c libc3/fn.h libc3/frame.c libc3/frame.h libc3/hash.c libc3/hash.h libc3/ident.c libc3/ident.h libc3/integer.c libc3/integer.h libc3/list.c libc3/list.h libc3/module.h libc3/quote.c libc3/quote.h libc3/types.h libc3/eval.h libc3/buf_parse.h libc3/cfn.c libc3/set.c.in libc3/set.h.in libc3/set_cursor.c.in libc3/set_cursor.h.in libc3/str.c libc3/eval.c libc3/set_item.c.in libc3/set_item.h.in libc3/fact.c libc3/skiplist.c.in libc3/operator.c libc3/operator.h libc3/skiplist.h.in libc3/skiplist_node.c.in libc3/skiplist_node.h.in libc3/str.h libc3/sym.c libc3/sym.h libc3/tag.c libc3/c3.h libc3/facts.c libc3/tuple.c libc3/tuple.h libc3/ucd.c libc3/ucd.h libc3/tag.h libc3/module.c libc3/buf_parse.c libc3/cfn.h libc3/sha1.h test/bool_test.c test/buf_file_test.c test/buf_inspect_test.c test/buf_parse_test.c test/buf_test.c test/call_test.c test/character_test.c test/hash_test.c test/fact_test.c test/fact_test.h test/facts_cursor_test.c test/facts_test.c test/facts_with_test.c test/ident_test.c test/env_test.c test/libc3_test.c test/tuple_test.c test/list_test.c test/set__fact_test.c test/set__tag_test.c test/compare_test.h test/skiplist__fact_test.c test/str_test.c test/test.c test/test.h test/sym_test.c test/tag_test.c test/tag_test.h test/types_test.c test/compare_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.c ic3/buf_linenoise.h ic3/ic3.c ic3/linenoise.c libc3/arg.c libc3/arg.h libc3/binding.c libc3/binding.h libc3/bool.c libc3/bool.h libc3/set_item__tag.c libc3/skiplist_node__fact.c libc3/set__tag.c libc3/set_item__tag.h libc3/set__tag.h libc3/set_cursor__tag.h libc3/set_cursor__tag.c libc3/buf.c libc3/buf.h libc3/buf_file.c libc3/buf_file.h libc3/buf_parse_c.c libc3/buf_parse_c.h libc3/buf_save.c libc3/log.h libc3/skiplist_node__fact.h libc3/skiplist__fact.c libc3/skiplist__fact.h libc3/set_item__fact.h libc3/set_item__fact.c libc3/set__fact.h libc3/set__fact.c libc3/set_cursor__fact.h libc3/compare.h libc3/buf_save.h libc3/env.c libc3/env.h libc3/c_types.h libc3/call.c libc3/call.h libc3/log.c libc3/array.h libc3/error.c libc3/error.h libc3/error_handler.c libc3/error_handler.h libc3/io.c libc3/io.h libc3/fact.h libc3/character.c libc3/array.c libc3/facts.h libc3/facts_cursor.c libc3/facts_cursor.h libc3/facts_spec.c libc3/facts_spec.h libc3/facts_spec_cursor.c libc3/facts_spec_cursor.h libc3/character.h libc3/set_cursor__fact.c libc3/c3.c libc3/facts_with.c libc3/facts_with.h libc3/facts_with_cursor.c libc3/facts_with_cursor.h libc3/fn.c libc3/fn.h libc3/frame.c libc3/frame.h libc3/hash.c libc3/hash.h libc3/ident.c libc3/ident.h libc3/integer.c libc3/integer.h libc3/list.c libc3/list.h libc3/module.h libc3/quote.c libc3/quote.h libc3/types.h libc3/eval.h libc3/cfn.c libc3/set.c.in libc3/set.h.in libc3/set_cursor.c.in libc3/set_cursor.h.in libc3/str.c libc3/eval.c libc3/buf_inspect.h libc3/ceiling.h libc3/ceiling.c libc3/set_item.c.in libc3/set_item.h.in libc3/fact.c libc3/skiplist.c.in libc3/operator.c libc3/operator.h libc3/buf_parse.c libc3/skiplist.h.in libc3/skiplist_node.c.in libc3/skiplist_node.h.in libc3/str.h libc3/sym.c libc3/sym.h libc3/tag.c libc3/c3.h libc3/facts.c libc3/buf_inspect.c libc3/buf_parse.h libc3/tuple.c libc3/tuple.h libc3/ucd.c libc3/ucd.h libc3/tag.h libc3/module.c libc3/compare.c libc3/cfn.h libc3/sha1.h test/bool_test.c test/buf_file_test.c test/buf_inspect_test.c test/buf_parse_test.c test/buf_test.c test/call_test.c test/character_test.c test/hash_test.c test/fact_test.c test/fact_test.h test/facts_cursor_test.c test/facts_test.c test/facts_with_test.c test/ident_test.c test/env_test.c test/libc3_test.c test/tuple_test.c test/list_test.c test/set__fact_test.c test/set__tag_test.c test/compare_test.h test/skiplist__fact_test.c test/str_test.c test/test.c test/test.h test/sym_test.c test/tag_test.c test/tag_test.h test/types_test.c test/compare_test.c test/cfn_test.c ucd2c/ucd.h ucd2c/ucd2c.c '
diff --git a/test/cfn_test.c b/test/cfn_test.c
index 354e804..863578c 100644
--- a/test/cfn_test.c
+++ b/test/cfn_test.c
@@ -12,13 +12,17 @@
*/
#include <string.h>
#include "../libc3/cfn.h"
+#include "../libc3/list.h"
+#include "../libc3/sym.h"
+#include "../libc3/tag.h"
#include "test.h"
void cfn_test ();
-void cfn_test_init_clean ();
void cfn_test_apply ();
void cfn_test_copy ();
+void cfn_test_init_clean ();
void cfn_test_link ();
+bool cfn_test_not (bool a);
void cfn_test_set_type ();
void cfn_test ()
@@ -30,27 +34,63 @@ void cfn_test ()
cfn_test_set_type();
}
+bool cfn_test_not (bool a)
+{
+ return a ? false : true;
+}
+
void cfn_test_init_clean ()
{
s_cfn tmp;
- TEST_EQ(cfn_init(&tmp), &tmp);
+ TEST_EQ(cfn_init(&tmp, sym_1("cfn_test_not"),
+ list_1("(:bool)"),
+ sym_1("bool")), &tmp);
cfn_clean(&tmp);
test_ok();
}
void cfn_test_apply ()
{
+ s_list *args;
+ s_tag result;
s_cfn tmp;
- cfn_init(&tmp);
-
+ cfn_init(&tmp, sym_1("cfn_test_not"),
+ list_1("(:bool)"),
+ sym_1("bool"));
+ args = list_new(NULL, NULL);
+ tag_init_bool(&args->tag, false);
+ TEST_EQ(cfn_apply(&tmp, args, &result), &result);
+ TEST_EQ(result.data.bool, true);
+ list_delete_all(args);
cfn_clean(&tmp);
}
void cfn_test_copy ()
{
s_cfn a;
+ s_list *a_arg_types;
s_cfn b;
- cfn_init(&a);
+ s_list *b_arg_types;
+ cfn_init(&a, sym_1("cfn_test_not"),
+ list_1("(:bool)"),
+ sym_1("bool"));
+ TEST_EQ(cfn_copy(&a, &b), &b);
+ TEST_EQ(a.name, b.name);
+ TEST_EQ(a.ptr.p, b.ptr.p);
+ TEST_EQ(a.arity, b.arity);
+ TEST_EQ(a.result_type, b.result_type);
+ TEST_EQ(a.arg_result, b.arg_result);
+ a_arg_types = a.arg_types;
+ b_arg_types = b.arg_types;
+ while (a_arg_types && b_arg_types) {
+ TEST_EQ(a_arg_types->tag.type.type, TAG_SYM);
+ TEST_EQ(a_arg_types->tag.type.type, b_arg_types->tag.type.type);
+ TEST_EQ(a_arg_types->tag.data.sym, b_arg_types->tag.data.sym);
+ a_arg_types = list_next(a_arg_types);
+ b_arg_types = list_next(b_arg_types);
+ }
+ TEST_EQ(a.cif, b.cif);
+ cfn_clean(&b);
cfn_clean(&a);
}
diff --git a/test/sources.mk b/test/sources.mk
index b7c4c15..d603cd5 100644
--- a/test/sources.mk
+++ b/test/sources.mk
@@ -6,6 +6,7 @@ SOURCES = \
buf_parse_test.c \
buf_test.c \
call_test.c \
+ cfn_test.c \
character_test.c \
compare_test.c \
env_test.c \
diff --git a/test/sources.sh b/test/sources.sh
index f28d2a6..428a88f 100644
--- a/test/sources.sh
+++ b/test/sources.sh
@@ -1,2 +1,2 @@
# sources.sh generated by update_sources
-SOURCES='bool_test.c buf_file_test.c buf_inspect_test.c buf_parse_test.c buf_test.c call_test.c character_test.c compare_test.c env_test.c fact_test.c facts_cursor_test.c facts_test.c facts_with_test.c hash_test.c ident_test.c libc3_test.c list_test.c set__fact_test.c set__tag_test.c skiplist__fact_test.c str_test.c sym_test.c tag_test.c test.c tuple_test.c types_test.c '
+SOURCES='bool_test.c buf_file_test.c buf_inspect_test.c buf_parse_test.c buf_test.c call_test.c cfn_test.c character_test.c compare_test.c env_test.c fact_test.c facts_cursor_test.c facts_test.c facts_with_test.c hash_test.c ident_test.c libc3_test.c list_test.c set__fact_test.c set__tag_test.c skiplist__fact_test.c str_test.c sym_test.c tag_test.c test.c tuple_test.c types_test.c '
diff --git a/test/test.h b/test/test.h
index cc2c76d..988e650 100644
--- a/test/test.h
+++ b/test/test.h
@@ -32,8 +32,8 @@
#define TEST_EQ(test, expected) \
do { \
- long long signed tmp = (long long signed) (test); \
- if (tmp == (long long signed) (expected)) { \
+ long long signed TEST_EQ_tmp = (long long signed) (test); \
+ if (TEST_EQ_tmp == (long long signed) (expected)) { \
test_ok(); \
} \
else { \
@@ -43,15 +43,15 @@
"Expected %s got %lld.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
- # test, # expected, # expected, tmp, \
+ # test, # expected, # expected, TEST_EQ_tmp, \
TEST_COLOR_RESET); \
} \
} while (0)
#define TEST_FLOAT_EQ(test, expected) \
do { \
- f32 tmp = (f32) (test); \
- if (fabsf(tmp - (f32) (expected)) <= FLT_EPSILON) \
+ float TEST_FLOAT_EQ_tmp = (float) (test); \
+ if (fabsf(TEST_FLOAT_EQ_tmp - (float) (expected)) <= FLT_EPSILON) \
test_ok(); \
else { \
test_ko(); \
@@ -60,16 +60,18 @@
"Expected %s got %.16g.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
- # test, # expected, # expected, tmp, \
+ # test, # expected, # expected, TEST_FLOAT_EQ_tmp, \
TEST_COLOR_RESET); \
} \
} while (0)
#define TEST_FLOAT_EQ2(test, expected1, expected2) \
do { \
- f32 tmp = (f32) (test); \
- if (fabsf(tmp - (f32) (expected1)) <= FLT_EPSILON || \
- fabsf(tmp - (f32) (expected2)) <= FLT_EPSILON) \
+ float TEST_FLOAT_EQ2_tmp = (float) (test); \
+ if (fabsf(TEST_FLOAT_EQ2_tmp - \
+ (float) (expected1)) <= FLT_EPSILON || \
+ fabsf(TEST_FLOAT_EQ2_tmp - \
+ (float) (expected2)) <= FLT_EPSILON) \
test_ok(); \
else { \
test_ko(); \
@@ -78,32 +80,32 @@
"Expected %s got %.16g.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
- # test, # expected1, # expected1, tmp, \
+ # test, # expected1, # expected1, TEST_FLOAT_EQ2_tmp, \
TEST_COLOR_RESET); \
} \
} while (0)
#define TEST_DOUBLE_EQ(test, expected) \
do { \
- f64 tmp = (f64) (test); \
- if (fabs(tmp - (expected)) <= DBL_EPSILON) \
+ f64 TEST_DOUBLE_EQ_tmp = (double) (test); \
+ if (fabs(TEST_DOUBLE_EQ_tmp - (expected)) <= DBL_EPSILON) \
test_ok(); \
else { \
test_ko(); \
printf("\n%sAssertion failed in %s:%d %s\n" \
"%s == %s\n" \
- "Expected %s got %lf.%s\n", \
+ "Expected %s got %lf.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
- # test, # expected, # expected, tmp, \
+ # test, # expected, # expected, TEST_DOUBLE_EQ_tmp, \
TEST_COLOR_RESET); \
} \
} while (0)
-#define TEST_STR_CMP(a, b, expected) \
+#define TEST_STR_COMPARE(a, b, expected) \
do { \
- sw tmp = str_compare(a, b); \
- if (tmp == expected) { \
+ sw TEST_STR_COMPARE_tmp = str_compare(a, b); \
+ if (TEST_STR_COMPARE_tmp == expected) { \
test_ok(); \
} \
else { \
@@ -113,15 +115,15 @@
"Expected %s got %ld.%s\n", \
TEST_COLOR_KO, \
__FILE__, __LINE__, __func__, \
- # a, # b, # expected, # expected, tmp, \
+ # a, # b, # expected, # expected, TEST_STR_COMPARE_tmp, \
TEST_COLOR_RESET); \
} \
} while (0)
#define TEST_STRNCMP(test, result, bytes) \
do { \
- const char *tmp = (test); \
- if (strncmp(tmp, (result), (bytes)) == 0) { \
+ const char *TEST_STRNCMP_tmp = (test); \
+ if (strncmp(TEST_STRNCMP_tmp, (result), (bytes)) == 0) { \
test_ok(); \
} \
else { \
@@ -133,7 +135,7 @@
# test, # result, (long) (bytes)); \
printf("Expected %s got \"", \
# result); \
- fwrite(tmp, (bytes), 1, stdout); \
+ fwrite(TEST_STRNCMP_tmp, (bytes), 1, stdout); \
printf("\".%s\n", TEST_COLOR_RESET); \
} \
} while (0)