iris

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

commit 60d4c2eb9824194b7c1b4a4dda537080f6e6ad25
parent 8dc3257f1cd68efd60176c8d7a51dec9cbae1e40
Author: sin <sin@2f30.org>
Date:   Fri,  9 May 2014 20:52:07 +0100

Use internal state variable to track the lexer's state

Diffstat:
Mlexer.c | 49++++++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 23 deletions(-)

diff --git a/lexer.c b/lexer.c @@ -58,7 +58,6 @@ struct tok gettok(struct lexerctx *ctx, const char *buf, size_t len) { struct tok tok; - enum state state = State_Se; char *tmp; if (ctx->ready == 0) { @@ -66,36 +65,36 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len) ctx->e = buf; ctx->ready = 1; } - + ctx->state = State_Se; while (ctx->e < &buf[len]) { - switch (state) { + switch (ctx->state) { case State_Se: if (*ctx->e == ' ' || *ctx->e == '\t' || *ctx->e == '\n') break; if (isalpha(*ctx->e) != 0) - state = State_Identifier; + ctx->state = State_Identifier; else if (*ctx->e == '#') - state = State_Probable_Boolean; + ctx->state = State_Probable_Boolean; else if (isdigit(*ctx->e) != 0) - state = State_Number; + ctx->state = State_Number; else if (*ctx->e == '-' || *ctx->e == '+') - state = State_Signed_Number; + ctx->state = State_Signed_Number; else if (*ctx->e == '"') - state = State_Probable_String; + ctx->state = State_Probable_String; else if (*ctx->e == '(') - state = State_Lparen; + ctx->state = State_Lparen; else if (*ctx->e == ')') - state = State_Rparen; + ctx->state = State_Rparen; else if (*ctx->e == '\'') - state = State_Quote; + ctx->state = State_Quote; else if (*ctx->e == '.') - state = State_Dot; + ctx->state = State_Dot; else if (*ctx->e == ';') - state = State_Comment; + ctx->state = State_Comment; else - state = State_Illegal_Input; - if (state != State_Se) + ctx->state = State_Illegal_Input; + if (ctx->state != State_Se) ctx->s = ctx->e; break; case State_Identifier: @@ -114,9 +113,9 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len) break; case State_Probable_Boolean: if (*ctx->e == 'f' || *ctx->e == 't') - state = State_Boolean; + ctx->state = State_Boolean; else if (*ctx->e == '\\') - state = State_Probable_Character; + ctx->state = State_Probable_Character; else { tok.type = Error; tok.s = "not a boolean or a character"; @@ -156,11 +155,11 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len) tok.e = NULL; return tok; } - state = State_Number; + ctx->state = State_Number; break; case State_Probable_Character: if (isalpha(*ctx->e) != 0) { - state = State_Character; + ctx->state = State_Character; } else { tok.type = Error; tok.s = "expected character constant"; @@ -182,7 +181,7 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len) break; case State_Probable_String: if (*ctx->e == '"') - state = String; + ctx->state = String; break; case State_String: tok.type = String; @@ -212,7 +211,7 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len) case State_Comment: tmp = strchr(ctx->s, '\n'); if (tmp) { - state = State_Se; + ctx->state = State_Se; ctx->s = tmp; } break; @@ -229,7 +228,6 @@ gettok(struct lexerctx *ctx, const char *buf, size_t len) } ctx->e++; } - tok.type = Eof; tok.s = "reached the end-of-file"; tok.e = NULL; @@ -241,9 +239,13 @@ initlexer(void) { struct lexerctx *ctx; - ctx = calloc(1, sizeof(*ctx)); + ctx = malloc(sizeof(*ctx)); if (!ctx) return NULL; + ctx->state = State_Se; + ctx->ready = 0; + ctx->s = NULL; + ctx->e = NULL; return ctx; } @@ -251,4 +253,5 @@ void resetlexer(struct lexerctx *ctx) { ctx->ready = 0; + ctx->state = State_Se; }