commit 8c1168fc1c6d93116ce70843e8e2f06e34ec18d5
parent 1f730e0a33a4821070b539c6ccfecbbbd47eb18f
Author: sin <sin@2f30.org>
Date: Fri, 16 May 2014 13:16:42 +0100
Add integer type predicate
Diffstat:
4 files changed, 53 insertions(+), 31 deletions(-)
diff --git a/debug.c b/debug.c
@@ -25,8 +25,8 @@ printtok(struct tok *t)
case TBoolean:
printf("token: boolean, value: '%s'", l);
break;
- case TNumber:
- printf("token number, value: '%s'", l);
+ case TInteger:
+ printf("token integer, value: '%s'", l);
break;
case TCharacter:
printf("token character, value: '%s'", l);
diff --git a/lexer.c b/lexer.c
@@ -12,8 +12,8 @@ enum state {
SIdentifier,
SProbable_Boolean,
SBoolean,
- SNumber,
- SSigned_Number,
+ SInteger,
+ SSigned_Integer,
SProbable_Character,
SCharacter,
SProbable_String,
@@ -65,9 +65,9 @@ again:
else if (*e == '#')
state = SProbable_Boolean;
else if (isdigit(*e) != 0)
- state = SNumber;
+ state = SInteger;
else if (*e == '-' || *e == '+')
- state = SSigned_Number;
+ state = SSigned_Integer;
else if (*e == '"')
state = SProbable_String;
else if (*e == '(')
@@ -122,9 +122,9 @@ again:
tok.s = "missing delimiter after boolean";
tok.e = NULL;
return tok;
- case SNumber:
+ case SInteger:
if (delim(*e) != 0) {
- tok.type = TNumber;
+ tok.type = TInteger;
tok.s = s;
tok.e = e;
ungetc(*e, in);
@@ -132,19 +132,19 @@ again:
}
if (isdigit(*e) == 0) {
tok.type = TError;
- tok.s = "not a number";
+ tok.s = "not a integer";
tok.e = NULL;
return tok;
}
break;
- case SSigned_Number:
+ case SSigned_Integer:
if (isdigit(*e) == 0) {
tok.type = TError;
- tok.s = "not a number";
+ tok.s = "not a integer";
tok.e = NULL;
return tok;
}
- state = SNumber;
+ state = SInteger;
break;
case SProbable_Character:
if (isalpha(*e) != 0) {
diff --git a/lexer.h b/lexer.h
@@ -4,7 +4,7 @@ enum toktype {
TEof = -1,
TIdentifier,
TBoolean,
- TNumber,
+ TInteger,
TCharacter,
TString,
TLparen,
diff --git a/parser.c b/parser.c
@@ -13,7 +13,7 @@ enum objtype {
OEof = -1,
OIdentifier,
OBoolean,
- ONumber,
+ OInteger,
OCharacter,
OString,
OEmptylist,
@@ -40,7 +40,7 @@ struct object {
struct {
bool v;
} b;
- /* number */
+ /* integer */
struct {
long v;
} n;
@@ -75,6 +75,7 @@ static struct object *evalset(struct object *);
/* primitive procedures */
static struct object *evalboolean(struct object *);
static struct object *evaldiff(struct object *);
+static struct object *evalinteger(struct object *);
static struct object *evalnull(struct object *);
static struct object *evalplus(struct object *);
@@ -96,9 +97,10 @@ struct {
struct object *(*fn)(struct object *);
} procs[] = {
{ .name = "boolean", .fn = evalboolean },
- { .name = "diff", .fn = evaldiff },
- { .name = "null", .fn = evalnull },
- { .name = "plus", .fn = evalplus },
+ { .name = "diff", .fn = evaldiff },
+ { .name = "integer", .fn = evalinteger },
+ { .name = "null", .fn = evalnull },
+ { .name = "plus", .fn = evalplus },
};
static struct object *
@@ -152,12 +154,12 @@ boolean(bool v)
}
static struct object *
-number(long v)
+integer(long v)
{
struct object *o;
o = newobject();
- o->type = ONumber;
+ o->type = OInteger;
o->d.n.v = v;
return o;
}
@@ -260,8 +262,8 @@ sexpression(FILE *in)
case TBoolean:
/* #t or #f */
return boolean(l[1] == 't' ? true : false);
- case TNumber:
- return number(strtol(l, 0, 10));
+ case TInteger:
+ return integer(strtol(l, 0, 10));
case TCharacter:
/* #\c */
return character(l[2]);
@@ -438,8 +440,8 @@ dodiff(struct object *o, struct object *n)
otmp = eval(car(o));
if (otmp->type == OError)
return otmp;
- if (otmp->type != ONumber)
- return error("expected number");
+ if (otmp->type != OInteger)
+ return error("expected integer");
n->d.n.v -= otmp->d.n.v;
return dodiff(cdr(o), n);
}
@@ -457,8 +459,8 @@ evaldiff(struct object *o)
n = eval(cadr(o));
if (n->type == OError)
return n;
- if (n->type != ONumber)
- return error("expected number");
+ if (n->type != OInteger)
+ return error("expected integer");
if (!caddr(o)) {
n->d.n.v *= -1;
return n;
@@ -467,6 +469,26 @@ evaldiff(struct object *o)
}
static struct object *
+evalinteger(struct object *o)
+{
+ struct object *arg;
+
+ if (o->type != OPair)
+ return NULL;
+ if (car(o)->type != OIdentifier ||
+ strcmp(car(o)->d.i.s, "integer") != 0)
+ return NULL;
+ 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 *
evalnull(struct object *o)
{
struct object *arg;
@@ -496,8 +518,8 @@ doplus(struct object *o, struct object *n)
otmp = eval(car(o));
if (otmp->type == OError)
return otmp;
- if (otmp->type != ONumber)
- return error("expected number");
+ if (otmp->type != OInteger)
+ return error("expected integer");
n->d.n.v += otmp->d.n.v;
return doplus(cdr(o), n);
}
@@ -510,7 +532,7 @@ evalplus(struct object *o)
if (car(o)->type != OIdentifier ||
strcmp(car(o)->d.i.s, "plus") != 0)
return NULL;
- return doplus(cdr(o), number(0));
+ return doplus(cdr(o), integer(0));
}
struct object *
@@ -524,7 +546,7 @@ eval(struct object *o)
case OError:
case OEof:
case OBoolean:
- case ONumber:
+ case OInteger:
case OCharacter:
case OString:
return o;
@@ -586,7 +608,7 @@ print(struct object *o)
case OBoolean:
printf("#%c", o->d.b.v == false ? 'f' : 't');
break;
- case ONumber:
+ case OInteger:
printf("%ld", o->d.n.v);
break;
case OCharacter: