split up eval code
This commit is contained in:
parent
ca33a1096c
commit
6440eeec77
142
tokenize.l
142
tokenize.l
|
@ -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,68 +230,90 @@ lookup(struct env *e, char *name)
|
||||||
return lookup(e->parent, name);
|
return lookup(e->parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (def a <ausdruck>) */
|
||||||
|
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 <ausdruck::NUM> <audsruck::NUM> */
|
||||||
|
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 *
|
struct ast *
|
||||||
eval(struct ast *a, struct env *e)
|
eval(struct ast *a, struct env *e)
|
||||||
{
|
{
|
||||||
if (a == NULL) return NULL;
|
if (a == NULL) return NULL;
|
||||||
|
|
||||||
if (a->type == AST_TOK) {
|
switch (a->type) {
|
||||||
if (a->v.token->type == NUM) {
|
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 (token_is_sym(a->v.token))
|
||||||
else if (a->v.token->type == SYM) {
|
return eval_sym(a, e);
|
||||||
fprintf(stderr, "process: %s\n", a->v.token->v.str);
|
else if (token_is_str(a->v.token))
|
||||||
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)
|
|
||||||
return make_ast(AST_TOK, 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);
|
return eval(a->v.list, e);
|
||||||
} else {
|
default:
|
||||||
fprintf(stderr, "%d\n", a->type);
|
fprintf(stderr, "%d\n", a->type);
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue