commit f3c5bfda03ab1412ffb98a0d00b91300646040d1
parent 50ab31181588006ba4e2f1e3d3ad56d8d57d24e3
Author: sin <sin@2f30.org>
Date: Thu, 15 May 2014 11:05:40 +0100
Prepare the ground for more builtins
Diffstat:
M | parser.c | | | 31 | ++++++++++++++++++++++--------- |
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/parser.c b/parser.c
@@ -59,11 +59,14 @@ struct object {
} d;
};
+static struct object *evalquote(struct object *);
+
struct {
char *name;
struct object *o;
+ struct object *(*fn)(struct object *);
} builtins[] = {
- { .name = "quote" },
+ { .name = "quote", .fn = evalquote },
};
static int
@@ -242,26 +245,28 @@ sexpression(FILE *in)
return NULL;
}
-static int
-quoted(struct object *o)
+struct object *
+evalquote(struct object *o)
{
struct object *car;
if (o->type == OPair) {
car = o->d.p.car;
- return car->type == OIdentifier &&
- strcmp(car->d.i.s, "quote") == 0;
+ if (car->type == OIdentifier &&
+ strcmp(car->d.i.s, "quote") == 0)
+ return o->d.p.cdr->d.p.car;
}
- return 0;
+ return NULL;
}
struct object *
eval(struct object *o)
{
+ size_t i;
struct object *otmp;
- switch (o->type) {
/* self-evaluating objects */
+ switch (o->type) {
case OError:
case OEof:
case OBoolean:
@@ -270,6 +275,7 @@ eval(struct object *o)
case OString:
return o;
}
+ /* evaluate identifiers */
if (o->type == OIdentifier) {
if (builtin(o->d.i.s) == 1)
return error("cannot eval builtin in this context");
@@ -278,8 +284,12 @@ eval(struct object *o)
return error("unbound identifier");
return otmp;
}
- if (quoted(o))
- return o->d.p.cdr->d.p.car; /* cadr */
+ /* evaluate builtins */
+ for (i = 0; i < LEN(builtins); i++) {
+ otmp = builtins[i].fn(o);
+ if (otmp)
+ return otmp;
+ }
return error("cannot eval object");
}
@@ -315,6 +325,9 @@ print(struct object *o)
case OEof:
printf("%s", o->d.eof.s);
break;
+ case OIdentifier:
+ printf("%s", o->d.i.s);
+ break;
case OBoolean:
printf("#%c", o->d.b.v == false ? 'f' : 't');
break;