commit 97989d0dba5a1616b7ddd0ef5509174970c4e80a
parent 7bc0a99f392960959c86c3dced5632973a5cc28c
Author: sin <sin@2f30.org>
Date: Fri, 16 May 2014 15:09:28 +0100
Add lt/gt/eq
Diffstat:
M | parser.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);