Commit c4ef728e0b3cb50187e635195f514a391064001c

Thomas de Grivel 2024-04-12T10:58:35

wip env_eval_fn

diff --git a/libc3/env.c b/libc3/env.c
index 7a5840c..5f561d0 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -23,6 +23,7 @@
 #include "call.h"
 #include "cfn.h"
 #include "compare.h"
+#include "complex.h"
 #include "data.h"
 #include "env.h"
 #include "error.h"
@@ -419,7 +420,79 @@ bool env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
   assert(env);
   assert(call);
   assert(dest);
-  return env_eval_fn_call(env, call->fn, call->arguments, dest);
+  return env_eval_call_fn_args(env, call->fn, call->arguments, dest);
+}
+
+bool env_eval_call_fn_args (s_env *env, const s_fn *fn,
+                            const s_list *arguments, s_tag *dest)
+{
+  s_list *args = NULL;
+  const s_list *args_final = NULL;
+  s_fn_clause *clause;
+  s_frame frame;
+  s_tag tag;
+  s_list *tmp = NULL;
+  assert(env);
+  assert(fn);
+  assert(dest);
+  clause = fn->clauses;
+  if (arguments) {
+    if (fn->macro || fn->special_operator)
+      args_final = arguments;
+    else {
+      if (! env_eval_call_arguments(env, arguments, &args)) {
+        env->frame = frame_clean(&frame);
+        return false;
+      }
+      args_final = args;
+    }
+    while (clause) {
+      frame_init(&frame, env->frame);
+      env->frame = &frame;
+      if (env_eval_equal_list(env, fn->macro || fn->special_operator,
+                              clause->pattern, args_final, &tmp))
+        break;
+      env->frame = frame_clean(&frame);
+      clause = clause->next_clause;
+    }
+    if (! clause) {
+      err_puts("env_eval_fn_call: no clause matching.\nTried clauses :\n");
+      clause = fn->clauses;
+      while (clause) {
+        err_inspect_fn_pattern(clause->pattern);
+        err_puts("\n");
+        clause = clause->next_clause;
+      }
+      err_puts("\nArguments :\n");
+      err_inspect_fn_pattern(args);
+      err_puts("\n");
+      list_delete_all(args);
+      return false;
+    }
+  }
+  else {
+    frame_init(&frame, env->frame);
+    env->frame = &frame;
+  }
+  if (! env_eval_block(env, &clause->algo, &tag)) {
+    list_delete_all(args);
+    list_delete_all(tmp);
+    env->frame = frame_clean(&frame);
+    return false;
+  }
+  list_delete_all(args);
+  list_delete_all(tmp);
+  env->frame = frame_clean(&frame);
+  if (fn->macro) {
+    if (! env_eval_tag(env, &tag, dest)) {
+      tag_clean(&tag);
+      return false;
+    }
+    tag_clean(&tag);
+  }
+  else
+    *dest = tag;
+  return true;
 }
 
 bool env_eval_call_resolve (s_env *env, s_call *call)
@@ -764,76 +837,56 @@ bool env_eval_equal_tuple (s_env *env, bool macro, const s_tuple *a,
   return true;
 }
 
