Remove some ancient stupidity
This commit is contained in:
parent
ba2e31d81f
commit
dae5622955
|
@ -48,10 +48,9 @@ Observe that the whole program is enclosed in an implicit pair of `{}` and that
|
||||||
Runtime
|
Runtime
|
||||||
-------
|
-------
|
||||||
All variables are put in a single global namespace with no further scoping.
|
All variables are put in a single global namespace with no further scoping.
|
||||||
When calling a command (which is a list of lists), all arguments are
|
Arguments to a block (which is a list of lists) must be assigned to variables
|
||||||
automatically stored in variables named 0, 1, 2, 3, ... n. They are however
|
first using the `arg` special form, and that must happen before they get
|
||||||
effectively inaccessible and you must rename them first using the `arg` special
|
overriden by execution of a different block.
|
||||||
form.
|
|
||||||
|
|
||||||
When evaluating a command, the first argument is typically a string with its
|
When evaluating a command, the first argument is typically a string with its
|
||||||
name and it is resolved as if `set` was called on it.
|
name and it is resolved as if `set` was called on it.
|
||||||
|
|
76
ell.c
76
ell.c
|
@ -625,6 +625,7 @@ parser_run (struct parser *self, const char **e) {
|
||||||
struct context {
|
struct context {
|
||||||
struct item *variables; ///< List of variables
|
struct item *variables; ///< List of variables
|
||||||
struct native_fn *native; ///< Maps strings to C functions
|
struct native_fn *native; ///< Maps strings to C functions
|
||||||
|
struct item *arguments; ///< Arguments to last executed block
|
||||||
|
|
||||||
char *error; ///< Error information
|
char *error; ///< Error information
|
||||||
bool error_is_fatal; ///< Whether the error can be catched
|
bool error_is_fatal; ///< Whether the error can be catched
|
||||||
|
@ -654,6 +655,7 @@ context_free (struct context *ctx) {
|
||||||
free (iter);
|
free (iter);
|
||||||
}
|
}
|
||||||
item_free_list (ctx->variables);
|
item_free_list (ctx->variables);
|
||||||
|
item_free_list (ctx->arguments);
|
||||||
free (ctx->error);
|
free (ctx->error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,19 +735,19 @@ set_error (struct context *ctx, const char *format, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
rename_arguments (struct context *ctx, struct item *names) {
|
assign_arguments (struct context *ctx, struct item *names) {
|
||||||
size_t i = 0;
|
struct item *arg = ctx->arguments;
|
||||||
for (; names; names = names->next) {
|
for (; names; names = names->next) {
|
||||||
if (names->type != ITEM_STRING)
|
if (names->type != ITEM_STRING)
|
||||||
return set_error (ctx, "argument names must be strings");
|
return set_error (ctx, "argument names must be strings");
|
||||||
|
|
||||||
char buf[64];
|
struct item *value = NULL;
|
||||||
(void) snprintf (buf, sizeof buf, "%zu", i++);
|
if (arg && !check (ctx, (value = new_clone (arg))))
|
||||||
struct item *value = get (ctx, buf);
|
|
||||||
if (value && !check (ctx, (value = new_clone (value))))
|
|
||||||
return false;
|
return false;
|
||||||
if (!set (ctx, names->value, value))
|
if (!set (ctx, names->value, value))
|
||||||
return false;
|
return false;
|
||||||
|
if (arg)
|
||||||
|
arg = arg->next;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -770,14 +772,6 @@ 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 check (ctx, (value = new_clone (value)))
|
|
||||||
&& set (ctx, buf, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
execute_native (struct context *ctx, const char *name, struct item *args,
|
execute_native (struct context *ctx, const char *name, struct item *args,
|
||||||
struct item **result) {
|
struct item **result) {
|
||||||
|
@ -805,16 +799,8 @@ execute_resolved (struct context *ctx, struct item *body, struct item *args,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should probably maintain arguments in a separate list,
|
item_free_list (ctx->arguments);
|
||||||
// either that or at least remember the count so that we can reset them
|
ctx->arguments = evaluated;
|
||||||
// NOTE: it even seems that storing them as numbers is completely useless
|
|
||||||
size_t i = 0;
|
|
||||||
for (struct item *arg = evaluated; arg; arg = arg->next)
|
|
||||||
if (!set_arg (ctx, i++, arg)) {
|
|
||||||
item_free_list (evaluated);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
item_free_list (evaluated);
|
|
||||||
return execute (ctx, body->head, result);
|
return execute (ctx, body->head, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,7 +813,7 @@ execute_item (struct context *ctx, struct item *body, struct item **result) {
|
||||||
if (!strcmp (name, "quote"))
|
if (!strcmp (name, "quote"))
|
||||||
return !args || check (ctx, (*result = new_clone_list (args)));
|
return !args || check (ctx, (*result = new_clone_list (args)));
|
||||||
if (!strcmp (name, "arg"))
|
if (!strcmp (name, "arg"))
|
||||||
return rename_arguments (ctx, args);
|
return assign_arguments (ctx, args);
|
||||||
if ((body = get (ctx, name)))
|
if ((body = get (ctx, name)))
|
||||||
return execute_resolved (ctx, body, args, result);
|
return execute_resolved (ctx, body, args, result);
|
||||||
return execute_native (ctx, name, args, result);
|
return execute_native (ctx, name, args, result);
|
||||||
|
@ -897,6 +883,28 @@ execute (struct context *ctx, struct item *body, struct item **result) {
|
||||||
#define defn(name) static bool name \
|
#define defn(name) static bool name \
|
||||||
(struct context *ctx, struct item *args, struct item **result)
|
(struct context *ctx, struct item *args, struct item **result)
|
||||||
|
|
||||||
|
static bool
|
||||||
|
set_single_argument (struct context *ctx, struct item *item) {
|
||||||
|
struct item *single;
|
||||||
|
if (!check (ctx, (single = new_clone (item))))
|
||||||
|
return false;
|
||||||
|
item_free_list (ctx->arguments);
|
||||||
|
ctx->arguments = single;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define E_BREAK "_break"
|
||||||
|
|
||||||
|
static bool
|
||||||
|
eat_error (struct context *ctx, const char *name) {
|
||||||
|
if (!ctx->error || strcmp (ctx->error, name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
free (ctx->error);
|
||||||
|
ctx->error = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static struct item *
|
static struct item *
|
||||||
new_number (double n) {
|
new_number (double n) {
|
||||||
char *s;
|
char *s;
|
||||||
|
@ -914,18 +922,6 @@ new_number (double n) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define E_BREAK "_break"
|
|
||||||
|
|
||||||
static bool
|
|
||||||
eat_error (struct context *ctx, const char *name) {
|
|
||||||
if (!ctx->error || strcmp (ctx->error, name))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
free (ctx->error);
|
|
||||||
ctx->error = NULL;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
truthy (struct item *item) {
|
truthy (struct item *item) {
|
||||||
return item
|
return item
|
||||||
|
@ -1001,7 +997,7 @@ defn (fn_for) {
|
||||||
(void) result;
|
(void) result;
|
||||||
for (struct item *v = list->head; v; v = v->next) {
|
for (struct item *v = list->head; v; v = v->next) {
|
||||||
struct item *res = NULL;
|
struct item *res = NULL;
|
||||||
bool ok = set_arg (ctx, 0, v)
|
bool ok = set_single_argument (ctx, v)
|
||||||
&& execute (ctx, body->head, &res);
|
&& execute (ctx, body->head, &res);
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
if (eat_error (ctx, E_BREAK))
|
if (eat_error (ctx, E_BREAK))
|
||||||
|
@ -1025,7 +1021,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_arg (ctx, 0, v)
|
if (!set_single_argument (ctx, v)
|
||||||
|| !execute (ctx, body->head, out)) {
|
|| !execute (ctx, body->head, out)) {
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1046,7 +1042,7 @@ 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 *keep = NULL;
|
struct item *keep = NULL;
|
||||||
if (!set_arg (ctx, 0, v)
|
if (!set_single_argument (ctx, v)
|
||||||
|| !execute (ctx, body->head, &keep)) {
|
|| !execute (ctx, body->head, &keep)) {
|
||||||
item_free_list (res);
|
item_free_list (res);
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue