Commit ae064295eac43df3914067f6ebbc5c4816b9d0d6

Thomas de Grivel 2024-02-20T16:40:46

fix special_operator_arity

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index 73716c2..74aa3f3 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -2490,7 +2490,7 @@ sw buf_parse_quote (s_buf *buf, s_quote *dest)
 sw buf_parse_special_operator (s_buf *buf, s_call *dest)
 {
   s_list **args_last;
-  s_tag arity;
+  u8 arity;
   uw i;
   sw r;
   sw result = 0;
@@ -2506,21 +2506,13 @@ sw buf_parse_special_operator (s_buf *buf, s_call *dest)
     r = 0;
     goto restore;
   }
-  if (! special_operator_arity(&tmp.ident, &arity)) {
+  if (! (arity = special_operator_arity(&tmp.ident))) {
     r = 0;
     goto restore;
   }
-  if (arity.type != TAG_U8 || ! arity.data.u8) {
-    err_write_1("buf_parse_special_operator: ");
-    err_inspect_ident(&tmp.ident);
-    err_write_1("invalid arity: ");
-    err_inspect_tag(&arity);
-    r = -2;
-    goto restore;
-  }
   args_last = &tmp.arguments;
   i = 0;
-  while (i < arity.data.u8) {
+  while (i < arity) {
     if ((r = buf_parse_comments(buf)) < 0)
       goto restore;
     result += r;
diff --git a/libc3/env.c b/libc3/env.c
index f75c89a..fecb083 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -1642,9 +1642,9 @@ void env_push_unwind_protect (s_env *env,
   env->unwind_protect = unwind_protect;
 }
 
-s_tag * env_special_operator_arity (s_env *env, const s_ident *ident,
-                                    s_tag *dest)
+u8 env_special_operator_arity (s_env *env, const s_ident *ident)
 {
+  u8 arity;
   s_facts_cursor cursor;
   s_tag tag_arity;
   s_tag tag_ident;
@@ -1658,16 +1658,24 @@ s_tag * env_special_operator_arity (s_env *env, const s_ident *ident,
   facts_with_tags(&env->facts, &cursor,
                   &tag_ident, &tag_arity, &tag_var);
   if (facts_cursor_next(&cursor)) {
-    tag_init_copy(dest, &tag_var);
+    if (tag_var.type != TAG_U8) {
+      err_write_1("env_special_operator_arity: "
+                  "invalid arity for special operator ");
+      err_inspect_ident(&tag_ident.data.ident);
+      err_write_1("\n");
+      facts_cursor_clean(&cursor);
+      return 0;
+    }
+    arity = tag_var.data.u8;
     facts_cursor_clean(&cursor);
-    return dest;
+    return arity;
   }
   facts_cursor_clean(&cursor);
   err_write_1("env_special_operator_arity: "
               "arity not found for special operator ");
   err_inspect_ident(&tag_ident.data.ident);
   err_write_1("\n");
-  return NULL;
+  return 0;
 }
 
 bool env_struct_type_exists (s_env *env, const s_sym *module)
diff --git a/libc3/env.h b/libc3/env.h
index 456f860..18e2ce0 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -120,9 +120,8 @@ s8            env_operator_precedence (s_env *env, const s_ident *op);
 s_ident *     env_operator_resolve (s_env *env, const s_ident *op,
                                     u8 arity, s_ident *dest);
 const s_sym * env_operator_symbol (s_env *env, const s_ident *op);
-s_tag *       env_special_operator_arity (s_env *env,
-                                          const s_ident *ident,
-                                          s_tag *dest);
+u8            env_special_operator_arity (s_env *env,
+                                          const s_ident *ident);
 bool          env_struct_type_exists (s_env *env,
                                         const s_sym *module);
 const s_struct_type *
diff --git a/libc3/special_operator.c b/libc3/special_operator.c
index 8144b52..e631ff7 100644
--- a/libc3/special_operator.c
+++ b/libc3/special_operator.c
@@ -13,7 +13,7 @@
 #include "env.h"
 #include "operator.h"
 
-s_tag * special_operator_arity (const s_ident *ident, s_tag *dest)
+u8 special_operator_arity (const s_ident *ident)
 {
-  return env_special_operator_arity(&g_c3_env, ident, dest);
+  return env_special_operator_arity(&g_c3_env, ident);
 }
diff --git a/libc3/special_operator.h b/libc3/special_operator.h
index 8fa0e3c..fbdc9f6 100644
--- a/libc3/special_operator.h
+++ b/libc3/special_operator.h
@@ -16,6 +16,6 @@
 #include "types.h"
 
 /* Observers */
-s_tag * special_operator_arity (const s_ident *ident, s_tag *dest);
+u8 special_operator_arity (const s_ident *ident);
 
 #endif /* LIBC3_SPECIAL_OPERATOR_H */