commit 2a05ed0a3743603003afeb9f36fa5912bdb9c10d
parent 4db212d423da3639af21f77dce6bf2d897d8fcc3
Author: sin <sin@2f30.org>
Date: Thu, 15 May 2014 17:03:03 +0100
Add diff
Diffstat:
M | parser.c | | | 27 | +++++++++++++++++++++++++++ |
1 file changed, 27 insertions(+), 0 deletions(-)
diff --git a/parser.c b/parser.c
@@ -60,6 +60,7 @@ struct object {
};
static struct object *evaldefine(struct object *);
+static struct object *evaldiff(struct object *);
static struct object *evalif(struct object *);
static struct object *evalok(struct object *);
static struct object *evalplus(struct object *);
@@ -72,6 +73,7 @@ struct {
struct object *(*fn)(struct object *);
} builtins[] = {
{ .name = "define", .fn = evaldefine },
+ { .name = "diff", .fn = evaldiff },
{ .name = "if", .fn = evalif },
{ .name = "ok", .fn = evalok },
{ .name = "plus", .fn = evalplus },
@@ -324,6 +326,31 @@ evaldefine(struct object *o)
}
static struct object *
+dodiff(struct object *o, struct object *n)
+{
+ if (!car(o))
+ return n;
+ if (car(o)->type != ONumber)
+ return error("expected number");
+ n->d.n.v -= car(o)->d.n.v;
+ return dodiff(cdr(o), n);
+}
+
+static struct object *
+evaldiff(struct object *o)
+{
+ struct object *ocar;
+
+ if (o->type != OPair)
+ return NULL;
+ ocar = car(o);
+ if (ocar->type != OIdentifier ||
+ strcmp(ocar->d.i.s, "diff") != 0)
+ return NULL;
+ return dodiff(cdr(o), number(0));
+}
+
+static struct object *
evalif(struct object *o)
{
struct object *ocar;