Commit 9523ec9d304c28ff45ea3295f17c998b1395cc4d

Thomas de Grivel 2023-09-11T11:36:58

buf_inspect_call_brackets

diff --git a/lib/c3/0.1/c3.facts b/lib/c3/0.1/c3.facts
index 83dfe9e..e549515 100644
--- a/lib/c3/0.1/c3.facts
+++ b/lib/c3/0.1/c3.facts
@@ -14,6 +14,7 @@ add {C3, :symbol, C3.==}
 add {C3, :symbol, C3.>=}
 add {C3, :symbol, C3.>}
 add {C3, :symbol, C3._"()"}
+add {C3, :symbol, C3._"[]"}
 add {C3, :symbol, C3.break}
 add {C3, :symbol, C3.first}
 add {C3, :symbol, C3.xor}
@@ -75,6 +76,8 @@ add {C3.!, :is_a, :operator}
 replace {C3._"()", :arity, 1}
 replace {C3._"()", :cfn, cfn :tag "tag_paren" (:tag, :&result)}
 add {C3._"()", :is_a, :operator}
+replace {C3._"[]", :arity, 2}
+replace {C3._"[]", :cfn, cfn :tag "tag_brackets" (:tag, :tag, :&result)}
 replace {C3.&&, :arity, 2}
 replace {C3.&&, :cfn, cfn :bool "tag_and" (:tag, :tag)}
 add {C3.&&, :is_a, :operator}
diff --git a/libc3/array.c b/libc3/array.c
index 4bab9d0..66d3dd5 100644
--- a/libc3/array.c
+++ b/libc3/array.c
@@ -64,13 +64,18 @@ void * array_data (const s_array *a, const uw *address)
   assert(a);
   assert(address);
   while (i < a->dimension) {
+    if (address[i] >= a->dimensions[i].count) {
+      errx(1, "array address overflow");
+      return NULL;
+    }
     offset += address[i] * a->dimensions[i].item_size;
     i++;
   }
+  assert(offset < a->size);
   return (s8 *) a->data + offset;
 }
 
-s_tag * array_data_tag (s_tag *a, s_tag *address, s_tag *dest)
+s_tag * array_data_tag (s_tag *a, const s_tag *address, s_tag *dest)
 {
   void *a_data;
   void *dest_data;
diff --git a/libc3/array.h b/libc3/array.h
index b36ffe7..e68b09b 100644
--- a/libc3/array.h
+++ b/libc3/array.h
@@ -21,6 +21,6 @@ s_array * array_init (s_array *a, e_tag_type type, uw dimension,
                       const uw *dimensions);
 s_array * array_init_1 (s_array *a, s8 *p);
 void *    array_data (const s_array *a, const uw *address);
-s_tag *   array_data_tag (s_tag *a, s_tag *address, s_tag *dest);
+s_tag *   array_data_tag (s_tag *a, const s_tag *address, s_tag *dest);
 
 #endif /* ARRAY_H */
diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index ff3995b..d848c31 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "../libtommath/tommath.h"
+#include "array.h"
 #include "buf.h"
 #include "buf_inspect.h"
 #include "buf_save.h"
@@ -243,6 +244,8 @@ sw buf_inspect_call (s_buf *buf, const s_call *call)
   s8 op_precedence;
   sw r;
   sw result = 0;
+  if (call->ident.sym == sym_1("[]"))
+    return buf_inspect_call_brackets(buf, call);
   if (operator_is_unary(&call->ident))
     return buf_inspect_call_op_unary(buf, call);
   if ((op_precedence = operator_precedence(&call->ident)) > 0)
@@ -296,6 +299,43 @@ sw buf_inspect_call_args_size (const s_list *args)
   return result;
 }
 
+sw buf_inspect_call_brackets (s_buf *buf, const s_call *call)
+{
+  s_array *address;
+  s_tag *array;
+  uw i = 0;
+  s_list *next;
+  sw r;
+  sw result = 0;
+  assert(buf);
+  assert(call);
+  assert(call->arguments);
+  next = list_next(call->arguments);
+  assert(next);
+  assert(! list_next(next));
+  assert(next->tag.type == TAG_ARRAY);
+  address = &next->tag.data.array;
+  assert(address->dimension == 1);
+  array = &call->arguments->tag;
+  if ((r = buf_inspect_tag(buf, array)) < 0)
+    return r;
+  result += r;
+  while (i < address->dimensions[0].count) {
+    if ((r = buf_write_1(buf, "[")) < 0)
+      return r;
+    result += r;
+    if ((r = buf_inspect_uw(buf, ((uw *) address->data)
+                            + i)) < 0)
+      return r;
+    result += r;
+    if ((r = buf_write_1(buf, "]")) < 0)
+      return r;
+    result += r;
+    i++;
+  }
+  return result;
+}
+
 sw buf_inspect_call_op (s_buf *buf, const s_call *call, s8 op_precedence)
 {
   s_tag *left;
diff --git a/libc3/buf_inspect.h b/libc3/buf_inspect.h
index c2115ab..935c9a1 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -55,6 +55,7 @@ sw buf_inspect_bool (s_buf *buf, const bool *b);
 sw buf_inspect_bool_size (const bool *b);
 sw buf_inspect_call (s_buf *buf, const s_call *call);
 sw buf_inspect_call_args (s_buf *buf, const s_list *args);
+sw buf_inspect_call_brackets (s_buf *buf, const s_call *call);
 sw buf_inspect_call_op (s_buf *buf, const s_call *call,
                         s8 op_precedence);
 sw buf_inspect_call_op_size (const s_call *call, s8 op_precedence);
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 3b7068c..5964623 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -437,7 +437,7 @@ sw buf_parse_brackets (s_buf *buf, s_call *dest)
   assert(dest);
   buf_save_init(buf, &save);
   call_init(&tmp);
-  ident_init(&tmp.ident, sym_1("Array"), sym_1("data"));
+  ident_init(&tmp.ident, NULL, sym_1("[]"));
   tmp.arguments = list_new(NULL, list_new(NULL, NULL));
   arg_dimensions = &(list_next(tmp.arguments)->tag);
   if ((r = buf_parse_tag_primary(buf, &tmp.arguments->tag)) <= 0)
diff --git a/libc3/tag.c b/libc3/tag.c
index f0bcffb..c1210b5 100644
--- a/libc3/tag.c
+++ b/libc3/tag.c
@@ -1382,6 +1382,27 @@ void tag_clean (s_tag *tag)
   }
 }
 
+s_tag * tag_brackets (s_tag *tag, const s_tag *address,
+                      s_tag *dest)
+{
+  assert(tag);
+  assert(address);
+  assert(dest);
+  switch (tag->type) {
+  case TAG_ARRAY:
+    switch (address->type) {
+    case TAG_ARRAY:
+      return array_data_tag(tag, address, dest);
+    default:
+      break;
+    }
+  default:
+    break;
+  }
+  warnx("tag_brackets: invalid arguments");
+  return NULL;
+}
+
 s_tag * tag_copy (const s_tag *src, s_tag *dest)
 {
   assert(src);
diff --git a/libc3/tag.h b/libc3/tag.h
index d8d65d7..2aafb86 100644
--- a/libc3/tag.h
+++ b/libc3/tag.h
@@ -94,6 +94,8 @@ s_tag * tag_new_var ();
 void tag_delete (s_tag *tag);
 
 /* Observers */
+s_tag *            tag_brackets (s_tag *tag, const s_tag *address,
+                                 s_tag *dest);
 s_tag *            tag_equal (const s_tag *a, const s_tag *b,
                               s_tag *dest);
 u64                tag_hash_u64 (const s_tag *tag);
diff --git a/test/ic3/array.in b/test/ic3/array.in
index 2290442..5ffa445 100644
--- a/test/ic3/array.in
+++ b/test/ic3/array.in
@@ -1,9 +1,5 @@
 (u8) {0, 1}
-Array.data((u8) {0, 1}, (uw) {0})
-Array.data((u8) {0, 1}, (uw) {1})
 a = (u8) {0, 1}
-Array.data(a, (uw) {0})
-Array.data(a, (uw) {1})
 quote a[0]
 quote a[1]
 a[0]
@@ -12,10 +8,10 @@ a[1]
       {2, 3}}
 b = (u8) {{0, 1},
           {2, 3}}
-Array.data(b, (uw) {0, 0})
-Array.data(b, (uw) {0, 1})
-Array.data(b, (uw) {1, 0})
-Array.data(b, (uw) {1, 1})
+quote b[0][0]
+quote b[0][1]
+quote b[1][0]
+quote b[1][1]
 b[0][0]
 b[0][1]
 b[1][0]
@@ -24,14 +20,14 @@ c = (u8) {{{0, 1},
            {2, 3}},
           {{4, 5},
            {6, 7}}}
-Array.data(c, (uw) {0, 0, 0})
-Array.data(c, (uw) {0, 0, 1})
-Array.data(c, (uw) {0, 1, 0})
-Array.data(c, (uw) {0, 1, 1})
-Array.data(c, (uw) {1, 0, 0})
-Array.data(c, (uw) {1, 0, 1})
-Array.data(c, (uw) {1, 1, 0})
-Array.data(c, (uw) {1, 1, 1})
+quote c[0][0][0]
+quote c[0][0][1]
+quote c[0][1][0]
+quote c[0][1][1]
+quote c[1][0][0]
+quote c[1][0][1]
+quote c[1][1][0]
+quote c[1][1][1]
 c[0][0][0]
 c[0][0][1]
 c[0][1][0]
@@ -48,22 +44,22 @@ d = (u8) {{{{0, 1},
             {10, 11}},
            {{12, 13},
             {14, 15}}}}
-Array.data(d, (uw) {0, 0, 0, 0})
-Array.data(d, (uw) {0, 0, 0, 1})
-Array.data(d, (uw) {0, 0, 1, 0})
-Array.data(d, (uw) {0, 0, 1, 1})
-Array.data(d, (uw) {0, 1, 0, 0})
-Array.data(d, (uw) {0, 1, 0, 1})
-Array.data(d, (uw) {0, 1, 1, 0})
-Array.data(d, (uw) {0, 1, 1, 1})
-Array.data(d, (uw) {1, 0, 0, 0})
-Array.data(d, (uw) {1, 0, 0, 1})
-Array.data(d, (uw) {1, 0, 1, 0})
-Array.data(d, (uw) {1, 0, 1, 1})
-Array.data(d, (uw) {1, 1, 0, 0})
-Array.data(d, (uw) {1, 1, 0, 1})
-Array.data(d, (uw) {1, 1, 1, 0})
-Array.data(d, (uw) {1, 1, 1, 1})
+quote d[0][0][0][0]
+quote d[0][0][0][1]
+quote d[0][0][1][0]
+quote d[0][0][1][1]
+quote d[0][1][0][0]
+quote d[0][1][0][1]
+quote d[0][1][1][0]
+quote d[0][1][1][1]
+quote d[1][0][0][0]
+quote d[1][0][0][1]
+quote d[1][0][1][0]
+quote d[1][0][1][1]
+quote d[1][1][0][0]
+quote d[1][1][0][1]
+quote d[1][1][1][0]
+quote d[1][1][1][1]
 d[0][0][0][0]
 d[0][0][0][1]
 d[0][0][1][0]
diff --git a/test/ic3/array.out.expected b/test/ic3/array.out.expected
index d45f1e9..45f30e2 100644
--- a/test/ic3/array.out.expected
+++ b/test/ic3/array.out.expected
@@ -1,32 +1,28 @@
 (u8) {0, 1}
-0
-1
 (u8) {0, 1}
-0
-1
-Array.data(a, (uw) {0})
-Array.data(a, (uw) {1})
+a[0]
+a[1]
 0
 1
 (u8) {{0, 1}, {2, 3}}
 (u8) {{0, 1}, {2, 3}}
-0
-1
-2
-3
+b[0][0]
+b[0][1]
+b[1][0]
+b[1][1]
 0
 1
 2
 3
 (u8) {{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}
-0
-1
-2
-3
-4
-5
-6
-7
+c[0][0][0]
+c[0][0][1]
+c[0][1][0]
+c[0][1][1]
+c[1][0][0]
+c[1][0][1]
+c[1][1][0]
+c[1][1][1]
 0
 1
 2
@@ -36,22 +32,22 @@ Array.data(a, (uw) {1})
 6
 7
 (u8) {{{{0, 1}, {2, 3}}, {{4, 5}, {6, 7}}}, {{{8, 9}, {10, 11}}, {{12, 13}, {14, 15}}}}
-0
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-15
+d[0][0][0][0]
+d[0][0][0][1]
+d[0][0][1][0]
+d[0][0][1][1]
+d[0][1][0][0]
+d[0][1][0][1]
+d[0][1][1][0]
+d[0][1][1][1]
+d[1][0][0][0]
+d[1][0][0][1]
+d[1][0][1][0]
+d[1][0][1][1]
+d[1][1][0][0]
+d[1][1][0][1]
+d[1][1][1][0]
+d[1][1][1][1]
 0
 1
 2