iris

small scheme interpreter
git clone git://git.2f30.org/iris.git
Log | Files | Refs | LICENSE

commit f3c5bfda03ab1412ffb98a0d00b91300646040d1
parent 50ab31181588006ba4e2f1e3d3ad56d8d57d24e3
Author: sin <sin@2f30.org>
Date:   Thu May 15 11:05:40 +0100

Prepare the ground for more builtins

Diffstat:
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;