iris

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

commit 30bcc78313a2fd2e676ad14f5a62bd6450ec117f
parent 489b9ef2bdc8f84fa6f30e4f84eea475847d8506
Author: sin <sin@2f30.org>
Date:   Wed, 14 May 2014 15:59:43 +0100

Add rudimentary parsing for self-evaluating objects

Diffstat:
Mparser.c | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mparser.h | 13++++++++++++-
Mrepl.c | 22++++++----------------
3 files changed, 176 insertions(+), 17 deletions(-)

diff --git a/parser.c b/parser.c @@ -2,6 +2,8 @@ #include <stdbool.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> +#include "lexer.h" #include "parser.h" struct object * @@ -14,3 +16,159 @@ newobject(void) return NULL; return o; } + +struct object * +error(struct tok *t) +{ + struct object *o; + char *l; + + l = lexeme(t); + if (!l) + return NULL; + o = newobject(); + o->type = OError; + o->d.err.s = strdup(l); + free(l); + return o; +} + +struct object * +eof(struct tok *t) +{ + struct object *o; + char *l; + + l = lexeme(t); + if (!l) + return NULL; + o = newobject(); + o->type = OEof; + o->d.err.s = strdup(l); + free(l); + return o; +} + +struct object * +boolean(struct tok *t) +{ + struct object *o; + char *l; + + l = lexeme(t); + if (!l) + return NULL; + o = newobject(); + o->type = OBoolean; + if (l[1] == 'f') + o->d.b.v = false; + if (l[1] == 't') + o->d.b.v = true; + free(l); + return o; +} + +struct object * +number(struct tok *t) +{ + struct object *o; + char *l; + + l = lexeme(t); + if (!l) + return NULL; + o = newobject(); + o->type = ONumber; + o->d.c.v = strtol(l, 0, 10); + free(l); + return o; +} + +struct object * +character(struct tok *t) +{ + struct object *o; + char *l; + + l = lexeme(t); + if (!l) + return NULL; + o = newobject(); + o->type = OCharacter; + o->d.c.v = l[2]; + free(l); + return o; +} + +struct object * +string(struct tok *t) +{ + struct object *o; + char *l; + + l = lexeme(t); + if (!l) + return NULL; + o = newobject(); + o->type = OString; + o->d.s.s = strdup(l); + free(l); + return o; +} + +struct object * +sexpression(FILE *in) +{ + struct tok t; + + t = gettok(in); + + switch (t.type) { + case TEof: + return eof(&t); + case TError: + return error(&t); + case TBoolean: + return boolean(&t); + case TNumber: + return number(&t); + case TCharacter: + return character(&t); + case TString: + return string(&t); + } + return NULL; +} + +struct object * +eval(struct object *o) +{ + return o; +} + +void +print(struct object *o) +{ + if (!o) + return; + switch (o->type) { + case OError: + printf("%s\n", o->d.err.s); + break; + case OEof: + printf("%s\n", o->d.eof.s); + break; + case OBoolean: + printf("#%c\n", o->d.b.v == false ? 'f' : 't'); + break; + case ONumber: + printf("%ld\n", o->d.n.v); + break; + case OCharacter: + printf("#\\%c\n", o->d.c.v); + break; + case OString: + printf("%s\n", o->d.s.s); + break; + } +} diff --git a/parser.h b/parser.h @@ -1,7 +1,9 @@ /* See LICENSE file for copyright and license details. */ enum objtype { + OError = -2, + OEof = -1, OIdentifier, - OBool, + OBoolean, ONumber, OCharacter, OString, @@ -10,6 +12,12 @@ enum objtype { struct object { enum objtype type; union { + struct { + char *s; + } err; + struct { + char *s; + } eof; /* identifier */ struct { char *s; @@ -34,3 +42,6 @@ struct object { }; struct object *newobject(void); +struct object *sexpression(FILE *); +struct object *eval(struct object *); +void print(struct object *); diff --git a/repl.c b/repl.c @@ -1,24 +1,14 @@ /* See LICENSE file for copyright and license details. */ +#include <stdbool.h> #include <stdio.h> -#include "lexer.h" -#include "debug.h" - -static void -lexertest(FILE *in) -{ - struct tok tok; - - do { - tok = gettok(in); - printtok(&tok); - putchar('\n'); - fflush(stdout); - } while (tok.type != TEof && tok.type != TError); -} +#include "parser.h" int main(void) { - lexertest(stdin); + do { + print(eval(sexpression(stdin))); + } while (1); + /* not reachable */ return 0; }