parent
a621de2d50
commit
76df28e492
29
ell.c
29
ell.c
|
@ -852,6 +852,13 @@ set_single_argument (struct context *ctx, struct item *item) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
execute_any (struct context *ctx, struct item *body, struct item **result) {
|
||||||
|
if (body->type == ITEM_STRING)
|
||||||
|
return check (ctx, (*result = new_clone (body)));
|
||||||
|
return execute (ctx, body->head, result);
|
||||||
|
}
|
||||||
|
|
||||||
static struct item *
|
static struct item *
|
||||||
new_number (double n) {
|
new_number (double n) {
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -911,12 +918,12 @@ defn (fn_if) {
|
||||||
return set_error (ctx, "missing body");
|
return set_error (ctx, "missing body");
|
||||||
|
|
||||||
struct item *res = NULL;
|
struct item *res = NULL;
|
||||||
if (!execute_statement (ctx, cond, &res))
|
if (!execute_any (ctx, cond, &res))
|
||||||
return false;
|
return false;
|
||||||
bool match = truthy (res);
|
bool match = truthy (res);
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
if (match)
|
if (match)
|
||||||
return execute_statement (ctx, body, result);
|
return execute_any (ctx, body, result);
|
||||||
|
|
||||||
if (!(keyword = body->next))
|
if (!(keyword = body->next))
|
||||||
break;
|
break;
|
||||||
|
@ -926,7 +933,7 @@ defn (fn_if) {
|
||||||
if (!strcmp (keyword->value, "else")) {
|
if (!strcmp (keyword->value, "else")) {
|
||||||
if (!(body = keyword->next))
|
if (!(body = keyword->next))
|
||||||
return set_error (ctx, "missing body");
|
return set_error (ctx, "missing body");
|
||||||
return execute_statement (ctx, body, result);
|
return execute_any (ctx, body, result);
|
||||||
}
|
}
|
||||||
if (strcmp (keyword->value, "elif"))
|
if (strcmp (keyword->value, "elif"))
|
||||||
return set_error (ctx, "invalid keyword: %s", keyword->value);
|
return set_error (ctx, "invalid keyword: %s", keyword->value);
|
||||||
|
@ -935,8 +942,8 @@ defn (fn_if) {
|
||||||
}
|
}
|
||||||
|
|
||||||
defn (fn_map) {
|
defn (fn_map) {
|
||||||
struct item *body = args, *values;
|
struct item *body, *values;
|
||||||
if (!body || body->type != ITEM_LIST)
|
if (!(body = args))
|
||||||
return set_error (ctx, "first argument must be a function");
|
return set_error (ctx, "first argument must be a function");
|
||||||
if (!(values = body->next) || values->type != ITEM_LIST)
|
if (!(values = body->next) || values->type != ITEM_LIST)
|
||||||
return set_error (ctx, "second argument must be a list");
|
return set_error (ctx, "second argument must be a list");
|
||||||
|
@ -944,7 +951,7 @@ 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) {
|
||||||
if (!set_single_argument (ctx, v)
|
if (!set_single_argument (ctx, v)
|
||||||
|| !execute (ctx, body->head, out)) {
|
|| !execute_any (ctx, body, out)) {
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1008,12 +1015,12 @@ defn (fn_parse) {
|
||||||
}
|
}
|
||||||
|
|
||||||
defn (fn_try) {
|
defn (fn_try) {
|
||||||
struct item *body = args, *handler;
|
struct item *body, *handler;
|
||||||
if (!body || body->type != ITEM_LIST)
|
if (!(body = args))
|
||||||
return set_error (ctx, "first argument must be a function");
|
return set_error (ctx, "first argument must be a function");
|
||||||
if (!(handler = body->next) || handler->type != ITEM_LIST)
|
if (!(handler = body->next))
|
||||||
return set_error (ctx, "second argument must be a function");
|
return set_error (ctx, "second argument must be a function");
|
||||||
if (execute (ctx, body->head, result))
|
if (execute_any (ctx, body, result))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
struct item *message;
|
struct item *message;
|
||||||
|
@ -1025,7 +1032,7 @@ defn (fn_try) {
|
||||||
item_free_list (*result); *result = NULL;
|
item_free_list (*result); *result = NULL;
|
||||||
|
|
||||||
bool ok = set_single_argument (ctx, message)
|
bool ok = set_single_argument (ctx, message)
|
||||||
&& execute (ctx, handler->head, result);
|
&& execute_any (ctx, handler, result);
|
||||||
item_free (message);
|
item_free (message);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue