Fix for, map, filter
This commit is contained in:
parent
7e8bfbf9b9
commit
cbce0d6498
51
ell.c
51
ell.c
|
@ -765,6 +765,13 @@ execute_args (struct context *ctx, struct item *args, struct item **res) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
set_arg (struct context *ctx, size_t arg, struct item *value) {
|
||||||
|
char buf[64];
|
||||||
|
(void) snprintf (buf, sizeof buf, "%zu", arg);
|
||||||
|
return set (ctx, buf, value);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: we should probably maintain arguments in a separate list,
|
// TODO: we should probably maintain arguments in a separate list,
|
||||||
// either that or at least remember the count so that we can reset them
|
// either that or at least remember the count so that we can reset them
|
||||||
static bool
|
static bool
|
||||||
|
@ -776,12 +783,9 @@ execute_and_set_args (struct context *ctx, struct item *following) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (struct item *arg = args; arg; arg = arg->next) {
|
for (struct item *arg = args; arg; arg = arg->next)
|
||||||
char buf[64];
|
if (!set_arg (ctx, i++, arg))
|
||||||
(void) snprintf (buf, sizeof buf, "%zu", i++);
|
|
||||||
if (!set (ctx, buf, arg))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
item_free_list (args);
|
item_free_list (args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -822,6 +826,15 @@ execute_statement
|
||||||
body = get (ctx, name);
|
body = get (ctx, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: not sure whether it makes more sense to evaluate a list
|
||||||
|
// instead of leaving it as it is -> probably evaluate, since then
|
||||||
|
// lambdas will be better: { arg _n; print @_n } 'hello\n'
|
||||||
|
//
|
||||||
|
// Even though it's practically useless being able to dereference
|
||||||
|
// function names directly that way: `@list 1 2 3` vs `list 1 2 3`
|
||||||
|
//
|
||||||
|
// Maybe something like (choose [@f1 @f2 @f3]) arg1 arg2 arg3
|
||||||
|
|
||||||
if (!body) {
|
if (!body) {
|
||||||
struct native_fn *fn = native_find (name);
|
struct native_fn *fn = native_find (name);
|
||||||
if (!fn)
|
if (!fn)
|
||||||
|
@ -935,14 +948,10 @@ defn (fn_for) {
|
||||||
return set_error (ctx, "second argument must be a function");
|
return set_error (ctx, "second argument must be a function");
|
||||||
|
|
||||||
(void) result;
|
(void) result;
|
||||||
for (struct item *iter = list->head; iter; iter = iter->next) {
|
for (struct item *v = list->head; v; v = v->next) {
|
||||||
struct item *copy;
|
|
||||||
if (!check (ctx, (copy = new_clone (iter))))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
struct item *res = NULL;
|
struct item *res = NULL;
|
||||||
// FIXME: wrong thing is executed, see fn_map
|
bool ok = set_arg (ctx, 0, v)
|
||||||
bool ok = execute_statement (ctx, body, &res);
|
&& execute (ctx, body->head, &res);
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
@ -959,14 +968,12 @@ defn (fn_map) {
|
||||||
|
|
||||||
struct item *res = NULL, **out = &res;
|
struct item *res = NULL, **out = &res;
|
||||||
for (struct item *v = values->head; v; v = v->next) {
|
for (struct item *v = values->head; v; v = v->next) {
|
||||||
// FIXME: wrong thing is executed
|
if (!set_arg (ctx, 0, v)
|
||||||
// -> either temporarily append the value to the body
|
|| !execute (ctx, body->head, out)) {
|
||||||
// -> or modify execute_statement()
|
|
||||||
if (!execute_statement (ctx, v, out)) {
|
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (*out && (*out)->next)
|
while (*out)
|
||||||
out = &(*out)->next;
|
out = &(*out)->next;
|
||||||
}
|
}
|
||||||
return check (ctx, (*result = new_list (res)));
|
return check (ctx, (*result = new_list (res)));
|
||||||
|
@ -981,14 +988,14 @@ defn (fn_filter) {
|
||||||
|
|
||||||
struct item *res = NULL, **out = &res;
|
struct item *res = NULL, **out = &res;
|
||||||
for (struct item *v = values->head; v; v = v->next) {
|
for (struct item *v = values->head; v; v = v->next) {
|
||||||
struct item *res = NULL;
|
struct item *keep = NULL;
|
||||||
// FIXME: wrong thing is executed, see fn_map
|
if (!set_arg (ctx, 0, v)
|
||||||
if (!execute_statement (ctx, body, &res)) {
|
|| !execute (ctx, body->head, &keep)) {
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool match = truthy (res);
|
bool match = truthy (keep);
|
||||||
item_free_list (res);
|
item_free_list (keep);
|
||||||
if (!match)
|
if (!match)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue