diff --git a/Makefile b/Makefile
index 37dfbfd..4ecbe6c 100644
--- a/Makefile
+++ b/Makefile
@@ -141,6 +141,12 @@ gdb_test:
gen:
${MAKE} -C libc3 gen
+ic3:
+ ${MAKE} -C ic3 build
+
+ic3_debug:
+ ${MAKE} -C ic3 debug
+
ic3_gcovr:
${MAKE} clean_cov
${MAKE} ic3_test_cov
diff --git a/libc3/array.c b/libc3/array.c
index ebafd83..b70d9c9 100644
--- a/libc3/array.c
+++ b/libc3/array.c
@@ -50,6 +50,19 @@
#include "uw.h"
#include "var.h"
+s_array * array_allocate (s_array *a)
+{
+ assert(a);
+ a->data_free = calloc(1, a->size);
+ if (! a->data_free) {
+ err_puts("array_allocate: failed to allocate memory");
+ assert(! "array_allocate: failed to allocate memory");
+ return NULL;
+ }
+ a->data = a->data_free;
+ return a;
+}
+
void array_clean (s_array *a)
{
f_clean clean;
diff --git a/libc3/array.h b/libc3/array.h
index f6f8fab..3a8f5e2 100644
--- a/libc3/array.h
+++ b/libc3/array.h
@@ -30,6 +30,7 @@ s_tag * array_data_tag (const s_tag *a, const s_tag *address,
s_tag *dest);
/* Operators */
+s_array * array_allocate (s_array *a);
s_array * array_data_set (s_array *a, const uw *address,
const void *data);
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 60cbde4..ec5047a 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -81,25 +81,38 @@ sw buf_parse_array (s_buf *buf, s_array *dest)
sw buf_parse_array_data (s_buf *buf, s_array *dest)
{
- uw *address;
- uw i = 0;
- sw r;
+ uw *address = NULL;
+ uw i;
+ sw r = 0;
+ sw result = 0;
s_tag *tag;
s_array tmp;
assert(buf);
assert(dest);
+ if (! dest->dimension) {
+ if ((r = buf_read_1(buf, "{")) <= 0)
+ return r;
+ result += r;
+ if ((r = buf_ignore_spaces(buf)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_read_1(buf, "}")) <= 0)
+ return r;
+ result += r;
+ return result;
+ }
tmp = *dest;
if (! (address = calloc(tmp.dimension, sizeof(sw)))) {
err_puts("buf_parse_array_data: out of memory: address");
return -1;
}
tmp.count = 1;
+ i = 0;
while (i < tmp.dimension) {
tmp.count *= tmp.dimensions[i].count;
i++;
}
tmp.size = tmp.dimensions[0].count * tmp.dimensions[0].item_size;
- assert(tmp.count);
if (! (tmp.tags = calloc(tmp.count, sizeof(s_tag)))) {
free(address);
err_puts("buf_parse_array_data: out of memory: tags");
@@ -131,7 +144,6 @@ sw buf_parse_array_data_rec (s_buf *buf, s_array *dest, uw *address,
s_array tmp;
assert(buf);
assert(dest);
- assert(address);
tmp = *dest;
buf_save_init(buf, &save);
if ((r = buf_read_1(buf, "{")) <= 0) {
@@ -144,48 +156,50 @@ sw buf_parse_array_data_rec (s_buf *buf, s_array *dest, uw *address,
goto restore;
}
result += r;
- address[dimension] = 0;
- while (1) {
- if (dimension == tmp.dimension - 1) {
- if ((r = buf_parse_tag(buf, *tag)) < 0) {
- err_puts("buf_parse_array_data_rec: parse");
- goto clean;
+ if (address) {
+ address[dimension] = 0;
+ while (1) {
+ if (dimension == tmp.dimension - 1) {
+ if ((r = buf_parse_tag(buf, *tag)) < 0) {
+ err_puts("buf_parse_array_data_rec: parse");
+ goto clean;
+ }
+ result += r;
+ (*tag)++;
+ }
+ else {
+ if ((r = buf_parse_array_data_rec(buf, &tmp, address, tag,
+ dimension + 1)) <= 0) {
+ err_puts("buf_parse_array_data_rec: buf_parse_array_data_rec");
+ goto restore;
+ }
+ result += r;
+ }
+ address[dimension]++;
+ if ((r = buf_ignore_spaces(buf)) < 0) {
+ err_puts("buf_parse_array_data_rec: 2");
+ goto restore;
}
result += r;
- (*tag)++;
- }
- else {
- if ((r = buf_parse_array_data_rec(buf, &tmp, address, tag,
- dimension + 1)) <= 0) {
- err_puts("buf_parse_array_data_rec: buf_parse_array_data_rec");
+ if ((r = buf_read_1(buf, ",")) < 0) {
+ err_puts("buf_parse_array_data_rec: 3");
+ goto restore;
+ }
+ result += r;
+ if (! r)
+ break;
+ if ((r = buf_ignore_spaces(buf)) < 0) {
+ err_puts("buf_parse_array_data_rec: 4");
goto restore;
}
result += r;
}
- address[dimension]++;
- if ((r = buf_ignore_spaces(buf)) < 0) {
- err_puts("buf_parse_array_data_rec: 2");
- goto restore;
- }
- result += r;
- if ((r = buf_read_1(buf, ",")) < 0) {
- err_puts("buf_parse_array_data_rec: 3");
- goto restore;
- }
- result += r;
- if (! r)
- break;
if ((r = buf_ignore_spaces(buf)) < 0) {
err_puts("buf_parse_array_data_rec: 4");
goto restore;
}
result += r;
}
- if ((r = buf_ignore_spaces(buf)) < 0) {
- err_puts("buf_parse_array_data_rec: 4");
- goto restore;
- }
- result += r;
if ((r = buf_read_1(buf, "}")) <= 0) {
err_puts("buf_parse_array_data_rec: }");
goto restore;
@@ -267,7 +281,7 @@ sw buf_parse_array_dimensions (s_buf *buf, s_array *dest)
address = calloc(tmp.dimension, sizeof(sw));
tmp.dimensions[tmp.dimension - 1].item_size = size;
if ((r = buf_parse_array_dimensions_rec(buf, &tmp, address,
- 0)) <= 0) {
+ 0)) < 0) {
err_write_1("buf_parse_array_dimensions:"
" buf_parse_array_dimensions_rec: ");
err_inspect_sw(&r);
@@ -306,12 +320,14 @@ sw buf_parse_array_dimensions_rec (s_buf *buf, s_array *dest,
address[dimension] = 0;
while (1) {
if (dimension == dest->dimension - 1) {
- if ((r = buf_parse_tag(buf, &tag)) <= 0) {
+ if ((r = buf_parse_tag(buf, &tag)) < 0) {
err_puts("buf_parse_array_dimensions_rec: buf_parse_tag");
goto clean;
}
- result += r;
- tag_clean(&tag);
+ if (r) {
+ result += r;
+ tag_clean(&tag);
+ }
}
else {
if ((r = buf_parse_array_dimensions_rec(buf, &tmp, address,
diff --git a/libc3/env.c b/libc3/env.c
index dba0213..236639b 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -109,7 +109,8 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
uw i;
f_init_cast init_cast;
uw item_size;
- s_tag *tag;
+ s_tag *tag;
+ s_tag tag_eval;
s_array tmp = {0};
assert(env);
assert(array);
@@ -125,16 +126,20 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
return false;
}
if (! sym_to_init_cast(tmp.type, &init_cast))
- goto ko;
data = tmp.data;
tag = tmp.tags;
i = 0;
while (i < tmp.count) {
- s_tag tag_eval;
if (! env_eval_tag(env, tag, &tag_eval))
goto ko;
- if (! init_cast(data, &tag_eval))
+ if (! init_cast(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_puts(".");
goto ko;
+ }
tag_clean(&tag_eval);
data += item_size;
tag++;
diff --git a/libc3/hash.c b/libc3/hash.c
index 65a05ca..3fc96be 100644
--- a/libc3/hash.c
+++ b/libc3/hash.c
@@ -88,7 +88,15 @@ void hash_update_array (t_hash *hash, const s_array *a)
sizeof(a->dimensions[i].count));
i++;
}
- hash_update(hash, a->data, a->size);
+ if (a->data)
+ hash_update(hash, a->data, a->size);
+ else if (a->tags) {
+ i = 0;
+ while (i < a->count) {
+ hash_update_tag(hash, a->tags + i);
+ i++;
+ }
+ }
}
void hash_update_bool (t_hash *hash, const bool *x)
diff --git a/libc3/struct.c b/libc3/struct.c
index 73bc16a..e5d3674 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -127,6 +127,7 @@ s_struct * struct_init_cast (s_struct *s, const s_tag *tag)
}
warnx("struct_init_cast: cannot cast %s to Struct",
tag_type_to_string(tag->type));
+ //assert(! "struct_init_cast: cannot cast to Struct");
return NULL;
}
diff --git a/libc3/window/sdl2/gl_object.c b/libc3/window/sdl2/gl_object.c
index a811a81..6a03ee7 100644
--- a/libc3/window/sdl2/gl_object.c
+++ b/libc3/window/sdl2/gl_object.c
@@ -21,8 +21,10 @@ s_gl_object * gl_object_allocate (s_gl_object *object, uw vertex_count,
assert(triangle_count);
if (! array_init(&object->vertex, sym_1("GL.Vertex"), 1,
&vertex_count) ||
+ ! array_allocate(&object->vertex) ||
! array_init(&object->triangle, sym_1("GL.Triangle"), 1,
- &triangle_count))
+ &triangle_count) ||
+ ! array_allocate(&object->triangle))
return NULL;
return object;
}
diff --git a/test/ic3/array.in b/test/ic3/array.in
index 017521d..ff0d302 100644
--- a/test/ic3/array.in
+++ b/test/ic3/array.in
@@ -112,3 +112,5 @@ quote (List) {[1, 2], [3, 4]}
m = (List) {[1, 2], [3, 4]}
m[0]
m[1]
+quote (GL.Vertex) {}
+(GL.Vertex) {}
diff --git a/test/ic3/array.out.expected b/test/ic3/array.out.expected
index 15365e8..738e88a 100644
--- a/test/ic3/array.out.expected
+++ b/test/ic3/array.out.expected
@@ -98,3 +98,5 @@ d[1][1][1][1]
(List) {[1, 2], [3, 4]}
[1, 2]
[3, 4]
+(GL.Vertex) {}
+(GL.Vertex) {}