From 6440eeec7755aa288879f86b1342c92597069d35 Mon Sep 17 00:00:00 2001 From: Christian Barthel Date: Sat, 29 Jun 2019 12:25:01 +0200 Subject: [PATCH] split up eval code --- tokenize.l | 142 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 57 deletions(-) diff --git a/tokenize.l b/tokenize.l index f08cccc..0f01fee 100644 --- a/tokenize.l +++ b/tokenize.l @@ -51,7 +51,8 @@ enum yytokentype { QUOTE = 264 }; -struct token *make_token(enum yytokentype, int, char*); +struct token* make_token(enum yytokentype, int, char*); +struct ast* eval(struct ast *a, struct env *e); int yylval; char *yystr; %} @@ -95,7 +96,8 @@ debug_token(struct token *x, int indent) { } void -debug_ast(struct ast *a, int indent) { +debug_ast(struct ast *a, int indent) +{ while (a) { for (int i = 0; i < indent; i++) putc(' ', stderr); fprintf(stderr, "AST: %s,a=%p,list=%p,token=%p,next=%p", (a->type == AST_TOK) ? "AST_TOK" : @@ -155,6 +157,10 @@ make_env(char *name, struct ast *a) return e; } +int token_is_num(struct token *t) {return t->type == NUM;} +int token_is_sym(struct token *t) {return t->type == SYM;} +int token_is_str(struct token *t) {return t->type == STR;} + /* upon parsing a list of tokens like: * "(" -> "def" -> "(" -> "b" -> ")" -> "c" -> ")" * care must be taken when entering a new sub-list (b), @@ -224,68 +230,90 @@ lookup(struct env *e, char *name) return lookup(e->parent, name); } +/* (def a ) */ +struct ast * +eval_def(struct ast *a, struct env *e) +{ + a = a->next; /* skrip `def` */ + assert((a->next->type == AST_TOK && + a->next->v.token->type== STR) || + (a->next->type == AST_TOK && + a->next->v.token->type == NUM) || + (a->next->type == AST_LIST) || + (a->next->type == AST_TOK && + a->next->v.token->type== SYM)); + + append(e, make_env(a->v.token->v.str, eval(a->next, e))); + + assert(a->next->next == NULL); + return NULL; +} + +/* (add */ +struct ast * +eval_add(struct ast *a, struct env *e) +{ + assert (a != NULL && + a->next != NULL && + a->next->next != NULL && + a->next->next->next == NULL); + + struct ast *op1 = eval(a->next, e); + struct ast *op2 = eval(a->next->next, e); + + assert (op1 != NULL && + op1->type == AST_TOK && + op1->v.token->type == NUM && + op2 != NULL && + op2->type == AST_TOK && + op2->v.token->type == NUM); + return make_ast(AST_TOK, + make_token(NUM, + op1->v.token->v.num + + op2->v.token->v.num, + NULL)); +} + +struct ast * +eval_sym(struct ast *a, struct env *e) +{ + if (strcmp(a->v.token->v.str, "def") == 0) + return eval_def(a, e); + else if (strcmp(a->v.token->v.str, "lm") == 0) { + } else if (strcmp(a->v.token->v.str, "if") == 0) { + } else if (strcmp(a->v.token->v.str, "add") == 0) { + return eval_add(a, e); + } else if (strcmp(a->v.token->v.str, "q") == 0) { + //return make_ast(AST_QUOTE, a->next); + return a->next; + } else { + // fprintf(stderr, "Lookup: %s\n", a->v.token->v.str); + struct ast *var = lookup(e, a->v.token->v.str); + assert(var != NULL); /* variable found? */ + return var; + } + /* XXX: nand, eq, streq, symeq, add, sub, div, mul, + * mod, lt, numeq, num2bool + */ + return NULL; +} + struct ast * eval(struct ast *a, struct env *e) { if (a == NULL) return NULL; - - if (a->type == AST_TOK) { - if (a->v.token->type == NUM) { + + switch (a->type) { + case AST_TOK: + if (token_is_num(a->v.token)) return make_ast(AST_TOK, a->v.token); - } - else if (a->v.token->type == SYM) { - fprintf(stderr, "process: %s\n", a->v.token->v.str); - if (strcmp(a->v.token->v.str, "def") == 0) { - a = a->next; - assert((a->next->type == AST_TOK && - a->next->v.token->type== STR) || - (a->next->type == AST_TOK && - a->next->v.token->type == NUM) || - (a->next->type == AST_LIST) || - (a->next->type == AST_TOK && - a->next->v.token->type== SYM)); - append(e, make_env(a->v.token->v.str, eval(a->next, e))); - return NULL; - } else if (strcmp(a->v.token->v.str, "lm") == 0) { - } else if (strcmp(a->v.token->v.str, "if") == 0) { - } else if (strcmp(a->v.token->v.str, "add") == 0) { - assert (a != NULL && - a->next != NULL && - a->next->next != NULL && - a->next->next->next == NULL); - - struct ast *op1 = eval(a->next, e); - struct ast *op2 = eval(a->next->next, e); - - assert (op1 != NULL && - op1->type == AST_TOK && - op1->v.token->type == NUM && - op2 != NULL && - op2->type == AST_TOK && - op2->v.token->type == NUM); - return make_ast(AST_TOK, - make_token(NUM, - op1->v.token->v.num + - op2->v.token->v.num, - NULL)); - } else if (strcmp(a->v.token->v.str, "q") == 0) { - //return make_ast(AST_QUOTE, a->next); - return a->next; - } else { - // fprintf(stderr, "Lookup: %s\n", a->v.token->v.str); - struct ast *var = lookup(e, a->v.token->v.str); - assert(var != NULL); /* variable found? */ - return var; - } - /* XXX: nand, eq, streq, symeq, add, sub, div, mul, - * mod, lt, numeq, num2bool - */ - - } else if (a->v.token->type == STR) + else if (token_is_sym(a->v.token)) + return eval_sym(a, e); + else if (token_is_str(a->v.token)) return make_ast(AST_TOK, a->v.token); - } else if (a->type == AST_LIST) { + case AST_LIST: return eval(a->v.list, e); - } else { + default: fprintf(stderr, "%d\n", a->type); assert(0); }