From 712dcfc93198786a92c1a80a61ad03129c895eb4 Mon Sep 17 00:00:00 2001 From: Christian Barthel Date: Sun, 7 Jul 2019 22:23:44 +0200 Subject: [PATCH] eval function calls, 2nd and improved attempt --- tokenize.l | 137 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 32 deletions(-) diff --git a/tokenize.l b/tokenize.l index b640a11..44bcf20 100644 --- a/tokenize.l +++ b/tokenize.l @@ -86,7 +86,7 @@ enum yytokentype { }; struct token* make_token(enum yytokentype, int, char*); -struct ast* eval(struct ast *a, struct env *e); +struct ast* eval(struct ast *a, struct env *e, struct env **w); int yylval; char *yystr; %} @@ -144,6 +144,10 @@ void debug_token(struct token *x, int indent) { for (int i = 0; i < indent; i++) putc(' ', stderr); + if (x == NULL) { + fprintf(stderr, "NULL TOKEN\n"); + return; + } fprintf(stderr, "%d: (%p)", x->type, x); if (x->type == NUM) fprintf(stderr, "%d @ %p", x->v.num, x); if (x->type == STR || x->type == SYM) @@ -308,11 +312,11 @@ lookup(struct env *e, char *name) if (e == NULL) return NULL; for (struct env *t = e; t != NULL; t = t->next) { - fprintf(stderr, "env: %s\n", t->name); + /* fprintf(stderr, "env: %s\n", t->name); */ if (strcmp(t->name, name) == 0) return t->a; } - fprintf(stderr, "====\n"); + //fprintf(stderr, "====\n"); return lookup(e->parent, name); } @@ -321,6 +325,7 @@ struct ast * eval_def(struct ast *a, struct env *e) { a = a->next; /* skip `def` */ + //debug_ast(a, 0); reassure(a->v.token->type == SYM, /* must be a symbol */ "%s: expected SYM, given: %d", __func__, a->v.token->type); @@ -345,7 +350,7 @@ eval_def(struct ast *a, struct env *e) "%s: %s already assigned in env=%p", __func__, new, e); - append(e, make_env(new, eval(a->next, e))); + append(e, make_env(new, eval(a->next, e, NULL))); reassure(a->next->next == NULL, "%s: ended with unexpected token", __func__); @@ -356,12 +361,13 @@ eval_def(struct ast *a, struct env *e) struct ast * eval_if(struct ast *a, struct env *e) { + //debug_ast(a, 0); a = a->next; reassure(a != NULL && a->next != NULL, "%s: unexpected NULL", __func__); - struct ast *condition = eval(a, e); + struct ast *condition = eval(a, e, NULL); reassure(condition != NULL && condition->type == AST_TOK && @@ -373,9 +379,9 @@ eval_if(struct ast *a, struct env *e) __func__); if (condition->v.token->v.num == 1) - return eval(a->next, e); + return eval(a->next, e, NULL); else - return eval(a->next->next, e); + return eval(a->next->next, e, NULL); } /* (nand ) -> BOOL */ @@ -388,8 +394,8 @@ eval_nand(struct ast *a, struct env *e) a->next->next->next == NULL, "%s: unexpected NULL", __func__); - struct ast *op1 = eval(a->next, e); - struct ast *op2 = eval(a->next->next, e); + struct ast *op1 = eval(a->next, e, NULL); + struct ast *op2 = eval(a->next->next, e, NULL); reassure(op1 != NULL && op1->type == AST_TOK && @@ -416,8 +422,8 @@ eval_add(struct ast *a, struct env *e) a->next->next->next == NULL, "%s: expected 2 operands", __func__); - struct ast *op1 = eval(a->next, e); - struct ast *op2 = eval(a->next->next, e); + struct ast *op1 = eval(a->next, e, NULL); + struct ast *op2 = eval(a->next->next, e, NULL); reassure(op1 != NULL && op1->type == AST_TOK && @@ -443,8 +449,8 @@ eval_lt(struct ast *a, struct env *e) a->next->next->next == NULL, "%s: expected 2 operands", __func__); - struct ast *op1 = eval(a->next, e); - struct ast *op2 = eval(a->next->next, e); + struct ast *op1 = eval(a->next, e, NULL); + struct ast *op2 = eval(a->next->next, e, NULL); reassure(op1 != NULL && op1->type == AST_TOK && @@ -468,7 +474,7 @@ eval_inv(struct ast *a, struct env *e) a->next != NULL && a->next->next == NULL, "%s: expected one argument", __func__); - struct ast *op = eval(a->next, e); + struct ast *op = eval(a->next, e, NULL); reassure(op != NULL && op->type == AST_TOK && op->v.token->type == NUM && @@ -488,7 +494,7 @@ eval_num2bool(struct ast *a, struct env *e) a->next != NULL && a->next->next == NULL, "%s: expected one operand", __func__); - struct ast *op = eval(a->next, e); + struct ast *op = eval(a->next, e, NULL); reassure(op != NULL && op->type == AST_TOK && op->v.token->type == NUM && @@ -501,17 +507,26 @@ eval_num2bool(struct ast *a, struct env *e) } struct ast * -eval_internal_sym(struct ast *a, struct env *e) +eval_internal_sym(struct ast *x, struct env *e) { + struct ast *a = x->v.list; if (strcmp(a->v.token->v.str, "def") == 0) return eval_def(a, e); else if (strcmp(a->v.token->v.str, "lm") == 0) { //new->v.token = a->v.token; + return x; struct ast *l = make_ast(AST_LIST, NULL); struct ast *head = make_ast(AST_TOK, NULL); l->v.list = head; l->next = a->next; + fprintf(stderr, "%p, %p\n", l->next, a->next); + l->next->next = a->next->next; + //debug_ast(l, 0); head->v.token = a->v.token; + //fprintf(stderr, "returning AST:\n"); + //fprintf(stderr, "------------------------\n"); + //debug_ast(l, 0); + //fprintf(stderr, "------------------------\n"); return l; } else if (strcmp(a->v.token->v.str, "if") == 0) { return eval_if(a, e); @@ -541,13 +556,13 @@ eval_defined_sym(struct ast *a, struct env *e) __func__, a->v.token->v.str); return var; } - +struct env *lastenv; struct env * bind_args(struct token *args, struct ast *fnargs_values, struct env *e) { reassure(args && args->type == LPAR, - "%s: first argument", __func__); + "%s: first argument: %d %s", __func__, args->type, args->v.str); args = args->next; struct ast *a = fnargs_values; @@ -557,6 +572,7 @@ bind_args(struct token *args, newenv->name = strdup("__fn"); newenv->parent = e; + lastenv = newenv; while (t != NULL && t->type != RPAR) { reassure(t != NULL && @@ -569,7 +585,7 @@ bind_args(struct token *args, "%s: arg=%s given, but no value present", __func__, t->v.str); - struct ast *new = eval(a, e); + struct ast *new = eval(a, e, NULL); append(newenv, make_env(t->v.str, new)); @@ -587,11 +603,44 @@ bind_args(struct token *args, } struct ast * -eval_fn_call(struct ast *a, struct env *e) +eval_fn_name(struct ast *a, struct env *e, struct env **w) +{ + if (a->type == AST_LIST) { + //fprintf(stderr, "eval list\n"); + //debug_ast(a, 0); + //reassure(0, "not implemented\n"); + //return eval(a, e, NULL); + return a; + } else if (a->type == AST_TOK) { + //fprintf(stderr, "eval token: %s\n", a->v.token->v.str); + struct ast *fn = lookup(e, a->v.token->v.str); + return eval(fn, e, NULL); + } +} + +struct ast * +eval_fn_call(struct ast *a, struct env *e, struct env **w) +{ + //fprintf(stderr, "~~~~~~~~~~~~~~~~~~~~~~~~ eval call\n"); + + struct ast *fn = eval_fn_name(a, e, NULL); + struct ast *fn_body = fn->v.list->next->next; + struct ast *fn_args = fn->v.list->next; + struct token *args_head = fn->v.list->v.token->next; + struct ast *fn_args_values = a->next; + //debug_ast(fn, 0); + + struct env *newenv = bind_args(args_head, fn_args_values, e); + return eval(fn_body, newenv, NULL); +} + +struct ast * +eval_fn_call_old(struct ast *a, struct env *e, struct env **w) { struct ast *fnargs_values; struct ast *fn_head; struct ast *fn_body; + struct env *wanted = NULL; fnargs_values = a->next; reassure(fnargs_values != NULL, @@ -605,10 +654,16 @@ eval_fn_call(struct ast *a, struct env *e) char *fnstr = a->v.token->v.str; struct ast *fn = lookup(e, fnstr); + debug_ast(fn, 0); reassure(fn != NULL && fn->type == AST_LIST, "%s: lookup on `%s` failed", __func__, fnstr); + /* struct ast *fn2 = eval(fn, e, &wanted); */ + /* fprintf(stderr, "===========\n"); */ + debug_ast(fn, 0); + /* fn_head = fn2->v.list; */ + /* fn_body = fn2->next->next; */ fn_head = fn->v.list; fn_body = fn->next->next; } else if (a->type == AST_LIST @@ -617,8 +672,8 @@ eval_fn_call(struct ast *a, struct env *e) fn_head = a->v.list; fn_body = a->v.list->next->next; } else { - /* xxx */ - struct ast *fn = eval(a, e); + /* */ + struct ast *fn = eval(a, e, &wanted); fn_head = fn->v.list; fn_body = fn->next->next; } @@ -639,26 +694,37 @@ eval_fn_call(struct ast *a, struct env *e) "%s: args expected to be a list", __func__); struct env *newenv = bind_args(fnargs, fnargs_values, e); + if (wanted != NULL) { + /* fprintf(stderr, "==lastenv\n"); */ + /* for (struct env *e = lastenv; e; e=e->next) */ + /* fprintf(stderr, "e: %s\n", e->name); */ - for (struct env *e = newenv; e; e=e->next) - fprintf(stderr, "e: %s\n", e->name); + /* fprintf(stderr, "==newenv:\n"); */ + /* for (struct env *e = newenv; e; e=e->next) */ + /* fprintf(stderr, "e: %s\n", e->name); */ + + newenv->parent = wanted; + } + if (w != NULL) { + *w = newenv; + } reassure(newenv != NULL, "%s: setup for newenv failed", __func__); - return eval(fn_body, newenv); + return eval(fn_body, newenv, NULL); } struct ast * -eval_list(struct ast *a, struct env *e) +eval_list(struct ast *a, struct env *e, struct env **w) { if (token_is_internal(a->v.list->v.token)) - return eval_internal_sym(a->v.list, e); + return eval_internal_sym(a, e); else - return eval_fn_call(a->v.list, e); + return eval_fn_call(a->v.list, e, w); } struct ast * -eval(struct ast *a, struct env *e) +eval(struct ast *a, struct env *e, struct env **w) { if (a == NULL) return NULL; @@ -678,7 +744,7 @@ eval(struct ast *a, struct env *e) a->v.list->v.token->type == SYM) || (a->v.list->type == AST_LIST), "%s: expected LIST or TOK", __func__); - return eval_list(a, e); + return eval_list(a, e, w); default: reassure(0, "%s: wrong AST Type", __func__); } @@ -689,7 +755,7 @@ void pr(struct ast *a) { if (a == NULL) { - fprintf(stderr, "nil %p\n", a); + //fprintf(stderr, "nil %p\n", a); return; } switch (a->type) { @@ -709,6 +775,13 @@ pr(struct ast *a) break; case AST_LIST: printf("#fn\n"); + struct token *t = a->v.list->v.token; + debug_ast(a, 0); + while (t != NULL) { + printf("%d ", t->type); + t = t->next; + } + putchar('\n'); break; default: err(1, "don't know how to print"); @@ -745,7 +818,7 @@ int main(void) env->name = "__llm"; while (1) - pr(eval(parse(read_form()), env)); + pr(eval(parse(read_form()), env, NULL)); return 0; }