"quote" -> "block"

Update README accordingly.
This commit is contained in:
Přemysl Eric Janouch 2017-05-30 01:04:03 +02:00
parent 4698e522cc
commit d579e68051
Signed by: p
GPG Key ID: B715679E3A361BE6
2 changed files with 27 additions and 22 deletions

View File

@ -25,8 +25,8 @@ The parser, however, does a bunch of transformations:
* `[a b c]` makes a call to `(list a b c)`; * `[a b c]` makes a call to `(list a b c)`;
* `@var` is a shorthand for `(set var)`; * `@var` is a shorthand for `(set var)`;
* `{ code }` is the most complex one. Each line within the curly braces is * `{ code }` is the most complex one. Each line within the curly braces is
wrapped in parentheses, and the resulting list is quoted, so that it doesn't wrapped in parentheses, and the resulting sequence is wrapped in a quoted
execute immediately. list, so that it doesn't execute immediately.
As an example, consider the following snippet: As an example, consider the following snippet:
@ -38,13 +38,13 @@ As an example, consider the following snippet:
which gets expanded to the following: which gets expanded to the following:
((print (if (quote ((eq? (set var) foo))) ((print (if (block (eq? (set var) foo))
(quote ((values 'Hello world\n'))) (block (values 'Hello world\n'))
else else
(quote ((values 'Error\n')))))) (block (values 'Error\n')))))
Observe that the whole program is enclosed in an implicit pair of `{}` and that Observe that the whole program is enclosed in an implicit pair of `{}` and that
`quote` is a very powerful special form which can replace many others if needed. `block` is all that's left of special forms.
For a slightly more realistic example you can have a look at 'greet.ell'. For a slightly more realistic example you can have a look at 'greet.ell'.
@ -55,20 +55,27 @@ of lists) are assigned to local variables named `1`, `2`, etc., and the full
list of them is stored in `args`. list of them is stored in `args`.
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. Lists are left for
execution as they are.
The last expression in a block is the return value. The last expression in a block is the return value.
Special Forms Special Forms
------------- -------------
`quote [<arg>]...` `block [<arg>]...`
Like `values` but returns the arguments without any evaluation. Like `list` but doesn't evaluate arguments. A more appropriate name might be
`quoted-list`, which is not as descriptive in terms of syntax. If simple
quoting is desired, the list can be unpacked by an ordinary command.
Standard library Standard Library
---------------- ----------------
The standard library interprets the empty list and the empty string as false The standard library interprets the empty list and the empty string as false
values, everything else is taken as true. values, everything else is considered true. Numbers are floating point with
double precision, trailing zeroes are truncated.
Where a `<body>` is expected, strings retain their value, and block evaluation
is postponed as necessary.
`local <names> [<value>]...` `local <names> [<value>]...`
@ -89,7 +96,7 @@ Return an arbitrary number of values.
`if <cond> <body> [elif <cond> <body>]... [else <body>]` `if <cond> <body> [elif <cond> <body>]... [else <body>]`
Conditional evaluation, strings evaluate to themselves. Conditional evaluation.
`for <list> <body>` `for <list> <body>`
@ -129,7 +136,7 @@ Execute the body and pass any error to the handler instead of propagating it.
`throw <message>` `throw <message>`
Throw an error. Messages starting on an underscore don't generate backtraces Throw an error. Messages starting on an underscore don't generate backtraces,
which can be used to catch them. which can be used to catch them.
`not <value>` `not <value>`

16
ell.c
View File

@ -383,12 +383,10 @@ print_string (struct item *s) {
static bool static bool
print_block (struct item *list) { print_block (struct item *list) {
if (!list->head || strcmp (list->head->value, "quote") if (!list->head || strcmp (list->head->value, "block"))
|| !list->head->next || list->head->next->next
|| list->head->next->type != ITEM_LIST)
return false; return false;
list = list->head->next->head; list = list->head->next;
for (struct item *line = list; line; line = line->next) for (struct item *line = list; line; line = line->next)
if (line->type != ITEM_LIST) if (line->type != ITEM_LIST)
return false; return false;
@ -579,8 +577,7 @@ parse_item (struct parser *self, jmp_buf out) {
while ((*tail = parse_line (self, err))) while ((*tail = parse_line (self, err)))
tail = &(*tail)->next; tail = &(*tail)->next;
EXPECT (T_RBRACE); EXPECT (T_RBRACE);
result = CHECK (new_list (result)); return CHECK (parse_prefix_list (result, "block"));
return CHECK (parse_prefix_list (result, "quote"));
} }
self->memory_failure = !(self->error = lexer_errorf (&self->lexer, self->memory_failure = !(self->error = lexer_errorf (&self->lexer,
@ -843,8 +840,9 @@ execute_item (struct context *ctx, struct item *body, struct item **result) {
struct item *args = body->next; struct item *args = body->next;
if (body->type == ITEM_STRING) { if (body->type == ITEM_STRING) {
const char *name = body->value; const char *name = body->value;
if (!strcmp (name, "quote")) if (!strcmp (name, "block"))
return !args || check (ctx, (*result = new_clone_list (args))); return (!args || check (ctx, (args = new_clone_list (args))))
&& check (ctx, (*result = new_list (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);
@ -857,7 +855,7 @@ execute_item (struct context *ctx, struct item *body, struct item **result) {
return false; return false;
// It might a bit confusing that this doesn't evaluate arguments // It might a bit confusing that this doesn't evaluate arguments
// but neither does "quote" and there's nothing to do here // but neither does "block" and there's nothing to do here
if (!evaluated) if (!evaluated)
return true; return true;