iris

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

commit 9539419a2015c425987e74556e2dbf94e1887af5
parent 9c7e1299c8ab117b928e3b53570b33fcdbd8c735
Author: sin <sin@2f30.org>
Date:   Wed, 14 May 2014 13:46:29 +0100

Parse pairs/lists

Diffstat:
Mlexer.c | 13+++++++++++++
Mlexer.h | 1+
Mparser.c | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/lexer.c b/lexer.c @@ -30,6 +30,8 @@ static enum state state; static char *s; static char *e; static char buf[MAXTOKSIZE]; +static struct tok lasttok; +static int pendingtok; static int delim(int c) @@ -44,6 +46,10 @@ gettok(FILE *in) struct tok tok; int c; + if (pendingtok == 1) { + pendingtok = 0; + return lasttok; + } again: state = SSe; s = e = buf; @@ -240,3 +246,10 @@ lexeme(struct tok *t) return strdup(t->s); return strndup(t->s, t->e - t->s); } + +void +pushbacktok(struct tok t) +{ + lasttok = t; + pendingtok = 1; +} diff --git a/lexer.h b/lexer.h @@ -21,3 +21,4 @@ struct tok { struct tok gettok(FILE *fp); char *lexeme(struct tok *); +void pushbacktok(struct tok); diff --git a/parser.c b/parser.c @@ -16,6 +16,8 @@ enum objtype { ONumber, OCharacter, OString, + OEmptylist, + OPair, }; struct object { @@ -49,6 +51,11 @@ struct object { struct { char *s; } s; + /* pair */ + struct { + struct object *car; + struct object *cdr; + } p; } d; }; @@ -135,6 +142,52 @@ string(char *s) return o; } +static struct object * +emptylist(void) +{ + struct object *o; + + o = newobject(); + o->type = OEmptylist; + return o; +} + +static struct object * +cons(struct object *car, struct object *cdr) +{ + struct object *o; + + o = newobject(); + o->type = OPair; + o->d.p.car = car; + o->d.p.cdr = cdr; + return o; +} + +static struct object * +pair(FILE *in) +{ + struct object *car, *cdr; + struct tok t; + + t = gettok(in); + if (t.type == TRparen) + return emptylist(); + pushbacktok(t); + car = sexpression(in); + t = gettok(in); + if (t.type == TDot) { + cdr = sexpression(in); + t = gettok(in); + if (t.type != TRparen) + return error("missing right parenthesis"); + return cons(car, cdr); + } + pushbacktok(t); + cdr = pair(in); + return cons(car, cdr); +} + struct object * sexpression(FILE *in) { @@ -161,6 +214,8 @@ sexpression(FILE *in) return character(l[2]); case TString: return string(l); + case TLparen: + return pair(in); default: return error("unhandled token"); } @@ -182,6 +237,27 @@ eval(struct object *o) return o; } +static void +printpair(struct object *o) +{ + struct object *car, *cdr; + + car = o->d.p.car; + cdr = o->d.p.cdr; + print(car); + if (cdr->type == OPair) { + putchar(' '); + printpair(cdr); + } else if (cdr->type == OEmptylist) { + return; + } else { + putchar(' '); + putchar('.'); + putchar(' '); + print(cdr); + } +} + void print(struct object *o) { @@ -204,5 +280,13 @@ print(struct object *o) case OString: printf("%s", o->d.s.s); break; + case OEmptylist: + printf("()"); + break; + case OPair: + putchar('('); + printpair(o); + putchar(')'); + break; } }