-bool env_eval_fn_call (s_env *env, const s_fn *fn,
-                       const s_list *arguments, s_tag *dest)
+bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest)
 {
-  s_list *args = NULL;
-  const s_list *args_final = NULL;
-  s_fn_clause *clause;
-  s_frame frame;
-  s_tag tag;
-  s_list *tmp = NULL;
+  uw i;
+  s_fn_clause *src_clause;
+  s_list      *src_pattern;
+  s_fn tmp = {0};
+  s_fn_clause **tmp_clause;
+  s_list      **tmp_pattern;
   assert(env);
   assert(fn);
   assert(dest);
-  clause = fn->clauses;
-  if (arguments) {
-    if (fn->macro || fn->special_operator)
-      args_final = arguments;
-    else {
-      if (! env_eval_call_arguments(env, arguments, &args)) {
-        env->frame = frame_clean(&frame);
-        return false;
-      }
-      args_final = args;
-    }
-    while (clause) {
-      frame_init(&frame, env->frame);
-      env->frame = &frame;
-      if (env_eval_equal_list(env, fn->macro || fn->special_operator,
-                              clause->pattern, args_final, &tmp))
-        break;
-      env->frame = frame_clean(&frame);
-      clause = clause->next_clause;
-    }
-    if (! clause) {
-      err_puts("env_eval_fn_call: no clause matching.\nTried clauses :\n");
-      clause = fn->clauses;
-      while (clause) {
-        err_inspect_fn_pattern(clause->pattern);
-        err_puts("\n");
-        clause = clause->next_clause;
-      }
-      err_puts("\nArguments :\n");
-      err_inspect_fn_pattern(args);
-      err_puts("\n");
-      list_delete_all(args);
-      return false;
+  tmp_clause = &tmp.clauses;
+  src_clause = fn->clauses;
+  while (src_clause) {
+    *tmp_clause = fn_clause_new(NULL);
+    if (! *tmp_clause)
+      goto ko;
+    (*tmp_clause)->arity = src_clause->arity;
+    tmp_pattern = &(*tmp_clause)->pattern;
+    src_pattern = src_clause->pattern;
+    while (src_pattern) {
+      *tmp_pattern = list_new(NULL);
+      if (! *tmp_pattern)
+        goto ko;
+      if (! env_eval_fn_tag(env, &src_pattern->tag,
+                            &(*tmp_pattern)->tag))
+        goto ko;
+      tmp_pattern = &(*tmp_pattern)->next.data.list;
+      src_pattern = list_next(src_pattern);
     }
-  }
-  else {
-    frame_init(&frame, env->frame);
-    env->frame = &frame;
-  }
-  if (! env_eval_block(env, &clause->algo, &tag)) {
-    list_delete_all(args);
-    list_delete_all(tmp);
-    env->frame = frame_clean(&frame);
-    return false;
-  }
-  list_delete_all(args);
-  list_delete_all(tmp);
-  env->frame = frame_clean(&frame);
-  if (fn->macro) {
-    if (! env_eval_tag(env, &tag, dest)) {
-      tag_clean(&tag);
-      return false;
+    if (! block_init(&(*tmp_clause)->algo, src_clause->algo.count))
+      goto ko;
+    i = 0;
+    while (i < src_clause->algo.count) {
+      if (! env_eval_fn_tag(env, src_clause->algo.tag + i,
+                            (*tmp_clause)->algo.tag + i))
+        goto ko;
+      i++;
     }
-    tag_clean(&tag);
+    tmp_clause = &(*tmp_clause)->next_clause;
+    src_clause = src_clause->next_clause;
   }
-  else
-    *dest = tag;
+  tmp.macro = fn->macro;
+  tmp.special_operator = fn->special_operator;
+  dest->type = TAG_FN;
+  dest->data.fn = tmp;
   return true;
+ ko:
+  fn_clean(&tmp);
+  return false;
 }
 
 bool env_eval_ident (s_env *env, const s_ident *ident, s_tag *dest)
@@ -1022,6 +1075,24 @@ bool env_eval_quote_call (s_env *env, const s_call *call, s_tag *dest)
   return false;
 }
 
+bool env_eval_quote_complex (s_env *env, const s_complex *c,
+                             s_tag *dest)
+{
+  s_tag tmp = {0};
+  assert(env);
+  assert(c);
+  assert(dest);
+  tmp.type = TAG_COMPLEX;
+  tmp.data.complex = complex_new();
+  if (! env_eval_quote_tag(env, &c->x, &tmp.data.complex->x) ||
+      ! env_eval_quote_tag(env, &c->y, &tmp.data.complex->y)) {
+    complex_delete(tmp.data.complex);
+    return false;
+  }
+  *dest = tmp;
+  return true;
+}
+
 bool env_eval_quote_list (s_env *env, const s_list *list, s_tag *dest)
 {
   s_list *next;
@@ -1139,6 +1210,8 @@ bool env_eval_quote_tag (s_env *env, const s_tag *tag, s_tag *dest)
     return env_eval_quote_block(env, &tag->data.block, dest);
   case TAG_CALL:
     return env_eval_quote_call(env, &tag->data.call, dest);
+  case TAG_COMPLEX:
+    return env_eval_quote_complex(env, tag->data.complex, dest);
   case TAG_LIST:
     return env_eval_quote_list(env, tag->data.list, dest);
   case TAG_MAP:
@@ -1155,7 +1228,6 @@ bool env_eval_quote_tag (s_env *env, const s_tag *tag, s_tag *dest)
   case TAG_BOOL:
   case TAG_CFN:
   case TAG_CHARACTER:
-  case TAG_COMPLEX:
   case TAG_F32:
   case TAG_F64:
   case TAG_F128:
@@ -1319,75 +1391,6 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
   return false;
 }
 
-bool env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest)
-{
-  uw i;
-  s_block     *src_block;
-  s_fn_clause *src_clause;
-  s_list      *src_pattern;
-  s_tag       *src_tag;
-  s_tag         tmp = {0};
-  s_block      *tmp_block;
-  s_fn_clause **tmp_clause;
-  s_fn         *tmp_fn;
-  s_list      **tmp_pattern;
-  s_tag        *tmp_tag;
-  assert(env);
-  assert(fn);
-  assert(dest);
-  (void) env;
-  tmp.type = TAG_FN;
-  tmp_fn = &tmp.data.fn;
-  src_clause = fn->clauses;
-  tmp_clause = &tmp_fn->clauses;
-  while (src_clause) {
-    *tmp_clause = fn_clause_new(NULL);
-    src_pattern = src_clause->pattern;
-    tmp_pattern = &(*tmp_clause)->pattern;
-    while (src_pattern) {
-      *tmp_pattern = list_new(NULL);
-      if (! env_eval_fn_tag(env, &src_pattern->tag,
-                            &(*tmp_pattern)->tag))
-        goto ko;
-      src_pattern = list_next(src_pattern);
-      tmp_pattern = &(*tmp_pattern)->next.data.list;
-    }
-    src_block = &src_clause->algo;
-    tmp_block = &(*tmp_clause)->algo;
-    if (! block_init(tmp_block, src_block->count))
-      goto ko;
-    tmp_block->short_form = src_block->short_form;
-    i = 0;
-    while (i < src_block->count) {
-      src_tag = src_block->tag + i;
-      tmp_tag = tmp_block->tag + i;
-      if (! env_eval_fn_tag(env, src_tag, tmp_tag))
-        goto ko;
-      i++;
-    }
-    src_clause = src_clause->next_clause;
-    tmp_clause = &(*tmp_clause)->next_clause;
-  }
-  tmp_fn->macro = fn->macro;
-  tmp_fn->special_operator = fn->special_operator;
-  *dest = tmp;
-  return true;
- ko:
-  fn_clean(&tmp.data.fn);
-  return false;
-}
-
-bool env_eval_fn_tag (s_env *env, const s_tag *tag, s_tag *dest)
-{
-  assert(env);
-  assert(tag);
-  assert(dest);
-  (void) env;
-  if (! tag_init_copy(dest, tag))
-    return false;
-  return true;
-}
-
 bool env_eval_tag (s_env *env, const s_tag *tag, s_tag *dest)
 {
   assert(env);
diff --git a/libc3/env.h b/libc3/env.h
index acdb0f8..27786ea 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -51,6 +51,9 @@ bool          env_eval_call_cfn (s_env *env, const s_call *call,
                                  s_tag *dest);
 bool          env_eval_call_fn (s_env *env, const s_call *call,
                                 s_tag *dest);
+bool          env_eval_call_fn_args (s_env *env, const s_fn *fn,
+                                     const s_list *arguments,
+                                     s_tag *dest);
 bool          env_eval_call_resolve (s_env *env, s_call *call);
 bool          env_eval_complex (s_env *env, const s_complex *c,
                                 s_tag *dest);
@@ -73,8 +76,33 @@ bool          env_eval_equal_tuple (s_env *env, bool macro,
 bool          env_eval_fn (s_env *env, const s_fn *fn, s_tag *dest);
 bool          env_eval_fn_tag (s_env *env, const s_tag *tag,
                                s_tag *dest);
-bool          env_eval_fn_call (s_env *env, const s_fn *fn,
-                                const s_list *arguments, s_tag *dest);
+bool          env_eval_fn_tag_array (s_env *env, const s_array *array,
+                                     s_tag *dest);
+bool          env_eval_fn_tag_block (s_env *env, const s_block *block,
+                                     s_tag *dest);
+bool          env_eval_fn_tag_call (s_env *env, const s_call *call,
+                                    s_tag *dest);
+bool          env_eval_fn_tag_complex (s_env *env, const s_complex *c,
+                                       s_tag *dest);
+bool          env_eval_fn_tag_ident (s_env *env, const s_ident *ident,
+                                     s_tag *dest);
+bool          env_eval_fn_tag_list (s_env *env, const s_list *list,
+                                    s_tag *dest);
+bool          env_eval_fn_tag_map (s_env *env, const s_map *map,
+                                   s_tag *dest);
+bool          env_eval_fn_tag_quote (s_env *env, const s_quote *quote,
+                                     s_tag *dest);
+bool          env_eval_fn_tag_str (s_env *env, const s_str *str,
+                                   s_tag *dest);
+bool          env_eval_fn_tag_struct (s_env *env, const s_struct *s,
+                                      s_tag *dest);
+bool          env_eval_fn_tag_tag (s_env *env, const s_tag *tag,
+                                   s_tag *dest);
+bool          env_eval_fn_tag_tuple (s_env *env, const s_tuple *tuple,
+                                     s_tag *dest);
+bool          env_eval_fn_tag_unquote (s_env *env,
+                                       const s_unquote *unquote,
+                                       s_tag *dest);
 bool          env_eval_ident (s_env *env, const s_ident *ident,
                               s_tag *dest);
 bool          env_eval_ident_is_bound (s_env *env,
@@ -93,6 +121,8 @@ bool          env_eval_quote_block (s_env *env, const s_block *block,
                                     s_tag *dest);
 bool          env_eval_quote_call (s_env *env, const s_call *call,
                                    s_tag *dest);
+bool          env_eval_quote_complex (s_env *env, const s_complex *c,
+                                      s_tag *dest);
 bool          env_eval_quote_list (s_env *env, const s_list *list,
                                    s_tag *dest);
 bool          env_eval_quote_map (s_env *env, const s_map *map,
diff --git a/libc3/eval.c b/libc3/eval.c
index f0cd387..8908a61 100644
--- a/libc3/eval.c
+++ b/libc3/eval.c
@@ -20,5 +20,5 @@ bool eval_tag (const s_tag *tag, s_tag *dest)
 
 bool eval_fn_call (const s_fn *fn, const s_list *args, s_tag *dest)
 {
-  return env_eval_fn_call(&g_c3_env, fn, args, dest);
+  return env_eval_call_fn_args(&g_c3_env, fn, args, dest);
 }