Commit 7f453dbd209a99bc92daebb8a3590fbd126fa926

Thomas de Grivel 2024-07-07T22:57:42

access: buf_parse, buf_inspect, more tests

diff --git a/libc3/buf_inspect.c b/libc3/buf_inspect.c
index 82439f5..eef9bc1 100644
--- a/libc3/buf_inspect.c
+++ b/libc3/buf_inspect.c
@@ -359,6 +359,9 @@ sw buf_inspect_call (s_buf *buf, const s_call *call)
   sw r;
   sw result = 0;
   if (call->ident.module == &g_sym_C3 &&
+      call->ident.sym == &g_sym_access)
+    return buf_inspect_call_access(buf, call);
+  if (call->ident.module == &g_sym_C3 &&
       call->ident.sym == &g_sym_if_then_else)
     return buf_inspect_call_if_then_else(buf, call);
   if (! operator_find(&call->ident, &op))
@@ -386,6 +389,28 @@ sw buf_inspect_call (s_buf *buf, const s_call *call)
   return result;
 }
 
+sw buf_inspect_call_access (s_buf *buf, const s_call *call)
+{
+  s_list *args;
+  sw r;
+  sw result = 0;
+  s_tag *tag_sym;
+  assert(buf);
+  assert(call);
+  args = call->arguments;
+  tag_sym = &args->next.data.list->tag;
+  if ((r = buf_inspect_tag(buf, &args->tag)) < 0)
+    return r;
+  result += r;
+  if ((r = buf_write_1(buf, ".")) < 0)
+    return r;
+  result += r;
+  if ((r = buf_inspect_ident_sym(buf, tag_sym->data.sym)) < 0)
+    return r;
+  result += r;
+  return result;
+}
+
 sw buf_inspect_call_args (s_buf *buf, const s_list *args)
 {
   sw r;
@@ -1474,64 +1499,69 @@ sw buf_inspect_ident (s_buf *buf, const s_ident *ident)
       return r;
     result += r;
   }
-  if (ident->sym->str.size == 0) {
-    if ((r = buf_write_1(buf, "_\"\"")) < 0)
-      return r;
-    result += r;
-    return result;
-  }
-  if (ident_has_reserved_characters(ident)) {
-    if ((r = buf_inspect_ident_reserved(buf, ident)) < 0)
+  if ((r = buf_inspect_ident_sym(buf, ident->sym)) < 0)
+    return r;
+  result += r;
+  return result;
+}
+
+sw buf_inspect_ident_size (const s_ident *ident)
+{
+  sw r;
+  sw result = 0;
+  assert(ident);
+  if (ident->module) {
+    if ((r = buf_inspect_sym_size(&ident->module)) < 0)
       return r;
     result += r;
-    return result;
+    result += strlen(".");
   }
-  if ((r = buf_write_str(buf, &ident->sym->str)) < 0)
+  if ((r = buf_inspect_ident_sym_size(ident->sym)) < 0)
     return r;
   result += r;
   return result;
 }
 
-sw buf_inspect_ident_reserved (s_buf *buf, const s_ident *x)
+sw buf_inspect_ident_sym (s_buf *buf, const s_sym *sym)
+{
+  if (sym->str.size == 0)
+    return buf_write_1(buf, "_\"\"");
+  if (sym_has_ident_reserved_characters(sym))
+    return buf_inspect_ident_sym_reserved(buf, sym);
+  return buf_write_str(buf, &sym->str);
+}
+
+sw buf_inspect_ident_sym_reserved (s_buf *buf, const s_sym *sym)
 {
   sw size;
   assert(buf);
-  assert(x);
-  size = buf_inspect_ident_reserved_size(x);
+  assert(sym);
+  size = buf_inspect_ident_sym_reserved_size(sym);
   if (buf->wpos + size > buf->size) {
     assert(! "buffer overflow");
     return -1;
   }
   buf_write_1(buf, "_");
-  buf_inspect_str_reserved(buf, &x->sym->str);
+  buf_inspect_str(buf, &sym->str);
   return size;
 }
 
