bind args and create newenv, eval function calls
this commit adds the evaluation of user defined functions.
This commit is contained in:
parent
4759a61a80
commit
6b8812f467
166
tokenize.l
166
tokenize.l
|
@ -396,6 +396,7 @@ eval_nand(struct ast *a, struct env *e)
|
||||||
struct ast *
|
struct ast *
|
||||||
eval_add(struct ast *a, struct env *e)
|
eval_add(struct ast *a, struct env *e)
|
||||||
{
|
{
|
||||||
|
fprintf(stderr, "add?\n");
|
||||||
reassure(a != NULL &&
|
reassure(a != NULL &&
|
||||||
a->next != NULL &&
|
a->next != NULL &&
|
||||||
a->next->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 *l = make_ast(AST_LIST, NULL);
|
||||||
struct ast *head = make_ast(AST_TOK, NULL);
|
struct ast *head = make_ast(AST_TOK, NULL);
|
||||||
l->v.list = head;
|
l->v.list = head;
|
||||||
|
l->next = a->next;
|
||||||
head->v.token = a->v.token;
|
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;
|
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) {
|
} else if (strcmp(a->v.token->v.str, "if") == 0) {
|
||||||
return eval_if(a, e);
|
return eval_if(a, e);
|
||||||
} else if (strcmp(a->v.token->v.str, "inv") == 0) {
|
} 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;
|
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 *
|
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) &&
|
reassure((AST_TOK == a->type) &&
|
||||||
a->v.token->type == SYM,
|
a->v.token->type == SYM,
|
||||||
"%s: expected SYM", __func__);
|
"%s: expected SYM, is: %d",
|
||||||
|
__func__, a->type);
|
||||||
|
|
||||||
fprintf(stderr, "lookup: %d\n", a->type);
|
struct ast *fnargs_values = a->next;
|
||||||
fprintf(stderr, "lookup: %s\n", a->v.token->v.str);
|
reassure(fnargs_values != NULL,
|
||||||
struct ast *fn = lookup(e, a->v.token->v.str);
|
"%s: expected RPAR or function args", __func__);
|
||||||
|
/* XXX fprintf(stderr, "eval args: %d\n", fnargs_values->v.token->type); */
|
||||||
fprintf(stderr, "type: %d\n", fn->type);
|
|
||||||
fprintf(stderr, "token p: %p\n", fn->v.token);
|
char *fnstr = a->v.token->v.str;
|
||||||
fprintf(stderr, "list p:%p\n", fn->v.list);
|
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, "fnbody: %d, %p\n", fn_body->type, fn_body->v.list);
|
||||||
fprintf(stderr, "list: nxt token type: %d\n", fn->v.list->v.token->type); /* sym */
|
fprintf(stderr, "fnbody: %d, %d\n", fn_body->v.list->type, fn_body->v.list->v.token->type);
|
||||||
fprintf(stderr, "list: nxt token type: %s\n", fn->v.list->v.token->v.str); /* sym */
|
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 tok p: %p\n", fn->list->v.token); /\* sym *\/ */
|
||||||
/* fprintf(stderr, "nxt list p: %s\n", fn->list->v.list); /\* 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 tok p: %p\n", fn->next->v.token); /\* sym *\/ */
|
||||||
/* fprintf(stderr, "nxt list p: %s\n", fn->next->v.list); /\* sym *\/ */
|
/* fprintf(stderr, "nxt list p: %s\n", fn->next->v.list); /\* sym *\/ */
|
||||||
|
|
||||||
reassure(fn != NULL &&
|
/* reassure(fn != NULL && */
|
||||||
fn->type == AST_LIST &&
|
/* fn->type == AST_LIST && */
|
||||||
fn->v.list != NULL &&
|
/* fn->v.list != NULL && */
|
||||||
fn->v.list->type == AST_TOK &&
|
/* fn->v.list->type == AST_TOK && */
|
||||||
fn->v.list->v.token->type == SYM &&
|
/* fn->v.list->v.token->type == SYM && */
|
||||||
(strcmp(fn->v.list->v.token->v.str, "lm") == 0), "broken");
|
/* (strcmp(fn->v.list->v.token->v.str, "lm") == 0), "broken"); */
|
||||||
|
|
||||||
/* fprintf(stderr, "type %d\n", a->type); */
|
/* fprintf(stderr, "type %d\n", a->type); */
|
||||||
/* fprintf(stderr, "type %s\n", a->v.list->v.token->v.str); */
|
/* fprintf(stderr, "type %s\n", a->v.list->v.token->v.str); */
|
||||||
|
|
||||||
a = a->next; /* skip "lm" */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast *
|
struct ast *
|
||||||
|
@ -582,7 +686,7 @@ eval_list(struct ast *a, struct env *e)
|
||||||
if (token_is_internal(a->v.list->v.token))
|
if (token_is_internal(a->v.list->v.token))
|
||||||
return eval_internal_sym(a->v.list, e);
|
return eval_internal_sym(a->v.list, e);
|
||||||
else
|
else
|
||||||
return eval_defined_function(a->v.list, e);
|
return eval_fn_call(a->v.list, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ast *
|
struct ast *
|
||||||
|
|
Loading…
Reference in New Issue