Commit 5e982bea995572a8946b73995633a4a266163815

Thomas de Grivel 2023-02-11T10:39:18

wip

diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index a9991b1..56d54cd 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -427,6 +427,7 @@ sw buf_parse_fn (s_buf *buf, s_fn *dest)
   sw r;
   sw result = 0;
   s_buf_save save;
+  s_fn tmp;
   assert(buf);
   assert(dest);
   buf_save_init(buf, &save);
@@ -436,24 +437,26 @@ sw buf_parse_fn (s_buf *buf, s_fn *dest)
   if ((r = buf_ignore_spaces(buf)) <= 0)
     goto restore;
   result += r;
-  fn_init(dest);
-  if ((r = buf_parse_fn_pattern(buf, &dest->pattern)) < 0) {
+  fn_init(&tmp);
+  if ((r = buf_parse_fn_pattern(buf, &tmp.pattern)) < 0) {
     warnx("buf_parse_fn: invalid pattern");
     goto restore;
   }
-  dest->arity = list_length(dest->pattern);
+  tmp.arity = list_length(tmp.pattern);
   result += r;
   if ((r = buf_ignore_spaces(buf)) < 0)
     goto restore;
   result += r;
-  if ((r = buf_parse_fn_algo(buf, &dest->algo)) <= 0) {
-    buf_inspect_fn(&g_c3_env.err, dest);
+  if ((r = buf_parse_fn_algo(buf, &tmp.algo)) <= 0) {
+    buf_inspect_fn(&g_c3_env.err, &tmp);
     warnx("buf_parse_fn: invalid program");
     goto restore;
   }
+  *dest = tmp;
   r = result;
   goto clean;
  restore:
+  fn_clean(&tmp);
   buf_save_restore_rpos(buf, &save);
  clean:
   buf_save_clean(buf, &save);
diff --git a/libc3/env.c b/libc3/env.c
index 0e52b41..cdbb622 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -154,16 +154,20 @@ s_tag * env_eval_call_fn (s_env *env, const s_call *call, s_tag *dest)
   frame_init(&frame, env->frame);
   env->frame = &frame;
   if (call->arguments) {
-    if (! (args = env_eval_call_arguments(env, call->arguments)))
+    if (! (args = env_eval_call_arguments(env, call->arguments))) {
+      env->frame = frame_clean(&frame);
       return NULL;
+    }
     if (! env_eval_equal_list(env, fn->pattern, args, &tmp)) {
       list_delete_all(args);
+      env->frame = frame_clean(&frame);
       return NULL;
     }
   }
   if (! env_eval_progn(env, fn->algo, dest)) {
     list_delete_all(args);
     list_delete_all(tmp);
+    env->frame = frame_clean(&frame);
     return NULL;
   }
   list_delete_all(args);