Commit c237b4ceb63948b0e6742eb3692a78a30770f67b

Thomas de Grivel 2023-12-21T02:50:45

wip asan

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) {}