From 6b8812f46792b85a9d6318d4b93e7bd1da695dde Mon Sep 17 00:00:00 2001 From: Christian Barthel Date: Thu, 4 Jul 2019 16:09:47 +0200 Subject: [PATCH] bind args and create newenv, eval function calls this commit adds the evaluation of user defined functions. --- tokenize.l | 166 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 135 insertions(+), 31 deletions(-) diff --git a/tokenize.l b/tokenize.l index e9a46e0..c853f5f 100644 --- a/tokenize.l +++ b/tokenize.l @@ -396,6 +396,7 @@ eval_nand(struct ast *a, struct env *e) struct ast * eval_add(struct ast *a, struct env *e) { + fprintf(stderr, "add?\n"); reassure(a != NULL && a->next != NULL && a->next->next != NULL && @@ -496,17 +497,22 @@ eval_internal_sym(struct ast *a, struct env *e) struct ast *l = make_ast(AST_LIST, NULL); struct ast *head = make_ast(AST_TOK, NULL); l->v.list = head; + l->next = a->next; head->v.token = a->v.token; + + + fprintf(stderr, "====\n"); + fprintf(stderr, "%d\n", a->v.token); + fprintf(stderr, "====\n"); + fprintf(stderr, "%d\n", a->type); + fprintf(stderr, "%s\n", a->v.token->v.str); + fprintf(stderr, "%d\n", a->v.token->next->type); + fprintf(stderr, "%d\n", a->v.token->next->next->type); + fprintf(stderr, "%s\n", a->v.token->next->next->v.str); + fprintf(stderr, "%d\n", a->v.token->next->next->next->type); + fprintf(stderr, "%d\n", a->v.token->next->next->next->next->type); + fprintf(stderr, "====\n"); return l; - - - /* fprintf(stderr, "%d\n", a->type); */ - /* fprintf(stderr, "%s\n", a->v.token->v.str); */ - /* fprintf(stderr, "%d\n", a->v.token->next->type); */ - - /* fprintf(stderr, "%d\n", a->v.token->next->next->type); */ - /* fprintf(stderr, "%d\n", a->v.token->next->next->next->type); */ - /* fprintf(stderr, "%d\n", a->v.token->next->next->next->next->type); */ } else if (strcmp(a->v.token->v.str, "if") == 0) { return eval_if(a, e); } else if (strcmp(a->v.token->v.str, "inv") == 0) { @@ -536,24 +542,125 @@ eval_defined_sym(struct ast *a, struct env *e) return var; } +struct env * +bind_args(struct token *args, + struct ast *fnargs_values, struct env *e) +{ + reassure(args && args->type == LPAR, + "%s: first argument", __func__); + args = args->next; + + struct ast *a = fnargs_values; + struct token *t = args; + fprintf(stderr, "args: %d\n", fnargs_values->type); + fprintf(stderr, "args: %d\n", fnargs_values->v.token->type); + struct env *newenv = (struct env*) + calloc(1, sizeof(struct env)); + newenv->name = strdup("__fn"); + newenv->parent = e; + + while (t != NULL && t->type != RPAR) { + fprintf(stderr, "args assign: %d, %s [%d]\n", + t->type, t->v.str, a->type); + reassure(t != NULL && + t->type == SYM && + t->v.str != NULL, + "%s: wrong args param found: %s", + __func__, t->v.str); + reassure(a != NULL && + (a->type == AST_TOK || a->type == AST_LIST), + "%s: arg=%s given, but no value present", + __func__, t->v.str); + + struct ast *new = eval(a, e); + fprintf(stderr, "evaluated: %d, %d (ast,token)\n", new->type, new->v.token->type); + append(newenv, make_env(t->v.str, new)); + + t = t->next; + a = a->next; + } + + reassure (t->type == RPAR, + "%s: args formulation suspicious: %d", + __func__, args->type); + reassure (a == NULL, + "%s: actual value given but no arg left", + __func__); + return newenv; +} + struct ast * -eval_defined_function(struct ast *a, struct env *e) +eval_fn_call(struct ast *a, struct env *e) { reassure((AST_TOK == a->type) && a->v.token->type == SYM, - "%s: expected SYM", __func__); + "%s: expected SYM, is: %d", + __func__, a->type); - fprintf(stderr, "lookup: %d\n", a->type); - fprintf(stderr, "lookup: %s\n", a->v.token->v.str); - struct ast *fn = lookup(e, a->v.token->v.str); - - fprintf(stderr, "type: %d\n", fn->type); - fprintf(stderr, "token p: %p\n", fn->v.token); - fprintf(stderr, "list p:%p\n", fn->v.list); + struct ast *fnargs_values = a->next; + reassure(fnargs_values != NULL, + "%s: expected RPAR or function args", __func__); + /* XXX fprintf(stderr, "eval args: %d\n", fnargs_values->v.token->type); */ + + char *fnstr = a->v.token->v.str; + struct ast *fn = lookup(e, fnstr); + fprintf(stderr, "_lookup: %s\n", fnstr); + reassure(fn != NULL && fn->type == AST_LIST, + "%s: lookup on `%s` failed", __func__, fnstr); + + struct ast *fn_head = fn->v.list; + struct ast *fn_body = fn->next->next; - fprintf(stderr, "list: nxt type: %d\n", fn->v.list->type); /* sym */ - fprintf(stderr, "list: nxt token type: %d\n", fn->v.list->v.token->type); /* sym */ - fprintf(stderr, "list: nxt token type: %s\n", fn->v.list->v.token->v.str); /* sym */ + fprintf(stderr, "fnbody: %d, %p\n", fn_body->type, fn_body->v.list); + fprintf(stderr, "fnbody: %d, %d\n", fn_body->v.list->type, fn_body->v.list->v.token->type); + fprintf(stderr, "fnbody: %s\n", fn_body->v.list->v.token->v.str); + + reassure(fn_body != NULL && fn_body->type == AST_LIST, + "%s: expected function body as list", __func__); + + reassure(fn_head != NULL && + fn_head->type == AST_TOK && + fn_head->v.token->type == SYM && + strcmp(fn_head->v.token->v.str, "lm") == 0, + "%s: expected #fn", __func__); + + struct token *fnargs = fn_head->v.token->next; + + reassure(fnargs != NULL && + fnargs->type == LPAR, + "%s: args expected to be a list", __func__); + + struct env *newenv = bind_args(fnargs, fnargs_values, e); + for (struct env *e = newenv; e; e=e->next) + fprintf(stderr, "e: %s\n", e->name); + + reassure(newenv != NULL, + "%s: setup for newenv failed", __func__); + + return eval(fn_body, newenv); + /* fnargs: (), (a), (a b), (a b c), ... */ + /* fprintf(stderr, "args: %d %s\n", fnargs->type, ""); */ + /* fprintf(stderr, "args: %d %s\n", fnargs->next->type, */ + /* fnargs->next->v.str); */ + /* fprintf(stderr, "args: %d %s\n", */ + /* fnargs->next->next->type, */ + /* fnargs->next->next->v.str */ + /* ); */ + /* fprintf(stderr, "args: %d %s\n", fnargs->next->next->next->type, ""); */ + + /* ((lm (x y z) (...)) 1 2 3) */ + + /* fprintf(stderr, "now evaluate and bind parameter arguments %p\n", fnargs); */ + /* fprintf(stderr, "args: %d %p\n", fnargs->type, fnargs->v.token); */ + /* fprintf(stderr, "args: %d %p\n", fnargs->v.token->next->type, fnargs->v.list); */ + + /* fprintf(stderr, "type: %d\n", fn->type); */ + /* fprintf(stderr, "token p: %p\n", fn->v.token); */ + /* fprintf(stderr, "list p:%p\n", fn->v.list); */ + + /* fprintf(stderr, "list: nxt type: %d\n", fn->v.list->type); /\* sym *\/ */ + /* fprintf(stderr, "list: nxt token type: %d\n", fn->v.list->v.token->type); /\* sym *\/ */ + /* fprintf(stderr, "list: nxt token type: %s\n", fn->v.list->v.token->v.str); /\* sym *\/ */ /* fprintf(stderr, "nxt tok p: %p\n", fn->list->v.token); /\* sym *\/ */ /* fprintf(stderr, "nxt list p: %s\n", fn->list->v.list); /\* sym *\/ */ @@ -562,18 +669,15 @@ eval_defined_function(struct ast *a, struct env *e) /* fprintf(stderr, "nxt tok p: %p\n", fn->next->v.token); /\* sym *\/ */ /* fprintf(stderr, "nxt list p: %s\n", fn->next->v.list); /\* sym *\/ */ - reassure(fn != NULL && - fn->type == AST_LIST && - fn->v.list != NULL && - fn->v.list->type == AST_TOK && - fn->v.list->v.token->type == SYM && - (strcmp(fn->v.list->v.token->v.str, "lm") == 0), "broken"); + /* reassure(fn != NULL && */ + /* fn->type == AST_LIST && */ + /* fn->v.list != NULL && */ + /* fn->v.list->type == AST_TOK && */ + /* fn->v.list->v.token->type == SYM && */ + /* (strcmp(fn->v.list->v.token->v.str, "lm") == 0), "broken"); */ /* fprintf(stderr, "type %d\n", a->type); */ /* fprintf(stderr, "type %s\n", a->v.list->v.token->v.str); */ - - a = a->next; /* skip "lm" */ - } struct ast * @@ -582,7 +686,7 @@ eval_list(struct ast *a, struct env *e) if (token_is_internal(a->v.list->v.token)) return eval_internal_sym(a->v.list, e); else - return eval_defined_function(a->v.list, e); + return eval_fn_call(a->v.list, e); } struct ast *