diff --git a/.ic3_history b/.ic3_history
index 6f974c0..19dcf54 100644
--- a/.ic3_history
+++ b/.ic3_history
@@ -1,10 +1,3 @@
-make
-%GL.Sphere{}
-a = (U8) {0, 1}
-a[0]
-a[1]
-0.0
-123+123
123 + 123
123.123
123.123f
@@ -97,3 +90,10 @@ facts_next_id()
4.0 / 1920.0
4.0f / 1920.0f
4.0f / 1200.0f
+U8[]
+D
+U8[]
+U8[1]
+(U8[]) { 1, 2, 3 }
+(U8[]) {1, 2, 3}
+(U8[]) {0}
diff --git a/libc3/array.c b/libc3/array.c
index 585b469..b10a46e 100644
--- a/libc3/array.c
+++ b/libc3/array.c
@@ -40,19 +40,21 @@ void array_clean (s_array *a)
{
u8 *data;
uw i;
+ bool must_clean;
uw size;
assert(a);
free(a->dimensions);
- if (a->data) {
- if (sym_type_size(a->type, &size) &&
- size) {
- data = a->data;
- i = 0;
- while (i < a->count) {
- data_clean(a->type, data);
- data += size;
- i++;
- }
+ if (a->data &&
+ sym_must_clean(a->element_type, &must_clean) &&
+ must_clean &&
+ sym_type_size(a->element_type, &size) &&
+ size) {
+ data = a->data;
+ i = 0;
+ while (i < a->count) {
+ data_clean(a->element_type, data);
+ data += size;
+ i++;
}
}
if (a->free_data)
@@ -101,7 +103,7 @@ s_array * array_data_set (s_array *a, const uw *address,
assert(data);
a_data = array_data(a, address);
if (a_data) {
- if (! data_init_copy(a->type, a_data, data))
+ if (! data_init_copy(a->element_type, a_data, data))
return NULL;
return a;
}
@@ -142,9 +144,9 @@ s_tag * array_data_tag (const s_tag *a, const s_tag *address,
a_data = array_data(&a->data.array, address->data.array.data);
if (! a_data)
return NULL;
- if (! sym_to_tag_type(a->data.array.type, &tmp.type) ||
- ! tag_to_pointer(&tmp, a->data.array.type, &tmp_data) ||
- ! data_init_copy(a->data.array.type, tmp_data, a_data))
+ if (! sym_to_tag_type(a->data.array.element_type, &tmp.type) ||
+ ! tag_to_pointer(&tmp, a->data.array.element_type, &tmp_data) ||
+ ! data_init_copy(a->data.array.element_type, tmp_data, a_data))
return NULL;
*dest = tmp;
return dest;
@@ -160,7 +162,7 @@ s_array * array_free (s_array *a)
return a;
}
-s_array * array_init (s_array *a, const s_sym *type, uw dimension,
+s_array * array_init (s_array *a, const s_sym *array_type, uw dimension,
const uw *dimensions)
{
uw count = 1;
@@ -168,9 +170,10 @@ s_array * array_init (s_array *a, const s_sym *type, uw dimension,
uw item_size;
s_array tmp = {0};
assert(a);
- assert(type);
- assert(sym_is_module(type));
- tmp.type = type;
+ assert(array_type);
+ assert(sym_is_array_type(array_type));
+ tmp.array_type = array_type;
+ tmp.element_type = sym_array_type(array_type);
if (dimension) {
#ifdef DEBUG
while (i < dimension) {
@@ -187,7 +190,7 @@ s_array * array_init (s_array *a, const s_sym *type, uw dimension,
i++;
}
i--;
- if (! sym_type_size(type, &item_size)) {
+ if (! sym_type_size(tmp.element_type, &item_size)) {
free(tmp.dimensions);
return NULL;
}
@@ -261,13 +264,15 @@ s_array * array_init_copy (s_array *a, const s_array *src)
u8 *data_src;
uw i = 0;
uw item_size;
+ bool must_clean;
s_array tmp = {0};
assert(a);
assert(src);
- tmp.count = src->count;
- tmp.dimension = src->dimension;
- tmp.size = src->size;
- tmp.type = src->type;
+ tmp.array_type = src->array_type;
+ tmp.count = src->count;
+ tmp.dimension = src->dimension;
+ tmp.element_type = src->element_type;
+ tmp.size = src->size;
if (tmp.dimension) {
if (! (tmp.dimensions = calloc(tmp.dimension,
sizeof(s_array_dimension)))) {
@@ -290,7 +295,7 @@ s_array * array_init_copy (s_array *a, const s_array *src)
i = 0;
item_size = src->dimensions[src->dimension - 1].item_size;
while (i < src->count) {
- if (! data_init_copy(src->type, data_tmp, data_src))
+ if (! data_init_copy(src->element_type, data_tmp, data_src))
goto ko_data;
data_tmp += item_size;
data_src += item_size;
@@ -316,10 +321,12 @@ s_array * array_init_copy (s_array *a, const s_array *src)
*a = tmp;
return a;
ko_data:
- if (i) {
+ if (i &&
+ sym_must_clean(src->element_type, &must_clean) &&
+ must_clean) {
while (--i) {
data_tmp -= item_size;
- data_clean(src->type, data_tmp);
+ data_clean(src->element_type, data_tmp);
}
}
free(tmp.data);
@@ -335,7 +342,8 @@ s_array * array_init_copy (s_array *a, const s_array *src)
s_array * array_init_void (s_array *array)
{
s_array tmp = {0};
- tmp.type = &g_sym_Void;
+ tmp.array_type = sym_1("Void[0]");
+ tmp.element_type = &g_sym_Void;
*array = tmp;
return array;
}
diff --git a/libc3/array.h b/libc3/array.h
index 832ba59..8025bd8 100644
--- a/libc3/array.h
+++ b/libc3/array.h
@@ -17,7 +17,7 @@
/* Stack-allocation compatible functions, call array_clean after use. */
void array_clean (s_array *a);
-s_array * array_init (s_array *a, const s_sym *type,
+s_array * array_init (s_array *a, const s_sym *array_type,
uw dimension, const uw *dimensions);
s_array * array_init_1 (s_array *a, const char *p);
s_array * array_init_cast (s_array *a, const s_tag *tag);
diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 880367c..9efdc7f 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -47,7 +47,8 @@ sw buf_inspect_array (s_buf *buf, const s_array *array)
sw result = 0;
assert(buf);
assert(array);
- if ((r = buf_inspect_paren_sym(buf, array->type)) <= 0)
+ assert(sym_is_array_type(array->array_type));
+ if ((r = buf_inspect_paren_sym(buf, array->array_type)) <= 0)
goto clean;
result += r;
if ((r = buf_write_1(buf, " ")) < 0)
@@ -104,7 +105,8 @@ sw buf_inspect_array_data_rec (s_buf *buf, const s_array *array,
while (1) {
if (dimension == array->dimension - 1) {
if (*data) {
- if ((r = data_buf_inspect(array->type, buf, *data)) <= 0)
+ if ((r = data_buf_inspect(array->element_type,
+ buf, *data)) <= 0)
goto clean;
result += r;
*data += array->dimensions[dimension].item_size;
@@ -169,7 +171,8 @@ sw buf_inspect_array_data_size_rec (const s_array *array,
while (1) {
if (dimension == array->dimension - 1) {
if (*data) {
- if ((r = data_buf_inspect_size(array->type, *data)) <= 0)
+ if ((r = data_buf_inspect_size(array->element_type,
+ *data)) <= 0)
goto clean;
result += r;
*data += array->dimensions[dimension].item_size;
@@ -206,7 +209,7 @@ sw buf_inspect_array_size (const s_array *array)
sw r;
sw result = 0;
assert(array);
- if ((r = buf_inspect_paren_sym_size(array->type)) <= 0)
+ if ((r = buf_inspect_paren_sym_size(array->array_type)) <= 0)
goto clean;
result += r;
r = strlen(" ");
@@ -2063,7 +2066,7 @@ sw buf_inspect_sym (s_buf *buf, const s_sym * const *sym)
return buf_write_1(buf, ":\"\"");
if (sym_has_reserved_characters(x))
return buf_inspect_sym_reserved(buf, x);
- if (sym_is_module(x))
+ if (sym_is_module(x) || sym_is_array_type(x))
return buf_write_str(buf, &x->str);
size = x->str.size + 1;
if ((r = buf_write_1(buf, ":")) < 0 ||
@@ -2083,7 +2086,7 @@ sw buf_inspect_sym_size (const s_sym * const *sym)
return 3;
if (sym_has_reserved_characters(x))
return buf_inspect_sym_reserved_size(x);
- if (sym_is_module(x))
+ if (sym_is_module(x) || sym_is_array_type(x))
return x->str.size;
return x->str.size + colon_size;
}
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index d89fcd1..6417ec5 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -52,9 +52,14 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
assert(buf);
assert(dest);
buf_save_init(buf, &save);
- if ((r = buf_parse_paren_sym(buf, &tmp.type)) <= 0)
+ if ((r = buf_parse_paren_sym(buf, &tmp.array_type)) <= 0)
goto clean;
result += r;
+ if (! sym_is_array_type(tmp.array_type)) {
+ r = 0;
+ goto restore;
+ }
+ tmp.element_type = sym_array_type(tmp.array_type);
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
result += r;
@@ -279,7 +284,7 @@ sw buf_parse_array_dimensions (s_buf *buf, s_array *dest)
assert(buf);
assert(dest);
tmp = *dest;
- if (! sym_type_size(tmp.type, &size))
+ if (! sym_type_size(tmp.element_type, &size))
return -1;
if (! size) {
err_puts("buf_parse_array_dimensions: zero item size");
@@ -474,7 +479,7 @@ sw buf_parse_brackets (s_buf *buf, s_call *dest)
goto restore;
}
arg_addr->type = TAG_ARRAY;
- if (! list_to_array(addr, &g_sym_Uw, &arg_addr->data.array))
+ if (! list_to_array(addr, &g_sym_Uw_brackets, &arg_addr->data.array))
goto restore;
ident_init(&tmp.ident, NULL, &g_sym__brackets);
if (! operator_resolve(&tmp.ident, 2, &tmp.ident)) {
@@ -2766,12 +2771,24 @@ sw buf_parse_sym (s_buf *buf, const s_sym **dest)
while (1) {
if ((r = buf_peek_character_utf8(buf, &c)) <= 0)
break;
- if (c == '.') {
+ if (c == '[') {
if ((r = buf_peek_next_character_utf8(buf, &c)) <= 0)
+ break;
+ if (c != ']')
+ break;
+ csize = r;
+ if ((r = buf_xfer(&tmp, buf, csize)) < 0)
goto restore;
+ result += r;
+ break;
+ }
+ else if (c == '.') {
+ csize = r;
+ if ((r = buf_peek_next_character_utf8(buf, &c)) <= 0)
+ break;
if (! character_is_uppercase(c))
break;
- r = 1;
+ r += csize;
}
else if (sym_character_is_reserved(c))
break;
diff --git a/libc3/env.c b/libc3/env.c
index b82c21e..2249592 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -118,7 +118,7 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
array_init_copy(&tmp, array);
if (tmp.dimension) {
item_size = tmp.dimensions[tmp.dimension - 1].item_size;
- if (! tmp.data && array->tags) {
+ if (! tmp.data && tmp.tags) {
tmp.data = tmp.free_data = calloc(tmp.dimensions[0].count,
tmp.dimensions[0].item_size);
if (! tmp.data) {
@@ -132,11 +132,11 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
while (i < tmp.count) {
if (! env_eval_tag(env, tag, &tag_eval))
goto ko;
- if (! data_init_cast(array->type, data, &tag_eval)) {
+ if (! data_init_cast(tmp.element_type, data, &tag_eval)) {
err_write_1("env_eval_array: cannot cast ");
err_inspect_tag(&tag_eval);
err_write_1(" to ");
- err_inspect_sym(&tmp.type);
+ err_inspect_sym(&tmp.element_type);
err_puts(".");
goto ko;
}
diff --git a/libc3/hash.c b/libc3/hash.c
index b75181d..57ffe00 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -18,6 +18,7 @@
#include "hash.h"
#include "list.h"
#include "str.h"
+#include "sym.h"
#include "tag.h"
#include "tag_type.h"
@@ -78,13 +79,15 @@ bool hash_update_1 (t_hash *hash, const char *p)
bool hash_update_array (t_hash *hash, const s_array *a)
{
+ u8 *data;
uw i = 0;
+ uw size;
const char type[] = "array";
assert(hash);
assert(a);
if (! hash_update(hash, type, sizeof(type)) ||
- ! hash_update(hash, &a->dimension, sizeof(a->dimension)) ||
- ! hash_update(hash, &a->type, sizeof(a->type)))
+ ! hash_update_sym(hash, &a->array_type) ||
+ ! hash_update(hash, &a->dimension, sizeof(a->dimension)))
return false;
while (i < a->dimension) {
if (! hash_update(hash, &a->dimensions[i].count,
@@ -92,9 +95,16 @@ bool hash_update_array (t_hash *hash, const s_array *a)
return false;
i++;
}
- if (a->data) {
- if (! hash_update(hash, a->data, a->size))
- return false;
+ if (a->data &&
+ sym_type_size(a->element_type, &size) &&
+ size) {
+ data = a->data;
+ i = 0;
+ while (i < a->count) {
+ if (! data_hash_update(a->element_type, hash, data))
+ return false;
+ data += size;
+ }
}
else if (a->tags) {
i = 0;
diff --git a/libc3/list.c b/libc3/list.c
index bac4a82..da452d2 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -250,27 +250,29 @@ s_list ** list_remove_void (s_list **list)
return list;
}
-s_array * list_to_array (const s_list *list, const s_sym *type,
+s_array * list_to_array (const s_list *list, const s_sym *array_type,
s_array *dest)
{
s8 *data;
const void *data_list;
const s_list *l;
uw len;
+ bool must_clean;
uw size;
s_array tmp = {0};
assert(list);
- assert(type);
+ assert(array_type);
assert(dest);
len = list_length(list);
- if (! sym_type_size(type, &size))
+ if (! sym_type_size(array_type, &size))
return NULL;
if (! size) {
err_puts("list_to_array: zero item size");
assert(! "list_to_array: zero item size");
return NULL;
}
- tmp.type = type;
+ tmp.array_type = array_type;
+ tmp.element_type = sym_array_type(array_type);
if (len) {
tmp.dimension = 1;
tmp.dimensions = calloc(1, sizeof(s_array_dimension));
@@ -293,10 +295,10 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
data = tmp.data = tmp.free_data;
l = list;
while (l) {
- if (! tag_to_const_pointer(&l->tag, type, &data_list))
+ if (! tag_to_const_pointer(&l->tag, tmp.element_type, &data_list))
goto ko;
if (data_list) {
- if (! data_init_copy(type, data, data_list))
+ if (! data_init_copy(tmp.element_type, data, data_list))
goto ko;
}
data += size;
@@ -306,9 +308,12 @@ s_array * list_to_array (const s_list *list, const s_sym *type,
*dest = tmp;
return dest;
ko:
- while (data > (s8 *) tmp.data) {
- data -= size;
- data_clean(type, data);
+ if (sym_must_clean(tmp.element_type, &must_clean) &&
+ must_clean) {
+ while (data > (s8 *) tmp.data) {
+ data -= size;
+ data_clean(tmp.element_type, data);
+ }
}
free(tmp.data);
free(tmp.dimensions);
diff --git a/libc3/struct.c b/libc3/struct.c
index bf0dbea..b044893 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -46,6 +46,9 @@ void struct_clean (s_struct *s)
uw i;
const s_sym *sym;
assert(s);
+ assert(s->type);
+ if (! s->type->must_clean)
+ return;
if (s->data) {
i = 0;
while (i < s->type->map.count) {
diff --git a/libc3/struct_type.c b/libc3/struct_type.c
index 84ffdf4..0510f4f 100644
--- a/libc3/struct_type.c
+++ b/libc3/struct_type.c
@@ -54,10 +54,12 @@ s_struct_type * struct_type_init (s_struct_type *st,
{
uw count;
uw i;
+ bool must_clean;
uw offset;
const s_list *s;
uw size;
const s_tuple *tuple;
+ const s_sym *type;
assert(st);
assert(module);
assert(spec);
@@ -71,6 +73,7 @@ s_struct_type * struct_type_init (s_struct_type *st,
map_clean(&st->map);
return NULL;
}
+ st->must_clean = false;
offset = 0;
i = 0;
s = spec;
@@ -89,6 +92,14 @@ s_struct_type * struct_type_init (s_struct_type *st,
}
tag_init_copy(st->map.key + i, tuple->tag + 0);
tag_init_copy(st->map.value + i, tuple->tag + 1);
+ tag_type(st->map.value + i, &type);
+ if (! sym_must_clean(type, &must_clean)) {
+ map_clean(&st->map);
+ free(st->offset);
+ return NULL;
+ }
+ if (must_clean)
+ st->must_clean = true;
offset = struct_type_padding(offset, size);
st->offset[i] = offset;
offset += size;
diff --git a/libc3/struct_type.h b/libc3/struct_type.h
index 7d9c50f..c41baf7 100644
--- a/libc3/struct_type.h
+++ b/libc3/struct_type.h
@@ -31,11 +31,6 @@ s_struct_type * struct_type_init (s_struct_type *s, const s_sym *module,
const s_list *spec);
s_struct_type * struct_type_init_copy (s_struct_type *s,
const s_struct_type *src);
-/*
-s_struct_type * struct_type_init_from_env (s_struct_type *st,
- const s_sym *module,
- s_env *env);
-*/
/* Heap-allocation functions, call struct_type_delete after use. */
void struct_type_delete (s_struct_type *s);
diff --git a/libc3/sym.c b/libc3/sym.c
index 90d068d..717e2f8 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -53,6 +53,7 @@ const s_sym g_sym_U16 = {{{NULL}, 3, {"U16"}}};
const s_sym g_sym_U32 = {{{NULL}, 3, {"U32"}}};
const s_sym g_sym_U64 = {{{NULL}, 3, {"U64"}}};
const s_sym g_sym_Uw = {{{NULL}, 2, {"Uw"}}};
+const s_sym g_sym_Uw_brackets = {{{NULL}, 4, {"Uw[]"}}};
const s_sym g_sym_Var = {{{NULL}, 3, {"Var"}}};
const s_sym g_sym_Void = {{{NULL}, 4, {"Void"}}};
const s_sym g_sym_defstruct = {{{NULL}, 9, {"defstruct"}}};
@@ -82,6 +83,45 @@ const s_sym * sym_1 (const char *p)
return str_to_sym(&stra);
}
+const s_sym * sym_array_type (const s_sym *sym)
+{
+ s_buf buf;
+ character c;
+ sw r;
+ bool separator;
+ s_str str;
+ const s_sym *tmp;
+ assert(sym);
+ buf_init_alloc(&buf, sym->str.size);
+ str = sym->str;
+ separator = true;
+ while (1) {
+ if (separator) {
+ if (str_read_character_utf8(&str, &c) <= 0)
+ return NULL;
+ if (! character_is_uppercase(c))
+ return NULL;
+ separator = false;
+ buf_write_character_utf8(&buf, c);
+ }
+ else {
+ r = str_read_character_utf8(&str, &c);
+ if (r <= 0)
+ return NULL;
+ if (c == '.')
+ separator = true;
+ else if (c == '[') {
+ buf_read_to_str(&buf, &str);
+ tmp = str_to_sym(&str);
+ str_clean(&str);
+ return tmp;
+ }
+ buf_write_character_utf8(&buf, c);
+ }
+ }
+ return NULL;
+}
+
bool sym_character_is_reserved (character c)
{
return (character_is_space(c) ||
@@ -135,12 +175,21 @@ const s_sym * sym_find (const s_str *str)
bool sym_has_reserved_characters (const s_sym *sym)
{
character c;
+ bool is_array_type;
sw r;
s_str stra;
str_init(&stra, NULL, sym->str.size, sym->str.ptr.p);
+ is_array_type = sym_is_array_type(sym);
while (1) {
if ((r = str_read_character_utf8(&stra, &c)) <= 0)
break;
+ if (is_array_type && c == '[') {
+ if ((r = str_read_character_utf8(&stra, &c)) <= 0)
+ return true;
+ if (c == ']' &&
+ (r = str_peek_character_utf8(&stra, &c)) <= 0)
+ return false;
+ }
if (c == '.') {
if ((r = str_peek_character_utf8(&stra, &c)) <= 0)
return true;
@@ -232,6 +281,7 @@ void sym_init_g_sym (void)
sym_intern(&g_sym_U32, NULL);
sym_intern(&g_sym_U64, NULL);
sym_intern(&g_sym_Uw, NULL);
+ sym_intern(&g_sym_Uw_brackets, NULL);
sym_intern(&g_sym_Var, NULL);
sym_intern(&g_sym_Void, NULL);
sym_intern(&g_sym_cast, NULL);
@@ -288,12 +338,64 @@ bool sym_intern (const s_sym *sym, s_sym *free_sym)
return true;
}
+bool sym_is_array_type (const s_sym *sym)
+{
+ character c;
+ sw r;
+ bool separator;
+ s_str str;
+ assert(sym);
+ str = sym->str;
+ separator = true;
+ while (1) {
+ if (separator) {
+ if (str_read_character_utf8(&str, &c) <= 0)
+ return false;
+ if (! character_is_uppercase(c))
+ return false;
+ separator = false;
+ }
+ else {
+ r = str_read_character_utf8(&str, &c);
+ if (r <= 0)
+ return false;
+ if (c == '.')
+ separator = true;
+ if (c == '[')
+ return true;
+ }
+ }
+ return false;
+}
+
bool sym_is_module (const s_sym *sym)
{
character c;
- if (str_peek_character_utf8(&sym->str, &c) <= 0)
- return false;
- return character_is_uppercase(c);
+ sw r;
+ bool separator;
+ s_str str;
+ assert(sym);
+ str = sym->str;
+ separator = true;
+ while (1) {
+ if (separator) {
+ if (str_read_character_utf8(&str, &c) <= 0)
+ return false;
+ if (! character_is_uppercase(c))
+ return false;
+ separator = false;
+ }
+ else {
+ r = str_read_character_utf8(&str, &c);
+ if (r <= 0)
+ return true;
+ if (c == '.')
+ separator = true;
+ if (c == '[')
+ return false;
+ }
+ }
+ return true;
}
s_sym_list * sym_list_new (const s_sym *sym, s_sym *free_sym,
@@ -314,10 +416,9 @@ s_sym_list * sym_list_new (const s_sym *sym, s_sym *free_sym,
bool sym_must_clean (const s_sym *sym, bool *must_clean)
{
- if (sym_is_array_type(sym)) {
- *must_clean = sym_must_clean(sym_array_type(sym));
- return true;
- }
+ const s_struct_type *st;
+ if (sym_is_array_type(sym))
+ sym = sym_array_type(sym);
if (sym == &g_sym_Bool) {
*must_clean = false;
return true;
@@ -422,8 +523,9 @@ bool sym_must_clean (const s_sym *sym, bool *must_clean)
*must_clean = false;
return true;
}
- if (struct_type_exists(sym)) {
- *must_clean = struct_type_must_clean(sym);
+ st = struct_type_find(sym);
+ if (st) {
+ *must_clean = st->must_clean;
return true;
}
err_write_1("sym_must_clean: unknown type: ");
@@ -588,290 +690,6 @@ bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
return false;
}
-/*
-bool sym_to_init_cast (const s_sym *type, f_init_cast *dest)
-{
- if (type == &g_sym_Array) {
- *dest = (f_init_cast) array_init_cast;
- return true;
- }
- if (type == &g_sym_Bool) {
- *dest = (f_init_cast) bool_init_cast;
- return true;
- }
- if (type == &g_sym_Call) {
- *dest = (f_init_cast) call_init_cast;
- return true;
- }
- if (type == &g_sym_Cfn) {
- *dest = (f_init_cast) cfn_init_cast;
- return true;
- }
- if (type == &g_sym_Character) {
- *dest = (f_init_cast) character_init_cast;
- return true;
- }
- if (type == &g_sym_F32) {
- *dest = (f_init_cast) f32_init_cast;
- return true;
- }
- if (type == &g_sym_F64) {
- *dest = (f_init_cast) f64_init_cast;
- return true;
- }
- if (type == &g_sym_Fact) {
- *dest = (f_init_cast) fact_init_cast;
- return true;
- }
- if (type == &g_sym_Fn) {
- *dest = (f_init_cast) fn_init_cast;
- return true;
- }
- if (type == &g_sym_Ident) {
- *dest = (f_init_cast) ident_init_cast;
- return true;
- }
- if (type == &g_sym_Integer) {
- *dest = (f_init_cast) integer_init_cast;
- return true;
- }
- if (type == &g_sym_List) {
- *dest = (f_init_cast) list_init_cast;
- return true;
- }
- if (type == &g_sym_Ptag) {
- *dest = (f_init_cast) ptag_init_cast;
- return true;
- }
- if (type == &g_sym_Ptr) {
- *dest = (f_init_cast) ptr_init_cast;
- return true;
- }
- if (type == &g_sym_PtrFree) {
- *dest = (f_init_cast) ptr_free_init_cast;
- return true;
- }
- if (type == &g_sym_Quote) {
- *dest = (f_init_cast) quote_init_cast;
- return true;
- }
- if (type == &g_sym_S8) {
- *dest = (f_init_cast) s8_init_cast;
- return true;
- }
- if (type == &g_sym_S16) {
- *dest = (f_init_cast) s16_init_cast;
- return true;
- }
- if (type == &g_sym_S32) {
- *dest = (f_init_cast) s32_init_cast;
- return true;
- }
- if (type == &g_sym_S64) {
- *dest = (f_init_cast) s64_init_cast;
- return true;
- }
- if (type == &g_sym_Str) {
- *dest = (f_init_cast) str_init_cast;
- return true;
- }
- if (type == &g_sym_Struct) {
- *dest = (f_init_cast) struct_init_cast;
- return true;
- }
- if (type == &g_sym_Sw) {
- *dest = (f_init_cast) sw_init_cast;
- return true;
- }
- if (type == &g_sym_Sym) {
- *dest = (f_init_cast) sym_init_cast;
- return true;
- }
- if (type == &g_sym_Tuple) {
- *dest = (f_init_cast) tuple_init_cast;
- return true;
- }
- if (type == &g_sym_U8) {
- *dest = (f_init_cast) u8_init_cast;
- return true;
- }
- if (type == &g_sym_U16) {
- *dest = (f_init_cast) u16_init_cast;
- return true;
- }
- if (type == &g_sym_U32) {
- *dest = (f_init_cast) u32_init_cast;
- return true;
- }
- if (type == &g_sym_U64) {
- *dest = (f_init_cast) u64_init_cast;
- return true;
- }
- if (type == &g_sym_Uw) {
- *dest = (f_init_cast) uw_init_cast;
- return true;
- }
- if (type == &g_sym_Var) {
- *dest = NULL;
- return true;
- }
- if (type == &g_sym_Void) {
- *dest = NULL;
- return true;
- }
- if (struct_type_exists(type)) {
- *dest = (f_init_cast) struct_init_cast;
- return true;
- }
- err_write_1("sym_to_init_cast: unknown type: ");
- err_inspect_sym(&type);
- err_write_1("\n");
- assert(! "sym_to_init_cast: unknown type");
- return false;
-}
-
-bool sym_to_init_copy (const s_sym *type, f_init_copy *dest)
-{
- if (type == &g_sym_Array) {
- *dest = (f_init_copy) array_init_copy;
- return true;
- }
- if (type == &g_sym_Bool) {
- *dest = (f_init_copy) bool_init_copy;
- return true;
- }
- if (type == &g_sym_Call) {
- *dest = (f_init_copy) call_init_copy;
- return true;
- }
- if (type == &g_sym_Cfn) {
- *dest = (f_init_copy) cfn_init_copy;
- return true;
- }
- if (type == &g_sym_Character) {
- *dest = (f_init_copy) character_init_copy;
- return true;
- }
- if (type == &g_sym_F32) {
- *dest = (f_init_copy) f32_init_copy;
- return true;
- }
- if (type == &g_sym_F64) {
- *dest = (f_init_copy) f64_init_copy;
- return true;
- }
- if (type == &g_sym_Fact) {
- *dest = (f_init_copy) fact_init_copy;
- return true;
- }
- if (type == &g_sym_Fn) {
- *dest = (f_init_copy) fn_init_copy;
- return true;
- }
- if (type == &g_sym_Ident) {
- *dest = (f_init_copy) ident_init_copy;
- return true;
- }
- if (type == &g_sym_Integer) {
- *dest = (f_init_copy) integer_init_copy;
- return true;
- }
- if (type == &g_sym_List) {
- *dest = (f_init_copy) list_init_copy;
- return true;
- }
- if (type == &g_sym_Ptag) {
- *dest = (f_init_copy) ptag_init_copy;
- return true;
- }
- if (type == &g_sym_Ptr) {
- *dest = (f_init_copy) ptr_init_copy;
- return true;
- }
- if (type == &g_sym_PtrFree) {
- *dest = (f_init_copy) ptr_free_init_copy;
- return true;
- }
- if (type == &g_sym_Quote) {
- *dest = (f_init_copy) quote_init_copy;
- return true;
- }
- if (type == &g_sym_S8) {
- *dest = (f_init_copy) s8_init_copy;
- return true;
- }
- if (type == &g_sym_S16) {
- *dest = (f_init_copy) s16_init_copy;
- return true;
- }
- if (type == &g_sym_S32) {
- *dest = (f_init_copy) s32_init_copy;
- return true;
- }
- if (type == &g_sym_S64) {
- *dest = (f_init_copy) s64_init_copy;
- return true;
- }
- if (type == &g_sym_Str) {
- *dest = (f_init_copy) str_init_copy;
- return true;
- }
- if (type == &g_sym_Struct) {
- *dest = (f_init_copy) struct_init_copy;
- return true;
- }
- if (type == &g_sym_Sw) {
- *dest = (f_init_copy) sw_init_copy;
- return true;
- }
- if (type == &g_sym_Sym) {
- *dest = (f_init_copy) sym_init_copy;
- return true;
- }
- if (type == &g_sym_Tuple) {
- *dest = (f_init_copy) tuple_init_copy;
- return true;
- }
- if (type == &g_sym_U8) {
- *dest = (f_init_copy) u8_init_copy;
- return true;
- }
- if (type == &g_sym_U16) {
- *dest = (f_init_copy) u16_init_copy;
- return true;
- }
- if (type == &g_sym_U32) {
- *dest = (f_init_copy) u32_init_copy;
- return true;
- }
- if (type == &g_sym_U64) {
- *dest = (f_init_copy) u64_init_copy;
- return true;
- }
- if (type == &g_sym_Uw) {
- *dest = (f_init_copy) uw_init_copy;
- return true;
- }
- if (type == &g_sym_Var) {
- *dest = NULL;
- return true;
- }
- if (type == &g_sym_Void) {
- *dest = NULL;
- return true;
- }
- if (struct_type_exists(type)) {
- *dest = (f_init_copy) struct_init_copy;
- return true;
- }
- err_write_1("sym_to_init_copy: unknown type: ");
- err_inspect_sym(&type);
- err_write_1("\n");
- assert(! "sym_to_init_copy: unknown type");
- return false;
-}
-*/
-
bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest)
{
if (sym == &g_sym_Array) {
diff --git a/libc3/sym.h b/libc3/sym.h
index 187721b..1d35048 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -65,6 +65,7 @@ extern const s_sym g_sym_U16;
extern const s_sym g_sym_U32;
extern const s_sym g_sym_U64;
extern const s_sym g_sym_Uw;
+extern const s_sym g_sym_Uw_brackets;
extern const s_sym g_sym_Var;
extern const s_sym g_sym_Void;
extern const s_sym g_sym_cast;
@@ -93,13 +94,14 @@ void sym_delete_all (void);
const s_sym * sym_new (const s_str *src);
/* Observers */
-bool sym_array_type (const s_sym *sym, s_sym *dest);
+const s_sym * sym_array_type (const s_sym *sym);
bool sym_character_is_reserved (character c);
const s_sym * sym_find (const s_str *src);
bool sym_has_reserved_characters (const s_sym *sym);
s_str * sym_inspect (const s_sym *sym, s_str *dest);
bool sym_is_array_type (const s_sym *sym);
bool sym_is_module (const s_sym *sym);
+bool sym_must_clean (const s_sym *sym, bool *must_clean);
bool sym_to_ffi_type (const s_sym *sym, ffi_type *result_type,
ffi_type **dest);
bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest);
diff --git a/libc3/tag.c b/libc3/tag.c
index 14dfd0d..7f5400a 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1009,7 +1009,9 @@ const s_sym ** tag_type (const s_tag *tag, const s_sym **dest)
assert(dest);
switch (tag->type) {
case TAG_VOID: *dest = &g_sym_Void; return dest;
- case TAG_ARRAY: *dest = &g_sym_Array; return dest;
+ case TAG_ARRAY:
+ *dest = tag->data.array.array_type;
+ return dest;
case TAG_BOOL: *dest = &g_sym_Bool; return dest;
case TAG_CALL: *dest = &g_sym_Call; return dest;
case TAG_CFN: *dest = &g_sym_Cfn; return dest;
diff --git a/libc3/types.h b/libc3/types.h
index d74e700..ca47f11 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -334,6 +334,7 @@ struct str {
struct struct_type {
const s_sym *module;
s_map map;
+ bool must_clean;
uw *offset;
uw size;
};
@@ -392,7 +393,8 @@ struct array {
void *free_data;
uw size;
s_tag *tags;
- const s_sym *type;
+ const s_sym *array_type;
+ const s_sym *element_type;
};
/* 5 */
diff --git a/test/array_test.c b/test/array_test.c
index 350d3be..8da115e 100644
--- a/test/array_test.c
+++ b/test/array_test.c
@@ -59,12 +59,12 @@ void array_test (void)
TEST_CASE(array_data)
{
s_array a;
- TEST_EQ(array_init_1(&a, "(U8) {1, 2, 3}"), &a);
+ TEST_EQ(array_init_1(&a, "(U8[]) {1, 2, 3}"), &a);
TEST_EQ(* (u8 *) array_data(&a, (uw []) {0}), 1);
TEST_EQ(* (u8 *) array_data(&a, (uw []) {1}), 2);
TEST_EQ(* (u8 *) array_data(&a, (uw []) {2}), 3);
array_clean(&a);
- TEST_EQ(array_init_1(&a, "(U8) {1 + 1, 2 + 2, 3 + 3}"), &a);
+ TEST_EQ(array_init_1(&a, "(U8[]) {1 + 1, 2 + 2, 3 + 3}"), &a);
TEST_EQ(* (u8 *) array_data(&a, (uw []) {0}), 2);
TEST_EQ(* (u8 *) array_data(&a, (uw []) {1}), 4);
TEST_EQ(* (u8 *) array_data(&a, (uw []) {2}), 6);
@@ -74,55 +74,65 @@ TEST_CASE_END(array_data)
TEST_CASE(array_init_clean)
{
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 1, (uw []) {1});
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 1, (uw []) {10});
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 1, (uw []) {100});
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 2, ((uw []) {1, 1}));
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 2, ((uw []) {10, 10}));
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 2, ((uw []) {100, 100}));
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 3, ((uw []) {1, 1, 1}));
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 3, ((uw []) {10, 10, 10}));
- ARRAY_TEST_INIT_CLEAN(sym_1("U8"), 3, ((uw []) {100, 100, 100}));
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 1, (uw []) {1});
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 1, (uw []) {10});
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 1, (uw []) {100});
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 2, ((uw []) {1, 1}));
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 2, ((uw []) {10, 10}));
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 2, ((uw []) {100, 100}));
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 3, ((uw []) {1, 1, 1}));
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 3, ((uw []) {10, 10, 10}));
+ ARRAY_TEST_INIT_CLEAN(sym_1("U8[]"), 3, ((uw []) {100, 100, 100}));
}
TEST_CASE_END(array_init_clean)
TEST_CASE(array_init_1_clean)
{
- ARRAY_TEST_INIT_1_CLEAN("(U8) {0}");
- ARRAY_TEST_INIT_1_CLEAN("(U8) {0, 0}");
- ARRAY_TEST_INIT_1_CLEAN("(U8) {0, 0, 0}");
- ARRAY_TEST_INIT_1_CLEAN("(U8) {{0}, {0}}");
- ARRAY_TEST_INIT_1_CLEAN("(U8) {{0, 0}, {0, 0}}");
- ARRAY_TEST_INIT_1_CLEAN("(U8) {{0, 0}, {0, 0}, {0, 0}}");
- ARRAY_TEST_INIT_1_CLEAN("(U8) {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {0}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {0, 0}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {0, 0, 0}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {{0}, {0}}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {{0, 0}, {0, 0}}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {{0, 0}, {0, 0}, {0, 0}}");
+ ARRAY_TEST_INIT_1_CLEAN("(U8[]) {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}}");
}
TEST_CASE_END(array_init_1_clean)
TEST_CASE(array_inspect)
{
- ARRAY_TEST_INSPECT("(U8) {0}",
- "(U8) {0}");
- ARRAY_TEST_INSPECT("(U8) {0, 0}",
- "(U8) {0, 0}");
- ARRAY_TEST_INSPECT("(U8) {0, 0, 0}",
- "(U8) {0, 0, 0}");
- ARRAY_TEST_INSPECT("(U8) {{0}, {0}}",
- "(U8) {{0}, {0}}");
- ARRAY_TEST_INSPECT("(U8) {{0, 0}, {0, 0}}",
- "(U8) {{0, 0}, {0, 0}}");
- ARRAY_TEST_INSPECT("(U8) {{0, 0}, {0, 0}, {0, 0}}",
- "(U8) {{0, 0}, {0, 0}, {0, 0}}");
- ARRAY_TEST_INSPECT("(U8) {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}}",
- "(U8) {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}}");
- ARRAY_TEST_INSPECT("(U8) {1, 2, 3}", "(U8) {1, 2, 3}");
- ARRAY_TEST_INSPECT("(U8) {1 + 1, 2 + 2, 3 + 3}", "(U8) {2, 4, 6}");
- ARRAY_TEST_INSPECT("(U8) {255 + 1, 255 + 2, 255 + 3}", "(U8) {0, 1, 2}");
- ARRAY_TEST_INSPECT("(U16) {255 + 1, 255 + 2, 255 + 3}", "(U16) {256, 257, 258}");
- ARRAY_TEST_INSPECT("(U16) {65535 + 1, 65535 + 2, 65535 + 3}", "(U16) {0, 1, 2}");
- ARRAY_TEST_INSPECT("(U32) {65535 + 1, 65535 + 2, 65535 + 3}", "(U32) {65536, 65537, 65538}");
- ARRAY_TEST_INSPECT("(U32) {4294967295 + 1, 4294967295 + 2, 4294967295 + 3}", "(U32) {0, 1, 2}");
- ARRAY_TEST_INSPECT("(U64) {4294967295 + 1, 4294967295 + 2, 4294967295 + 3}", "(U64) {4294967296, 4294967297, 4294967298}");
- ARRAY_TEST_INSPECT("(U64) {18446744073709551615 + 1, 18446744073709551615 + 2, 18446744073709551615 + 3}", "(U64) {0, 1, 2}");
- ARRAY_TEST_INSPECT("(Integer) {18446744073709551615 + 1, 18446744073709551615 + 2, 18446744073709551615 + 3}", "(Integer) {18446744073709551616, 18446744073709551617, 18446744073709551618}");
+ ARRAY_TEST_INSPECT("(U8[]) {0}",
+ "(U8[]) {0}");
+ ARRAY_TEST_INSPECT("(U8[]) {0, 0}",
+ "(U8[]) {0, 0}");
+ ARRAY_TEST_INSPECT("(U8[]) {0, 0, 0}",
+ "(U8[]) {0, 0, 0}");
+ ARRAY_TEST_INSPECT("(U8[]) {{0}, {0}}",
+ "(U8[]) {{0}, {0}}");
+ ARRAY_TEST_INSPECT("(U8[]) {{0, 0}, {0, 0}}",
+ "(U8[]) {{0, 0}, {0, 0}}");
+ ARRAY_TEST_INSPECT("(U8[]) {{0, 0}, {0, 0}, {0, 0}}",
+ "(U8[]) {{0, 0}, {0, 0}, {0, 0}}");
+ ARRAY_TEST_INSPECT("(U8[]) {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}}",
+ "(U8[]) {{{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}}");
+ ARRAY_TEST_INSPECT("(U8[]) {1, 2, 3}",
+ "(U8[]) {1, 2, 3}");
+ ARRAY_TEST_INSPECT("(U8[]) {1 + 1, 2 + 2, 3 + 3}",
+ "(U8[]) {2, 4, 6}");
+ ARRAY_TEST_INSPECT("(U8[]) {255 + 1, 255 + 2, 255 + 3}",
+ "(U8[]) {0, 1, 2}");
+ ARRAY_TEST_INSPECT("(U16[]) {255 + 1, 255 + 2, 255 + 3}",
+ "(U16[]) {256, 257, 258}");
+ ARRAY_TEST_INSPECT("(U16[]) {65535 + 1, 65535 + 2, 65535 + 3}",
+ "(U16[]) {0, 1, 2}");
+ ARRAY_TEST_INSPECT("(U32[]) {65535 + 1, 65535 + 2, 65535 + 3}",
+ "(U32[]) {65536, 65537, 65538}");
+ ARRAY_TEST_INSPECT("(U32[]) {4294967295 + 1, 4294967295 + 2, 4294967295 + 3}",
+ "(U32[]) {0, 1, 2}");
+ ARRAY_TEST_INSPECT("(U64[]) {4294967295 + 1, 4294967295 + 2, 4294967295 + 3}",
+ "(U64[]) {4294967296, 4294967297, 4294967298}");
+ ARRAY_TEST_INSPECT("(U64[]) {18446744073709551615 + 1, 18446744073709551615 + 2, 18446744073709551615 + 3}",
+ "(U64[]) {0, 1, 2}");
+ ARRAY_TEST_INSPECT("(Integer[]) {18446744073709551615 + 1, 18446744073709551615 + 2, 18446744073709551615 + 3}",
+ "(Integer[]) {18446744073709551616, 18446744073709551617, 18446744073709551618}");
}
TEST_CASE_END(array_inspect)
diff --git a/test/buf_inspect_test.c b/test/buf_inspect_test.c
index 5eb013e..4d5aad9 100644
--- a/test/buf_inspect_test.c
+++ b/test/buf_inspect_test.c
@@ -201,11 +201,12 @@ void buf_inspect_test (void)
TEST_CASE(buf_inspect_array)
{
- BUF_INSPECT_TEST_ARRAY("(U8){0}", "(U8) {0}");
- BUF_INSPECT_TEST_ARRAY("(U8){{0, 1}, {2, 3}}",
- "(U8) {{0, 1}, {2, 3}}");
- BUF_INSPECT_TEST_ARRAY("(U8) { { { 0 , 1 } , {2 , 3 } } , { { 4 , 5 } , { 6 , 7 } } }",
- "(U8) {{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}");
+ BUF_INSPECT_TEST_ARRAY("(U8[]){0}",
+ "(U8[]) {0}");
+ BUF_INSPECT_TEST_ARRAY("(U8[]){{0, 1}, {2, 3}}",
+ "(U8[]) {{0, 1}, {2, 3}}");
+ BUF_INSPECT_TEST_ARRAY("(U8[]) { { { 0 , 1 } , {2 , 3 } } , { { 4 , 5 } , { 6 , 7 } } }",
+ "(U8[]) {{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}");
}
TEST_CASE_END(buf_inspect_array)
diff --git a/test/buf_parse_test.c b/test/buf_parse_test.c
index 9546e10..358b26f 100644
--- a/test/buf_parse_test.c
+++ b/test/buf_parse_test.c
@@ -693,11 +693,11 @@ void buf_parse_test (void)
TEST_CASE(buf_parse_array)
{
- BUF_PARSE_TEST_ARRAY("(U8){0}");
- BUF_PARSE_TEST_ARRAY("(U8) {0}");
- BUF_PARSE_TEST_ARRAY("(U8) {{0}, {0}}");
- BUF_PARSE_TEST_ARRAY("(U8) {{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}");
- BUF_PARSE_TEST_ARRAY("(U8){ { 0 },{ 0 } }");
+ BUF_PARSE_TEST_ARRAY("(U8[]){0}");
+ BUF_PARSE_TEST_ARRAY("(U8[]) {0}");
+ BUF_PARSE_TEST_ARRAY("(U8[]) {{0}, {0}}");
+ BUF_PARSE_TEST_ARRAY("(U8[]) {{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}");
+ BUF_PARSE_TEST_ARRAY("(U8[]){ { 0 },{ 0 } }");
}
TEST_CASE_END(buf_parse_array)