diff --git a/Makefile b/Makefile
index eb49fbf..f6eb789 100644
--- a/Makefile
+++ b/Makefile
@@ -140,6 +140,9 @@ test_gcovr:
test_ic3: build
${MAKE} -C test test_ic3
+test_ic3_debug: debug
+ ${MAKE} -C test test_ic3_debug
+
.PHONY: all asan c3s cov clean clean_cov debug gcovr ic3 install libc3 libtommath license test test_asan test_cov test_debug test_gcovr test_ic3
include config.mk
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 1b034c1..835b95f 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -34,24 +34,24 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
s_array tmp;
const s_sym *type;
assert(buf);
- assert(a);
+ assert(dest);
buf_save_init(buf, &save);
- if ((r = buf_read_1(buf, "(")) < 0)
+ if ((r = buf_read_1(buf, "(")) <= 0)
goto clean;
result += r;
if ((r = buf_ignore_spaces(buf)) < 0)
goto clean;
result += r;
- if ((r = buf_parse_sym(buf, &type)) < 0)
+ if ((r = buf_parse_sym(buf, &type)) <= 0)
goto restore;
result += r;
- tmp.type = sym_to_e_tag_type(type);
+ tmp.type = sym_to_tag_type(type);
item_size = tag_type_size(tmp.type);
item = tag_to_pointer(&tag, type);
if ((r = buf_ignore_spaces(buf)) < 0)
goto clean;
result += r;
- if ((r = buf_read_1(buf, ")")) < 0)
+ if ((r = buf_read_1(buf, ")")) <= 0)
goto clean;
result += r;
if ((r = buf_ignore_spaces(buf)) < 0)
@@ -68,7 +68,8 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
}
if (r < 0)
goto restore;
- i = tmp.dimension;
+ if (! (i = tmp.dimension))
+ goto restore;
tmp.dimension++;
if (! (address = calloc(tmp.dimension, sizeof(uw))))
err(1, "buf_parse_array: address");
@@ -1451,6 +1452,15 @@ sw buf_parse_new_tag (s_buf *buf, s_tag **dest)
return r;
}
+sw buf_parse_ptag (s_buf *buf, p_tag *ptag)
+{
+ (void) buf;
+ (void) ptag;
+ assert(! "buf_parse_ptag: not implemented");
+ errx(1, "buf_parse_ptag: not implemented");
+ return -1;
+}
+
sw buf_parse_quote (s_buf *buf, s_quote *dest)
{
s_quote quote;
@@ -1550,18 +1560,23 @@ sw buf_parse_s_bases (s_buf *buf, const s_str *bases, uw bases_count,
assert(bases);
assert(bases_count);
assert(size);
+ assert(size <= 8);
assert(dest);
+ if (size > 8) {
+ errx(1, "buf_parse_s_bases: unsupported integer size: %u", size);
+ return -1;
+ }
buf_save_init(buf, &save);
while ((r = buf_parse_digit(buf, bases, bases_count)) >= 0) {
result += r;
- if (tmp > ((((s64) 1 << (size * 8)) - 1) +
+ if (tmp > ((((s64) 1 << (size * 8 - 1)) - 1) +
(s64) bases[0].size - 1) / (s64) bases[0].size) {
- warnx("buf_parse_s: integer overflow");
+ warnx("buf_parse_s_bases: integer overflow");
goto restore;
}
tmp *= bases[0].size;
- if (tmp > (s64) (1 << (size * 8)) - 1 - r) {
- warnx("buf_parse_s: integer overflow");
+ if (tmp > (s64) (1 << (size * 8 - 1)) - 1 - r) {
+ warnx("buf_parse_s_bases: integer overflow");
goto restore;
}
tmp += r;
@@ -1583,6 +1598,21 @@ 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;
@@ -1884,9 +1914,21 @@ sw buf_parse_tag (s_buf *buf, s_tag *dest)
return r;
}
+sw buf_parse_tag_array (s_buf *buf, s_tag *dest)
+{
+ sw r;
+ assert(buf);
+ assert(dest);
+ if ((r = buf_parse_array(buf, &dest->data.array)) > 0)
+ dest->type.type = TAG_ARRAY;
+ return r;
+}
+
sw buf_parse_tag_bool (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_bool(buf, &dest->data.bool)) > 0)
dest->type.type = TAG_BOOL;
return r;
@@ -1895,6 +1937,8 @@ sw buf_parse_tag_bool (s_buf *buf, s_tag *dest)
sw buf_parse_tag_call (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_call(buf, &dest->data.call)) > 0)
dest->type.type = TAG_CALL;
return r;
@@ -1903,6 +1947,8 @@ sw buf_parse_tag_call (s_buf *buf, s_tag *dest)
sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_call_op(buf, &dest->data.call)) > 0)
dest->type.type = TAG_CALL;
return r;
@@ -1911,6 +1957,8 @@ sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest)
sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_cfn(buf, &dest->data.cfn)) > 0)
dest->type.type = TAG_CFN;
return r;
@@ -1919,6 +1967,8 @@ sw buf_parse_tag_cfn (s_buf *buf, s_tag *dest)
sw buf_parse_tag_character (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_character(buf, &dest->data.character)) > 0)
dest->type.type = TAG_CHARACTER;
return r;
@@ -1927,6 +1977,8 @@ sw buf_parse_tag_character (s_buf *buf, s_tag *dest)
sw buf_parse_tag_fn (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_fn(buf, &dest->data.fn)) > 0)
dest->type.type = TAG_FN;
return r;
@@ -1935,6 +1987,8 @@ sw buf_parse_tag_fn (s_buf *buf, s_tag *dest)
sw buf_parse_tag_ident (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_ident(buf, &dest->data.ident)) > 0)
dest->type.type = TAG_IDENT;
return r;
@@ -1943,6 +1997,8 @@ sw buf_parse_tag_ident (s_buf *buf, s_tag *dest)
sw buf_parse_tag_integer (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_integer(buf, &dest->data.integer)) > 0)
dest->type.type = TAG_INTEGER;
return r;
@@ -1951,6 +2007,8 @@ sw buf_parse_tag_integer (s_buf *buf, s_tag *dest)
sw buf_parse_tag_list (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_list(buf, &dest->data.list)) > 0)
dest->type.type = TAG_LIST;
return r;
@@ -1972,7 +2030,8 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
goto restore;
result += r;
}
- if ((r = buf_parse_tag_bool(buf, dest)) != 0 ||
+ if ((r = buf_parse_tag_array(buf, dest)) != 0 ||
+ (r = buf_parse_tag_bool(buf, dest)) != 0 ||
(r = buf_parse_tag_character(buf, dest)) != 0)
goto end;
if ((r = buf_parse_tag_integer(buf, dest)) != 0) {
@@ -2010,6 +2069,8 @@ sw buf_parse_tag_primary (s_buf *buf, s_tag *dest)
sw buf_parse_tag_quote (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_quote(buf, &dest->data.quote)) > 0)
dest->type.type = TAG_QUOTE;
return r;
@@ -2018,6 +2079,8 @@ sw buf_parse_tag_quote (s_buf *buf, s_tag *dest)
sw buf_parse_tag_str (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_str(buf, &dest->data.str)) > 0)
dest->type.type = TAG_STR;
return r;
@@ -2026,6 +2089,8 @@ sw buf_parse_tag_str (s_buf *buf, s_tag *dest)
sw buf_parse_tag_sym (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_sym(buf, &dest->data.sym)) > 0)
dest->type.type = TAG_SYM;
return r;
@@ -2034,6 +2099,8 @@ sw buf_parse_tag_sym (s_buf *buf, s_tag *dest)
sw buf_parse_tag_tuple (s_buf *buf, s_tag *dest)
{
sw r;
+ assert(buf);
+ assert(dest);
if ((r = buf_parse_tuple(buf, &dest->data.tuple)) > 0)
dest->type.type = TAG_TUPLE;
return r;
@@ -2115,6 +2182,126 @@ sw buf_parse_tuple (s_buf *buf, s_tuple *tuple)
return r;
}
+sw buf_parse_u (s_buf *buf, u8 size, void *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) {
+ if ((r = buf_parse_u_bases(buf, bases_bin, 1, size,
+ dest)) <= 0)
+ goto restore;
+ result += r;
+ goto ok;
+ }
+ if ((r = buf_read_1(buf, "0o")) < 0)
+ goto restore;
+ result += r;
+ if (r > 0) {
+ if ((r = buf_parse_u_bases(buf, bases_oct, 1, size,
+ dest)) <= 0)
+ goto restore;
+ result += r;
+ goto ok;
+ }
+ if ((r = buf_read_1(buf, "0x")) < 0)
+ goto restore;
+ result += r;
+ if (r > 0) {
+ if ((r = buf_parse_u_bases(buf, bases_hex, 2, size,
+ dest)) <= 0)
+ goto restore;
+ result += r;
+ goto ok;
+ }
+ if ((r = buf_parse_u_bases(buf, bases_dec, 1, size,
+ dest)) <= 0)
+ goto restore;
+ result += r;
+ ok:
+ r = result;
+ goto clean;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ return r;
+}
+
+sw buf_parse_u_bases (s_buf *buf, const s_str *bases, uw bases_count,
+ u8 size, void *dest)
+{
+ sw r;
+ sw result = 0;
+ s_buf_save save;
+ u64 tmp = 0;
+ assert(buf);
+ assert(bases);
+ assert(bases_count);
+ assert(size);
+ assert(size <= 8);
+ assert(dest);
+ if (size > 8) {
+ errx(1, "buf_parse_u_bases: unsupported integer size: %u", size);
+ return -1;
+ }
+ buf_save_init(buf, &save);
+ while ((r = buf_parse_digit(buf, bases, bases_count)) >= 0) {
+ result += r;
+ if (tmp > ((((u64) 1 << (size * 8)) - 1) +
+ (u64) bases[0].size - 1) / (u64) bases[0].size) {
+ warnx("buf_parse_u_bases: integer overflow");
+ goto restore;
+ }
+ tmp *= bases[0].size;
+ if (tmp > (u64) (1 << (size * 8)) - 1 - r) {
+ warnx("buf_parse_u_bases: integer overflow");
+ goto restore;
+ }
+ tmp += r;
+ }
+ memcpy(dest, &tmp + 8 - size, size);
+ r = result;
+ goto clean;
+ restore:
+ buf_save_restore_rpos(buf, &save);
+ clean:
+ buf_save_clean(buf, &save);
+ 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;
@@ -2158,47 +2345,45 @@ sw buf_parse_u64_hex (s_buf *buf, u64 *dest)
return r;
}
-sw buf_parse_u32 (s_buf *buf, u32 *dest)
+sw buf_parse_var (s_buf *buf, void *dest)
{
+ character c;
sw r;
- sw result = 0;
- u8 digit;
s_buf_save save;
- u32 tmp = 0;
+ assert(buf);
+ (void) dest;
buf_save_init(buf, &save);
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- tmp = tmp * 10 + digit;
- result += r;
- }
- if (r < 0) {
- buf_save_restore_rpos(buf, &save);
+ if ((r = buf_read_1(buf, "?")) <= 0)
goto clean;
+ if (buf_peek_character_utf8(buf, &c) > 0 &&
+ ! ident_character_is_reserved(c)) {
+ r = 0;
+ goto restore;
}
- *dest = tmp;
- r = result;
+ restore:
+ buf_save_restore_rpos(buf, &save);
clean:
buf_save_clean(buf, &save);
return r;
}
-sw buf_parse_u8 (s_buf *buf, u8 *dest)
+sw buf_parse_void (s_buf *buf, void *dest)
{
+ character c;
sw r;
- sw result = 0;
- u8 digit;
s_buf_save save;
- u8 tmp = 0;
+ assert(buf);
+ (void) dest;
buf_save_init(buf, &save);
- while ((r = buf_parse_digit_dec(buf, &digit)) > 0) {
- tmp = tmp * 10 + digit;
- result += r;
- }
- if (r < 0) {
- buf_save_restore_rpos(buf, &save);
+ if ((r = buf_read_1(buf, "void")) <= 0)
goto clean;
+ if (buf_peek_character_utf8(buf, &c) > 0 &&
+ ! ident_character_is_reserved(c)) {
+ r = 0;
+ goto restore;
}
- *dest = tmp;
- r = result;
+ restore:
+ buf_save_restore_rpos(buf, &save);
clean:
buf_save_clean(buf, &save);
return r;
diff --git a/libc3/buf_parse.h b/libc3/buf_parse.h
index 4206f36..f3aba89 100644
--- a/libc3/buf_parse.h
+++ b/libc3/buf_parse.h
@@ -77,6 +77,7 @@ sw buf_parse_str_character_unicode (s_buf *buf, character *dest);
sw buf_parse_str_u8 (s_buf *buf, u8 *dest);
sw buf_parse_sym (s_buf *buf, const s_sym **dest);
sw buf_parse_tag (s_buf *buf, s_tag *dest);
+sw buf_parse_tag_array (s_buf *buf, s_tag *dest);
sw buf_parse_tag_bool (s_buf *buf, s_tag *dest);
sw buf_parse_tag_call (s_buf *buf, s_tag *dest);
sw buf_parse_tag_call_op (s_buf *buf, s_tag *dest);
@@ -94,9 +95,9 @@ 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, void *dest, u8 size);
-sw buf_parse_u_bases (s_buf *buf, void *dest, u8 size,
- const s_str *bases, uw bases_count);
+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_u16 (s_buf *buf, u16 *dest);
sw buf_parse_u32 (s_buf *buf, u32 *dest);
diff --git a/libc3/cfn.c b/libc3/cfn.c
index 4ab02c5..84354ad 100644
--- a/libc3/cfn.c
+++ b/libc3/cfn.c
@@ -21,10 +21,7 @@
#include "sym.h"
#include "tag.h"
-ffi_type * cfn_sym_to_ffi_type (const s_sym *sym,
- ffi_type *result_type);
s_tag * cfn_tag_init (s_tag *tag, const s_sym *type);
-void * cfn_tag_to_ffi_value (s_tag *tag, const s_sym *type);
s_tag * cfn_apply (s_cfn *cfn, s_list *args, s_tag *dest)
{
@@ -51,7 +48,7 @@ s_tag * cfn_apply (s_cfn *cfn, s_list *args, s_tag *dest)
if (cfn->arg_result)
cfn_tag_init(&tmp2, cfn->result_type);
/* make result point to tmp value */
- result = cfn_tag_to_ffi_value(&tmp, cfn->result_type);
+ result = tag_to_pointer(&tmp, cfn->result_type);
if (cfn->arity) {
if (! (arg_pointers = calloc(sizeof(void *), cfn->arity + 1)))
err(1, "cfn_apply");
@@ -63,20 +60,20 @@ s_tag * cfn_apply (s_cfn *cfn, s_list *args, s_tag *dest)
assert(cfn_arg_type->tag.type.type == TAG_SYM);
if (cfn_arg_type->tag.data.sym == sym_1("&result"))
if (cfn->cif.rtype == &ffi_type_pointer) {
- arg_pointers[i] = cfn_tag_to_ffi_value(&tmp2, cfn->result_type);
+ arg_pointers[i] = tag_to_pointer(&tmp2, cfn->result_type);
arg_values[i] = &arg_pointers[i];
}
else
- arg_values[i] = cfn_tag_to_ffi_value(&tmp2, cfn->result_type);
+ arg_values[i] = tag_to_pointer(&tmp2, cfn->result_type);
else {
if (cfn->cif.arg_types[i] == &ffi_type_pointer) {
- arg_pointers[i] = cfn_tag_to_ffi_value(&a->tag,
- cfn_arg_type->tag.data.sym);
+ arg_pointers[i] = tag_to_pointer(&a->tag,
+ cfn_arg_type->tag.data.sym);
arg_values[i] = &arg_pointers[i];
}
else
- arg_values[i] = cfn_tag_to_ffi_value(&a->tag,
- cfn_arg_type->tag.data.sym);
+ arg_values[i] = tag_to_pointer(&a->tag,
+ cfn_arg_type->tag.data.sym);
a = list_next(a);
}
cfn_arg_type = list_next(cfn_arg_type);
@@ -152,7 +149,7 @@ s_cfn * cfn_set_type (s_cfn *cfn, s_list *arg_type,
ffi_type *result_ffi_type;
ffi_status status;
assert(cfn);
- if (! (result_ffi_type = cfn_sym_to_ffi_type(result_type, NULL)))
+ if (! (result_ffi_type = sym_to_ffi_type(result_type, NULL)))
return NULL;
if ((arity = list_length(arg_type))) {
if (arity > 255) {
@@ -168,7 +165,7 @@ s_cfn * cfn_set_type (s_cfn *cfn, s_list *arg_type,
assert(! "cfn_set_type: invalid type");
errx(1, "cfn_set_type: invalid type");
}
- if (! (arg_ffi_type[i] = cfn_sym_to_ffi_type(a->tag.data.sym, result_ffi_type))) {
+ if (! (arg_ffi_type[i] = sym_to_ffi_type(a->tag.data.sym, result_ffi_type))) {
free(arg_ffi_type);
return NULL;
}
@@ -181,8 +178,8 @@ s_cfn * cfn_set_type (s_cfn *cfn, s_list *arg_type,
cfn->arg_types = arg_type;
cfn->arity = arity;
cfn->result_type = result_type;
- status = ffi_prep_cif(&cfn->cif, FFI_DEFAULT_ABI, cfn->arity, result_ffi_type,
- arg_ffi_type);
+ status = ffi_prep_cif(&cfn->cif, FFI_DEFAULT_ABI, cfn->arity,
+ result_ffi_type, arg_ffi_type);
if (status == FFI_BAD_TYPEDEF) {
warnx("cfn_set_type: ffi_prep_cif: FFI_BAD_TYPEDEF");
return NULL;
@@ -198,105 +195,10 @@ s_cfn * cfn_set_type (s_cfn *cfn, s_list *arg_type,
return cfn;
}
-ffi_type * cfn_sym_to_ffi_type (const s_sym *sym, ffi_type *result_type)
-{
- if (sym == sym_1("tag"))
- return &ffi_type_pointer;
- if (sym == sym_1("&result")) {
- if (! result_type)
- warnx("invalid result type: &result");
- return result_type;
- }
- if (sym == sym_1("s8"))
- return &ffi_type_sint8;
- if (sym == sym_1("s16"))
- return &ffi_type_sint16;
- if (sym == sym_1("s32"))
- return &ffi_type_sint32;
- if (sym == sym_1("s64"))
- return &ffi_type_sint64;
- if (sym == sym_1("sw"))
- return &ffi_type_sint;
- if (sym == sym_1("u8"))
- return &ffi_type_uint8;
- if (sym == sym_1("u16"))
- return &ffi_type_uint16;
- if (sym == sym_1("u32"))
- return &ffi_type_uint32;
- if (sym == sym_1("u64"))
- return &ffi_type_uint64;
- if (sym == sym_1("uw"))
- return &ffi_type_uint;
- assert(! "cfn_sym_to_ffi_type: unknown type");
- errx(1, "cfn_sym_to_ffi_type: unknown type");
- return NULL;
-}
-
-e_tag_type cfn_sym_to_tag_type (const s_sym *sym)
-{
- if (sym == sym_1("void"))
- return TAG_VOID;
- if (sym == sym_1("bool"))
- return TAG_BOOL;
- if (sym == sym_1("call"))
- return TAG_CALL;
- if (sym == sym_1("call_fn"))
- return TAG_CALL_FN;
- if (sym == sym_1("call_macro"))
- return TAG_CALL_MACRO;
- if (sym == sym_1("cfn"))
- return TAG_CFN;
- if (sym == sym_1("character"))
- return TAG_CHARACTER;
- if (sym == sym_1("f32"))
- return TAG_F32;
- if (sym == sym_1("f64"))
- return TAG_F64;
- if (sym == sym_1("fn"))
- return TAG_FN;
- if (sym == sym_1("ident"))
- return TAG_IDENT;
- if (sym == sym_1("integer"))
- return TAG_INTEGER;
- if (sym == sym_1("s64"))
- return TAG_S64;
- if (sym == sym_1("s32"))
- return TAG_S32;
- if (sym == sym_1("s16"))
- return TAG_S16;
- if (sym == sym_1("s8"))
- return TAG_S8;
- if (sym == sym_1("u8"))
- return TAG_U8;
- if (sym == sym_1("u16"))
- return TAG_U16;
- if (sym == sym_1("u32"))
- return TAG_U32;
- if (sym == sym_1("u64"))
- return TAG_U64;
- if (sym == sym_1("list"))
- return TAG_LIST;
- if (sym == sym_1("ptag"))
- return TAG_PTAG;
- if (sym == sym_1("quote"))
- return TAG_QUOTE;
- if (sym == sym_1("str"))
- return TAG_STR;
- if (sym == sym_1("sym"))
- return TAG_SYM;
- if (sym == sym_1("tag"))
- return TAG_VOID;
- if (sym == sym_1("tuple"))
- return TAG_TUPLE;
- assert(! "cfn_sym_to_tag_type: unknown type");
- errx(1, "cfn_sym_to_tag_type: unknown type: %s", sym->str.ptr.ps8);
- return TAG_VOID;
-}
-
s_tag * cfn_tag_init (s_tag *tag, const s_sym *type)
{
assert(tag);
bzero(tag, sizeof(s_tag));
- tag->type.type = cfn_sym_to_tag_type(type);
+ tag->type.type = sym_to_tag_type(type);
return tag;
}
diff --git a/libc3/ident.c b/libc3/ident.c
index 477d664..42f3ce8 100644
--- a/libc3/ident.c
+++ b/libc3/ident.c
@@ -26,8 +26,10 @@ e_bool ident_character_is_reserved (character c)
c == ',' ||
c == '.' ||
c == ';' ||
+ c == '[' ||
c == ']' ||
c == '|' ||
+ c == '{' ||
c == '}');
}
@@ -43,8 +45,14 @@ e_bool ident_first_character_is_reserved (character c)
return (character_is_digit(c) ||
character_is_uppercase(c) ||
character_is_space(c) ||
+ c == '"' ||
+ c == '(' ||
+ c == ')' ||
c == ':' ||
- c == '"');
+ c == '[' ||
+ c == ']' ||
+ c == '{' ||
+ c == '}');
}
e_bool ident_has_reserved_characters (const s_ident *ident)
diff --git a/libc3/sym.c b/libc3/sym.c
index 5f1ecb5..72fcd76 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -142,3 +142,98 @@ const s_sym * sym_new (const s_str *src)
g_sym_list = sym_list_new(sym, g_sym_list);
return sym;
}
+
+ffi_type * sym_to_ffi_type (const s_sym *sym, ffi_type *result_type)
+{
+ if (sym == sym_1("tag"))
+ return &ffi_type_pointer;
+ if (sym == sym_1("&result")) {
+ if (! result_type)
+ warnx("invalid result type: &result");
+ return result_type;
+ }
+ if (sym == sym_1("s8"))
+ return &ffi_type_sint8;
+ if (sym == sym_1("s16"))
+ return &ffi_type_sint16;
+ if (sym == sym_1("s32"))
+ return &ffi_type_sint32;
+ if (sym == sym_1("s64"))
+ return &ffi_type_sint64;
+ if (sym == sym_1("sw"))
+ return &ffi_type_sint;
+ if (sym == sym_1("u8"))
+ return &ffi_type_uint8;
+ if (sym == sym_1("u16"))
+ return &ffi_type_uint16;
+ if (sym == sym_1("u32"))
+ return &ffi_type_uint32;
+ if (sym == sym_1("u64"))
+ return &ffi_type_uint64;
+ if (sym == sym_1("uw"))
+ return &ffi_type_uint;
+ assert(! "sym_to_ffi_type: unknown type");
+ errx(1, "sym_to_ffi_type: unknown type");
+ return NULL;
+}
+
+e_tag_type sym_to_tag_type (const s_sym *sym)
+{
+ if (sym == sym_1("void"))
+ return TAG_VOID;
+ if (sym == sym_1("bool"))
+ return TAG_BOOL;
+ if (sym == sym_1("call"))
+ return TAG_CALL;
+ if (sym == sym_1("call_fn"))
+ return TAG_CALL_FN;
+ if (sym == sym_1("call_macro"))
+ return TAG_CALL_MACRO;
+ if (sym == sym_1("cfn"))
+ return TAG_CFN;
+ if (sym == sym_1("character"))
+ return TAG_CHARACTER;
+ if (sym == sym_1("f32"))
+ return TAG_F32;
+ if (sym == sym_1("f64"))
+ return TAG_F64;
+ if (sym == sym_1("fn"))
+ return TAG_FN;
+ if (sym == sym_1("ident"))
+ return TAG_IDENT;
+ if (sym == sym_1("integer"))
+ return TAG_INTEGER;
+ if (sym == sym_1("s64"))
+ return TAG_S64;
+ if (sym == sym_1("s32"))
+ return TAG_S32;
+ if (sym == sym_1("s16"))
+ return TAG_S16;
+ if (sym == sym_1("s8"))
+ return TAG_S8;
+ if (sym == sym_1("u8"))
+ return TAG_U8;
+ if (sym == sym_1("u16"))
+ return TAG_U16;
+ if (sym == sym_1("u32"))
+ return TAG_U32;
+ if (sym == sym_1("u64"))
+ return TAG_U64;
+ if (sym == sym_1("list"))
+ return TAG_LIST;
+ if (sym == sym_1("ptag"))
+ return TAG_PTAG;
+ if (sym == sym_1("quote"))
+ return TAG_QUOTE;
+ if (sym == sym_1("str"))
+ return TAG_STR;
+ if (sym == sym_1("sym"))
+ return TAG_SYM;
+ if (sym == sym_1("tag"))
+ return TAG_VOID;
+ if (sym == sym_1("tuple"))
+ return TAG_TUPLE;
+ assert(! "sym_to_tag_type: unknown type");
+ errx(1, "sym_to_tag_type: unknown type: %s", sym->str.ptr.ps8);
+ return -1;
+}
diff --git a/libc3/sym.h b/libc3/sym.h
index 95138e4..59e9f61 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -48,6 +48,7 @@ e_bool sym_is_module (const s_sym *sym);
const s_sym * sym_new (const s_str *src);
-e_tag_type sym_to_e_tag_type(const s_sym *sym);
+ffi_type * sym_to_ffi_type (const s_sym *sym, ffi_type *result_type);
+e_tag_type sym_to_tag_type (const s_sym *sym);
#endif /* SYM_H */
diff --git a/libc3/tag.c b/libc3/tag.c
index a487f53..e618bd8 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1971,11 +1971,11 @@ void * tag_to_pointer (s_tag *tag, const s_sym *type)
case TAG_VAR:
goto invalid_type;
}
- assert(! "cfn_tag_to_ffi_value: invalid tag type");
- errx(1, "cfn_tag_to_ffi_value: invalid tag type");
+ assert(! "tag_to_pointer: invalid tag type");
+ errx(1, "tag_to_pointer: invalid tag type");
return NULL;
invalid_type:
- warnx("cfn_tag_to_ffi_value: cannot cast %s to %s",
+ warnx("tag_to_pointer: cannot cast %s to %s",
tag_type_to_sym(tag->type.type)->str.ptr.ps8,
type->str.ptr.ps8);
return NULL;
diff --git a/libc3/tag.h b/libc3/tag.h
index d5d1bb7..b9ab1a7 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -99,6 +99,7 @@ s8 tag_number_compare (const s_tag *a, const s_tag *b);
sw tag_size (const s_tag *tag);
sw tag_type_size (e_tag_type type);
f_buf_parse tag_type_to_buf_parse (e_tag_type type);
+void * tag_to_pointer (s_tag *tag, const s_sym *type);
s8 * tag_type_to_string (e_tag_type type);
const s_sym * tag_type_to_sym (e_tag_type tag_type);
diff --git a/test/Makefile b/test/Makefile
index a6c8405..cc2529d 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -69,6 +69,9 @@ test_debug: libc3_test_debug
test_ic3:
IC3=${SRC_TOP}/ic3/ic3 time ./ic3_test
+test_ic3_debug:
+ IC3=${SRC_TOP}/ic3/ic3_debug time ./ic3_test
+
test_valgrind: libc3_test
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./libc3_test
diff --git a/test/ic3/array.err.expected b/test/ic3/array.err.expected
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/ic3/array.err.expected
diff --git a/test/ic3/array.in b/test/ic3/array.in
new file mode 100644
index 0000000..81548b8
--- /dev/null
+++ b/test/ic3/array.in
@@ -0,0 +1,2 @@
+(u8) [0, 1]
+(u8) [[0, 1], [2, 3]]
diff --git a/test/ic3/array.out.expected b/test/ic3/array.out.expected
new file mode 100644
index 0000000..81548b8
--- /dev/null
+++ b/test/ic3/array.out.expected
@@ -0,0 +1,2 @@
+(u8) [0, 1]
+(u8) [[0, 1], [2, 3]]
diff --git a/test/ic3/array.ret.expected b/test/ic3/array.ret.expected
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/test/ic3/array.ret.expected
@@ -0,0 +1 @@
+0
diff --git a/test/ic3/call.in b/test/ic3/call.in
index ae37a9b..9cfcb23 100644
--- a/test/ic3/call.in
+++ b/test/ic3/call.in
@@ -6,8 +6,8 @@ quote Test.test()
quote Test.test(1)
quote Test.test(1, 2)
quote Test.test(1, 2, 3)
-quote first([1, 2])
-quote C3.first([1, 2])
+quote first((1, 2))
+quote C3.first((1, 2))
-first([1, 2])
-C3.first([2, 3])
+first((1, 2))
+C3.first((2, 3))
diff --git a/test/ic3/call.out.expected b/test/ic3/call.out.expected
index 822192c..23cb720 100644
--- a/test/ic3/call.out.expected
+++ b/test/ic3/call.out.expected
@@ -14,9 +14,9 @@ quote Test.test(1, 2)
quote Test.test(1, 2, 3)
-quote first([1, 2])
+quote first((1, 2))
-quote C3.first([1, 2])
+quote C3.first((1, 2))
1
diff --git a/test/ic3/fn.in b/test/ic3/fn.in
index df3ef2d..5d4daf3 100644
--- a/test/ic3/fn.in
+++ b/test/ic3/fn.in
@@ -1,16 +1,16 @@
quote fn (x) { x }
quote fn (x, _y) { x }
-quote fn ([x | _y]) { x }
+quote fn ((x | _y)) { x }
quote fn {
- ([]) { :error }
- ([x | _y]) { x }
+ (()) { :error }
+ ((x | _y)) { x }
(_) { :error }
}
fn (x) { x }
fn (x, _y) { x }
-fn ([x | _y]) { x }
+fn ((x | _y)) { x }
fn {
- ([]) { :error }
- ([x | _y]) { x }
+ (()) { :error }
+ ((x | _y)) { x }
(_) { :error }
}
diff --git a/test/ic3/fn.out.expected b/test/ic3/fn.out.expected
index d068afe..5d24ef1 100644
--- a/test/ic3/fn.out.expected
+++ b/test/ic3/fn.out.expected
@@ -2,11 +2,11 @@ quote fn (x) { x }
quote fn (x, _y) { x }
-quote fn ([x | _y]) { x }
+quote fn ((x | _y)) { x }
quote fn {
- ([]) { :error }
- ([x | _y]) { x }
+ (()) { :error }
+ ((x | _y)) { x }
(_) { :error }
}
@@ -15,11 +15,11 @@ fn (x) { x }
fn (x, _y) { x }
-fn ([x | _y]) { x }
+fn ((x | _y)) { x }
fn {
- ([]) { :error }
- ([x | _y]) { x }
+ (()) { :error }
+ ((x | _y)) { x }
(_) { :error }
}
diff --git a/test/ic3/list.out.expected b/test/ic3/list.out.expected
index 7339476..d85228a 100644
--- a/test/ic3/list.out.expected
+++ b/test/ic3/list.out.expected
@@ -1,45 +1,45 @@
-[]
+()
-[[]]
+(())
-[[], []]
+((), ())
-[[], [], []]
+((), (), ())
-[[], [], [], []]
+((), (), (), ())
-[[], []]
+((), ())
-[[], [], []]
+((), (), ())
-[[], [], []]
+((), (), ())
-[[], [], [], []]
+((), (), (), ())
-[[], []]
+((), ())
-[[], [], []]
+((), (), ())
-[[], [], [], []]
+((), (), (), ())
-[[[], []], [], []]
+(((), ()), (), ())
-[[[]], []]
+((()), ())
-[a]
+(a)
-[a, b]
+(a, b)
-[a, b, c]
+(a, b, c)
-[a | b]
+(a | b)
-[a, b | c]
+(a, b | c)
-[a, b, c, d]
+(a, b, c, d)
-[a, b, c | d]
+(a, b, c | d)
-[a, b, c | d]
+(a, b, c | d)
diff --git a/test/ic3/tuple.in b/test/ic3/tuple.in
index 8c450ff..c9bdfbe 100644
--- a/test/ic3/tuple.in
+++ b/test/ic3/tuple.in
@@ -1,7 +1,7 @@
-{[], []}
+{(), ()}
{"", ""}
-{[], ""}
-{"", []}
+{(), ""}
+{"", ()}
{:a, :b}
{:a, :b, :c}
{:a, :b, :c, :d}
diff --git a/test/ic3/tuple.out.expected b/test/ic3/tuple.out.expected
index 1f3a6c0..1a8ea5f 100644
--- a/test/ic3/tuple.out.expected
+++ b/test/ic3/tuple.out.expected
@@ -1,10 +1,10 @@
-{[], []}
+{(), ()}
{"", ""}
-{[], ""}
+{(), ""}
-{"", []}
+{"", ()}
{:a, :b}