Make and/or more useful
Now they follow Scheme, they just aren't special forms here.
This commit is contained in:
parent
4358e6f324
commit
735dfd026a
@ -129,6 +129,14 @@ Execute the body and pass any error to the handler instead of propagating it.
|
||||
|
||||
Throw an error. Messages starting on an underscore don't generate backtraces.
|
||||
|
||||
`not <value>`
|
||||
|
||||
Return a boolean with the opposite truthiness.
|
||||
|
||||
`and [<body>]...`, `or [<body>]...`
|
||||
|
||||
Short-circuit evaluation, trying to return whatever the bodies result in.
|
||||
|
||||
`+`, `-`, `*`, `/`
|
||||
|
||||
Arithmetic operations on floating point numbers.
|
||||
|
33
ell.c
33
ell.c
@ -839,7 +839,7 @@ execute_item (struct context *ctx, struct item *body, struct item **result) {
|
||||
struct item *args = body->next;
|
||||
if (body->type == ITEM_STRING) {
|
||||
const char *name = body->value;
|
||||
// TODO: these could be just regular handlers, only top priority
|
||||
// These could be just regular handlers, only top priority
|
||||
if (!strcmp (name, "quote"))
|
||||
return !args || check (ctx, (*result = new_clone_list (args)));
|
||||
if (!strcmp (name, "arg"))
|
||||
@ -1168,19 +1168,32 @@ defn (fn_not) {
|
||||
return check (ctx, (*result = new_boolean (!truthy (args))));
|
||||
}
|
||||
|
||||
// TODO: "and" and "or" should be short-circuiting special forms
|
||||
defn (fn_and) {
|
||||
bool res = true;
|
||||
for (; args; args = args->next)
|
||||
res &= truthy (args);
|
||||
return check (ctx, (*result = new_boolean (res)));
|
||||
if (!args)
|
||||
return check (ctx, (*result = new_boolean (true)));
|
||||
for (; args; args = args->next) {
|
||||
item_free_list (*result);
|
||||
*result = NULL;
|
||||
|
||||
if (!execute_any (ctx, args, result))
|
||||
return false;
|
||||
if (!truthy (*result))
|
||||
return check (ctx, (*result = new_boolean (false)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
defn (fn_or) {
|
||||
bool res = false;
|
||||
for (; args; args = args->next)
|
||||
res |= truthy (args);
|
||||
return check (ctx, (*result = new_boolean (res)));
|
||||
for (; args; args = args->next) {
|
||||
if (!execute_any (ctx, args, result))
|
||||
return false;
|
||||
if (truthy (*result))
|
||||
return true;
|
||||
|
||||
item_free_list (*result);
|
||||
*result = NULL;
|
||||
}
|
||||
return check (ctx, (*result = new_boolean (false)));
|
||||
}
|
||||
|
||||
defn (fn_eq) {
|
||||
|
Loading…
Reference in New Issue
Block a user