-sw buf_inspect_ident_reserved_size (const s_ident *x)
+sw buf_inspect_ident_sym_reserved_size (const s_sym *sym)
 {
   sw size;
-  assert(x);
+  assert(sym);
   size = strlen("_");
-  size += buf_inspect_str_reserved_size(&x->sym->str);
+  size += buf_inspect_str_size(&sym->str);
   return size;
 }
 
-sw buf_inspect_ident_size (const s_ident *ident)
+sw buf_inspect_ident_sym_size (const s_sym *sym)
 {
-  sw r;
-  sw result = 0;
-  assert(ident);
-  if (ident->module) {
-    if ((r = buf_inspect_sym_size(&ident->module)) < 0)
-      return r;
-    result += r;
-    result += strlen(".");
-  }
-  if (ident->sym->str.size == 0)
-    return result + strlen("_\"\"");
-  if (ident_has_reserved_characters(ident))
-    return result + buf_inspect_ident_reserved_size(ident);
-  return result + ident->sym->str.size;
+  if (sym->str.size == 0)
+    return strlen("_\"\"");
+  if (sym_has_ident_reserved_characters(sym))
+    return buf_inspect_ident_sym_reserved_size(sym);
+  return sym->str.size;
 }
 
 sw buf_inspect_integer (s_buf *buf, const s_integer *x)
diff --git a/libc3/buf_inspect.h b/libc3/buf_inspect.h
index 4a9b36c..5755cdb 100644
--- a/libc3/buf_inspect.h
+++ b/libc3/buf_inspect.h
@@ -62,6 +62,7 @@ sw buf_inspect_block_size (const s_block *b);
 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_access (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_if_then_else (s_buf *buf, const s_call *call);
@@ -104,9 +105,11 @@ sw buf_inspect_fn_pattern (s_buf *buf, const s_list *pattern);
 sw buf_inspect_fn_pattern_size (const s_list *pattern);
 sw buf_inspect_fn_size (const s_fn *fn);
 sw buf_inspect_ident (s_buf *buf, const s_ident *ident);
-sw buf_inspect_ident_reserved (s_buf *buf, const s_ident *ident);
-sw buf_inspect_ident_reserved_size (const s_ident *ident);
 sw buf_inspect_ident_size (const s_ident *ident);
+sw buf_inspect_ident_sym (s_buf *buf, const s_sym *sym);
+sw buf_inspect_ident_sym_reserved (s_buf *buf, const s_sym *sym);
+sw buf_inspect_ident_sym_reserved_size (const s_sym *sym);
+sw buf_inspect_ident_sym_size (const s_sym *sym);
 sw buf_inspect_integer (s_buf *buf, const s_integer *x);
 sw buf_inspect_integer_size (const s_integer *x);
 sw buf_inspect_list (s_buf *buf, const s_list * const *list);
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index f1f1a52..7c3f502 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -769,6 +769,7 @@ sw buf_parse_call_access (s_buf *buf, s_call *dest)
   if ((r = buf_read_1(buf, ".")) <= 0)
     goto restore;
   result += r;
+  tag_sym->type = TAG_SYM;
   r = buf_parse_ident_sym(buf, &tag_sym->data.sym);
   if (r <= 0)
     goto restore;
diff --git a/libc3/ident.c b/libc3/ident.c
index 74c1d90..3538944 100644
--- a/libc3/ident.c
+++ b/libc3/ident.c
@@ -60,25 +60,6 @@ s_tag * ident_get (const s_ident *ident, s_tag *dest)
   return env_ident_get(&g_c3_env, ident, dest);
 }
 
