iris

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

commit 97989d0dba5a1616b7ddd0ef5509174970c4e80a
parent 7bc0a99f392960959c86c3dced5632973a5cc28c
Author: sin <sin@2f30.org>
Date:   Fri, 16 May 2014 15:09:28 +0100

Add lt/gt/eq

Diffstat:
Mparser.c | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 97 insertions(+), 10 deletions(-)

diff --git a/parser.c b/parser.c @@ -75,7 +75,10 @@ static struct object *evalset(struct object *); /* primitive procedures */ static struct object *evalboolean(struct object *); static struct object *evaldiff(struct object *); +static struct object *evaleq(struct object *); +static struct object *evalgt(struct object *); static struct object *evalinteger(struct object *); +static struct object *evallt(struct object *); static struct object *evalnull(struct object *); static struct object *evalplus(struct object *); @@ -98,7 +101,10 @@ struct { } procs[] = { { .name = "boolean", .fn = evalboolean }, { .name = "diff", .fn = evaldiff }, + { .name = "eq", .fn = evaleq }, + { .name = "gt", .fn = evalgt }, { .name = "integer", .fn = evalinteger }, + { .name = "lt", .fn = evallt }, { .name = "null", .fn = evalnull }, { .name = "plus", .fn = evalplus }, }; @@ -332,13 +338,13 @@ evaldefine(struct object *o) if (car(o)->type != OIdentifier || strcmp(car(o)->d.i.name, "define") != 0) return NULL; + if (cadddr(o)) + return error("multiple arguments"); var = cadr(o); if (var->type != OIdentifier) return error("expected identifier"); if (!caddr(o)) return error("expected sexpression"); - if (cadddr(o)) - return error("multiple arguments"); val = eval(caddr(o)); if (val->type == OError) return val; @@ -394,6 +400,8 @@ evalset(struct object *o) if (car(o)->type != OIdentifier || strcmp(car(o)->d.i.name, "set") != 0) return NULL; + if (cadddr(o)) + return error("multiple arguments"); var = cadr(o); if (var->type != OIdentifier) return error("expected identifier"); @@ -401,8 +409,6 @@ evalset(struct object *o) return error("unbound identifier"); if (!caddr(o)) return error("expected sexpression"); - if (cadddr(o)) - return error("multiple arguments"); val = eval(caddr(o)); if (val->type == OError) return val; @@ -420,11 +426,11 @@ evalboolean(struct object *o) if (car(o)->type != OIdentifier || strcmp(car(o)->d.i.name, "boolean") != 0) return NULL; + if (caddr(o)) + return error("multiple arguments"); arg = eval(cadr(o)); if (arg->type == OError) return arg; - if (caddr(o)) - return error("multiple arguments"); if (arg->type == OBoolean) return boolean(true); return boolean(false); @@ -469,6 +475,60 @@ evaldiff(struct object *o) } static struct object * +evaleq(struct object *o) +{ + struct object *arg1, *arg2; + + if (o->type != OPair) + return NULL; + if (car(o)->type != OIdentifier || + strcmp(car(o)->d.i.name, "eq") != 0) + return NULL; + if (cadddr(o)) + return error("multiple arguments"); + arg1 = eval(cadr(o)); + if (arg1->type == OError) + return arg1; + if (arg1->type != OInteger) + return error("expected integer"); + arg2 = eval(caddr(o)); + if (arg2->type == OError) + return arg2; + if (arg2->type != OInteger) + return error("expected integer"); + if (arg1->d.n.v == arg2->d.n.v) + return boolean(true); + return boolean(false); +} + +static struct object * +evalgt(struct object *o) +{ + struct object *arg1, *arg2; + + if (o->type != OPair) + return NULL; + if (car(o)->type != OIdentifier || + strcmp(car(o)->d.i.name, "gt") != 0) + return NULL; + if (cadddr(o)) + return error("multiple arguments"); + arg1 = eval(cadr(o)); + if (arg1->type == OError) + return arg1; + if (arg1->type != OInteger) + return error("expected integer"); + arg2 = eval(caddr(o)); + if (arg2->type == OError) + return arg2; + if (arg2->type != OInteger) + return error("expected integer"); + if (arg1->d.n.v > arg2->d.n.v) + return boolean(true); + return boolean(false); +} + +static struct object * evalinteger(struct object *o) { struct object *arg; @@ -478,17 +538,44 @@ evalinteger(struct object *o) if (car(o)->type != OIdentifier || strcmp(car(o)->d.i.name, "integer") != 0) return NULL; + if (caddr(o)) + return error("multiple arguments"); arg = eval(cadr(o)); if (arg->type == OError) return arg; - if (caddr(o)) - return error("multiple arguments"); if (arg->type == OInteger) return boolean(true); return boolean(false); } static struct object * +evallt(struct object *o) +{ + struct object *arg1, *arg2; + + if (o->type != OPair) + return NULL; + if (car(o)->type != OIdentifier || + strcmp(car(o)->d.i.name, "lt") != 0) + return NULL; + if (cadddr(o)) + return error("multiple arguments"); + arg1 = eval(cadr(o)); + if (arg1->type == OError) + return arg1; + if (arg1->type != OInteger) + return error("expected integer"); + arg2 = eval(caddr(o)); + if (arg2->type == OError) + return arg2; + if (arg2->type != OInteger) + return error("expected integer"); + if (arg1->d.n.v < arg2->d.n.v) + return boolean(true); + return boolean(false); +} + +static struct object * evalnull(struct object *o) { struct object *arg; @@ -498,11 +585,11 @@ evalnull(struct object *o) if (car(o)->type != OIdentifier || strcmp(car(o)->d.i.name, "null") != 0) return NULL; + if (caddr(o)) + return error("multiple arguments"); arg = eval(cadr(o)); if (arg->type == OError) return arg; - if (caddr(o)) - return error("multiple arguments"); if (arg->type == OEmptylist) return boolean(true); return boolean(false);