Refactor argument saving

While nothing has been achieved, at least now it should be obvious.
This commit is contained in:
Přemysl Eric Janouch 2017-05-21 18:32:28 +02:00
parent b9c2a395d9
commit 2224ca00ad
Signed by: p
GPG Key ID: B715679E3A361BE6
1 changed files with 16 additions and 16 deletions

32
ell.c
View File

@ -764,8 +764,9 @@ static bool execute_statement (struct context *, struct item *, struct item **);
static bool execute (struct context *ctx, struct item *body, struct item **);
static bool
execute_args (struct context *ctx, struct item *args, struct item **res) {
execute_args (struct context *ctx, struct item *args) {
size_t i = 0;
struct item *res = NULL, **out = &res;
for (; args; args = args->next) {
struct item *evaluated = NULL;
// Arguments should not evaporate, default to a nil value
@ -774,10 +775,13 @@ execute_args (struct context *ctx, struct item *args, struct item **res) {
goto error;
item_free_list (evaluated->next);
evaluated->next = NULL;
res = &(*res = evaluated)->next;
out = &(*out = evaluated)->next;
i++;
}
item_free_list (ctx->arguments);
ctx->arguments = res;
return true;
error:
// Once the code flows like this, at least make some use of it
if (can_modify_error (ctx)) {
@ -786,6 +790,7 @@ error:
set_error (ctx, "(argument %zu) -> %s", i, tmp);
free (tmp);
}
item_free_list (res);
return false;
}
@ -795,11 +800,14 @@ execute_native (struct context *ctx, const char *name, struct item *args,
struct native_fn *fn = native_find (ctx, name);
if (!fn)
return set_error (ctx, "unknown function");
if (!execute_args (ctx, args))
return false;
struct item *evaluated = NULL;
bool ok = execute_args (ctx, args, &evaluated)
&& fn->handler (ctx, evaluated, result);
item_free_list (evaluated);
// "ctx->arguments" is for assign_arguments() only
args = ctx->arguments;
ctx->arguments = NULL;
bool ok = fn->handler (ctx, args, result);
item_free_list (args);
return ok;
}
@ -809,16 +817,8 @@ execute_resolved (struct context *ctx, struct item *body, struct item *args,
// Resolving names ecursively could be pretty fatal, let's not do that
if (body->type == ITEM_STRING)
return check (ctx, (*result = new_clone (body)));
struct item *evaluated = NULL;
if (!execute_args (ctx, args, &evaluated)) {
item_free_list (evaluated);
return false;
}
item_free_list (ctx->arguments);
ctx->arguments = evaluated;
return execute (ctx, body->head, result);
return execute_args (ctx, args)
&& execute (ctx, body->head, result);
}
static bool