commit 00d7556a1443ee2047887f20440320c459f1d272
parent 76e8179b214bea8c00515956c1602522caa759b6
Author: sin <sin@2f30.org>
Date: Fri, 16 May 2014 15:23:41 +0100
Add car, cdr and cons
Diffstat:
M | parser.c | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 59 insertions(+), 0 deletions(-)
diff --git a/parser.c b/parser.c
@@ -74,6 +74,9 @@ static struct object *evalset(struct object *);
/* primitive procedures */
static struct object *evalboolean(struct object *);
+static struct object *evalcar(struct object *);
+static struct object *evalcdr(struct object *);
+static struct object *evalcons(struct object *);
static struct object *evaldiff(struct object *);
static struct object *evaleq(struct object *);
static struct object *evalgt(struct object *);
@@ -100,6 +103,9 @@ struct {
struct object *(*fn)(struct object *);
} procs[] = {
{ .name = "boolean", .fn = evalboolean },
+ { .name = "car", .fn = evalcar },
+ { .name = "cdr", .fn = evalcdr },
+ { .name = "cons", .fn = evalcons },
{ .name = "diff", .fn = evaldiff },
{ .name = "eq", .fn = evaleq },
{ .name = "gt", .fn = evalgt },
@@ -440,6 +446,59 @@ evalboolean(struct object *o)
}
static struct object *
+evalcar(struct object *o)
+{
+ struct object *arg;
+
+ if (o->type != OPair)
+ return NULL;
+ if (car(o)->type != OIdentifier ||
+ strcmp(car(o)->d.i.name, "car") != 0)
+ return NULL;
+ if (caddr(o))
+ return error("multiple arguments");
+ arg = eval(cadr(o));
+ if (arg->type == OError)
+ return arg;
+ if (arg->type != OPair)
+ return error("expected pair");
+ return car(arg);
+}
+
+static struct object *
+evalcdr(struct object *o)
+{
+ struct object *arg;
+
+ if (o->type != OPair)
+ return NULL;
+ if (car(o)->type != OIdentifier ||
+ strcmp(car(o)->d.i.name, "cdr") != 0)
+ return NULL;
+ if (caddr(o))
+ return error("multiple arguments");
+ arg = eval(cadr(o));
+ if (arg->type == OError)
+ return arg;
+ if (arg->type != OPair)
+ return error("expected pair");
+ return cdr(arg);
+}
+
+static struct object *
+evalcons(struct object *o)
+{
+ if (o->type != OPair)
+ return NULL;
+ if (car(o)->type != OIdentifier ||
+ strcmp(car(o)->d.i.name, "cons") != 0)
+ return NULL;
+ if (cadddr(o))
+ return error("multiple arguments");
+ return cons(eval(cadr(o)), eval(caddr(o)));
+}
+
+static struct object *
dodiff(struct object *o, struct object *n)
{
struct object *arg;