Refactor argument saving
While nothing has been achieved, at least now it should be obvious.
This commit is contained in:
parent
b9c2a395d9
commit
2224ca00ad
32
ell.c
32
ell.c
|
@ -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 (struct context *ctx, struct item *body, struct item **);
|
||||||
|
|
||||||
static bool
|
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;
|
size_t i = 0;
|
||||||
|
struct item *res = NULL, **out = &res;
|
||||||
for (; args; args = args->next) {
|
for (; args; args = args->next) {
|
||||||
struct item *evaluated = NULL;
|
struct item *evaluated = NULL;
|
||||||
// Arguments should not evaporate, default to a nil value
|
// 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;
|
goto error;
|
||||||
item_free_list (evaluated->next);
|
item_free_list (evaluated->next);
|
||||||
evaluated->next = NULL;
|
evaluated->next = NULL;
|
||||||
res = &(*res = evaluated)->next;
|
out = &(*out = evaluated)->next;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
item_free_list (ctx->arguments);
|
||||||
|
ctx->arguments = res;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
// Once the code flows like this, at least make some use of it
|
// Once the code flows like this, at least make some use of it
|
||||||
if (can_modify_error (ctx)) {
|
if (can_modify_error (ctx)) {
|
||||||
|
@ -786,6 +790,7 @@ error:
|
||||||
set_error (ctx, "(argument %zu) -> %s", i, tmp);
|
set_error (ctx, "(argument %zu) -> %s", i, tmp);
|
||||||
free (tmp);
|
free (tmp);
|
||||||
}
|
}
|
||||||
|
item_free_list (res);
|
||||||
return false;
|
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);
|
struct native_fn *fn = native_find (ctx, name);
|
||||||
if (!fn)
|
if (!fn)
|
||||||
return set_error (ctx, "unknown function");
|
return set_error (ctx, "unknown function");
|
||||||
|
if (!execute_args (ctx, args))
|
||||||
|
return false;
|
||||||
|
|
||||||
struct item *evaluated = NULL;
|
// "ctx->arguments" is for assign_arguments() only
|
||||||
bool ok = execute_args (ctx, args, &evaluated)
|
args = ctx->arguments;
|
||||||
&& fn->handler (ctx, evaluated, result);
|
ctx->arguments = NULL;
|
||||||
item_free_list (evaluated);
|
bool ok = fn->handler (ctx, args, result);
|
||||||
|
item_free_list (args);
|
||||||
return ok;
|
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
|
// Resolving names ecursively could be pretty fatal, let's not do that
|
||||||
if (body->type == ITEM_STRING)
|
if (body->type == ITEM_STRING)
|
||||||
return check (ctx, (*result = new_clone (body)));
|
return check (ctx, (*result = new_clone (body)));
|
||||||
|
return execute_args (ctx, args)
|
||||||
struct item *evaluated = NULL;
|
&& execute (ctx, body->head, result);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
Loading…
Reference in New Issue