-bool ident_has_reserved_characters (const s_ident *ident)
-{
-  character c;
-  sw r;
-  s_str stra;
-  str_init(&stra, NULL, ident->sym->str.size, ident->sym->str.ptr.p);
-  if ((r = str_read_character_utf8(&stra, &c)) > 0) {
-    if (ident_first_character_is_reserved(c))
-      return true;
-    while ((r = str_read_character_utf8(&stra, &c)) > 0) {
-      if (ident_character_is_reserved(c))
-        return true;
-    }
-  }
-  if (r < 0)
-    return true;
-  return false;
-}
-
 s_ident * ident_init (s_ident *ident, const s_sym *module,
                       const s_sym *sym)
 {
diff --git a/libc3/ident.h b/libc3/ident.h
index 2aecf63..135d799 100644
--- a/libc3/ident.h
+++ b/libc3/ident.h
@@ -34,7 +34,6 @@ s_ident * ident_resolve_module (const s_ident *ident, s_ident *dest);
 bool    ident_character_is_reserved (character c);
 bool    ident_first_character_is_reserved (character c);
 s_tag * ident_get (const s_ident *ident, s_tag *dest);
-bool    ident_has_reserved_characters (const s_ident *ident);
 s_str * ident_inspect (const s_ident *ident, s_str *dest);
 bool *  ident_is_special_operator (const s_ident *ident, bool *dest);
 bool    ident_to_tag_type (const s_ident *ident, e_tag_type *dest);
diff --git a/libc3/sym.c b/libc3/sym.c
index 159199a..490603a 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -16,6 +16,7 @@
 #include "buf_inspect.h"
 #include "character.h"
 #include "compare.h"
+#include "ident.h"
 #include "str.h"
 #include "struct_type.h"
 #include "sym.h"
@@ -216,6 +217,25 @@ const s_sym * sym_find (const s_str *str)
   return NULL;
 }
 
+bool sym_has_ident_reserved_characters (const s_sym *sym)
+{
+  character c;
+  sw r;
+  s_str stra;
+  str_init(&stra, NULL, sym->str.size, sym->str.ptr.p);
+  if ((r = str_read_character_utf8(&stra, &c)) > 0) {
+    if (ident_first_character_is_reserved(c))
+      return true;
+    while ((r = str_read_character_utf8(&stra, &c)) > 0) {
+      if (ident_character_is_reserved(c))
+        return true;
+    }
+  }
+  if (r < 0)
+    return true;
+  return false;
+}
+
 bool sym_has_reserved_characters (const s_sym *sym)
 {
   character c;
diff --git a/libc3/sym.h b/libc3/sym.h
index 512d8e4..b12beee 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -130,6 +130,7 @@ const s_sym * sym_new (const s_str *src);
 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_ident_reserved_characters (const s_sym *sym);
 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);
diff --git a/test/ic3/access.in b/test/ic3/access.in
index 38559b1..282fc78 100644
--- a/test/ic3/access.in
+++ b/test/ic3/access.in
@@ -4,3 +4,19 @@ quote %{a: 1, b: 2, c: 3}.b
 %{a: 1, b: 2, c: 3}.b
 quote %{a: 1, b: 2, c: 3}.c
 %{a: 1, b: 2, c: 3}.c
+quote %{a: %{b: %{c: 1}}}.a
+%{a: %{b: %{c: 1}}}.a
+quote %{a: %{b: %{c: 1}}}.a.b
+%{a: %{b: %{c: 1}}}.a.b
+quote %{a: %{b: %{c: 1}}}.a.b.c
+%{a: %{b: %{c: 1}}}.a.b.c
+quote map = %{a: %{b: %{c: 1}}}
+map
+quote map.a
+map.a
+quote map.a.b
+mab.a.b
+quote map.a.b.c
+map.a.b.c
+quote map.a.b.c + map.a.b.c
+map.a.b.c + map.a.b.c
diff --git a/test/ic3/access.out.expected b/test/ic3/access.out.expected
index b9271a5..442fa6f 100644
--- a/test/ic3/access.out.expected
+++ b/test/ic3/access.out.expected
@@ -4,3 +4,19 @@
 2
 %{a: 1, b: 2, c: 3}.c
 3
+%{a: %{b: %{c: 1}}}.a
+%{b: %{c: 1}}
+%{a: %{b: %{c: 1}}}.a.b
+%{c: 1}
+%{a: %{b: %{c: 1}}}.a.b.c
+1
+map = %{a: %{b: %{c: 1}}}
+%{a: %{b: %{c: 1}}}
+map.a
+%{b: %{c: 1}}
+map.a.b
+%{c: 1}
+map.a.b.c
+1
+map.a.b.c + map.a.b.c
+2