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);