split up eval code

This commit is contained in:
Christian Barthel 2019-06-29 12:25:01 +02:00
parent ca33a1096c
commit 6440eeec77

View File

@ -51,7 +51,8 @@ enum yytokentype {
QUOTE = 264 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; int yylval;
char *yystr; char *yystr;
%} %}
@ -95,7 +96,8 @@ debug_token(struct token *x, int indent) {
} }
void void
debug_ast(struct ast *a, int indent) { debug_ast(struct ast *a, int indent)
{
while (a) { while (a) {
for (int i = 0; i < indent; i++) putc(' ', stderr); 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" : 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; 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: /* upon parsing a list of tokens like:
* "(" -> "def" -> "(" -> "b" -> ")" -> "c" -> ")" * "(" -> "def" -> "(" -> "b" -> ")" -> "c" -> ")"
* care must be taken when entering a new sub-list (b), * care must be taken when entering a new sub-list (b),
@ -224,19 +230,11 @@ lookup(struct env *e, char *name)
return lookup(e->parent, name); return lookup(e->parent, name);
} }
/* (def a <ausdruck>) */
struct ast * struct ast *
eval(struct ast *a, struct env *e) eval_def(struct ast *a, struct env *e)
{ {
if (a == NULL) return NULL; a = a->next; /* skrip `def` */
if (a->type == AST_TOK) {
if (a->v.token->type == NUM) {
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 && assert((a->next->type == AST_TOK &&
a->next->v.token->type== STR) || a->next->v.token->type== STR) ||
(a->next->type == AST_TOK && (a->next->type == AST_TOK &&
@ -244,11 +242,17 @@ eval(struct ast *a, struct env *e)
(a->next->type == AST_LIST) || (a->next->type == AST_LIST) ||
(a->next->type == AST_TOK && (a->next->type == AST_TOK &&
a->next->v.token->type== SYM)); a->next->v.token->type== SYM));
append(e, make_env(a->v.token->v.str, eval(a->next, e))); append(e, make_env(a->v.token->v.str, eval(a->next, e)));
assert(a->next->next == NULL);
return NULL; 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) { /* (add <ausdruck::NUM> <audsruck::NUM> */
struct ast *
eval_add(struct ast *a, struct env *e)
{
assert (a != NULL && assert (a != NULL &&
a->next != NULL && a->next != NULL &&
a->next->next != NULL && a->next->next != NULL &&
@ -268,6 +272,17 @@ eval(struct ast *a, struct env *e)
op1->v.token->v.num + op1->v.token->v.num +
op2->v.token->v.num, op2->v.token->v.num,
NULL)); 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) { } else if (strcmp(a->v.token->v.str, "q") == 0) {
//return make_ast(AST_QUOTE, a->next); //return make_ast(AST_QUOTE, a->next);
return a->next; return a->next;
@ -280,12 +295,25 @@ eval(struct ast *a, struct env *e)
/* XXX: nand, eq, streq, symeq, add, sub, div, mul, /* XXX: nand, eq, streq, symeq, add, sub, div, mul,
* mod, lt, numeq, num2bool * mod, lt, numeq, num2bool
*/ */
return NULL;
}
} else if (a->v.token->type == STR) struct ast *
eval(struct ast *a, struct env *e)
{
if (a == NULL) return NULL;
switch (a->type) {
case AST_TOK:
if (token_is_num(a->v.token))
return make_ast(AST_TOK, a->v.token); return make_ast(AST_TOK, a->v.token);
} else if (a->type == AST_LIST) { 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);
case AST_LIST:
return eval(a->v.list, e); return eval(a->v.list, e);
} else { default:
fprintf(stderr, "%d\n", a->type); fprintf(stderr, "%d\n", a->type);
assert(0); assert(0);
} }