distinguish function calls from sym evaluation

prepare function call handling: till now, i've
just eval'ed new tokens but i think that i have
to distinguish a function call from a symbol
evaluation.
This commit is contained in:
Christian Barthel 2019-06-30 23:10:17 +02:00
parent e718421f17
commit 97a04bd1ce
1 changed files with 32 additions and 11 deletions

View File

@ -161,6 +161,18 @@ 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_sym(struct token *t) {return t->type == SYM;}
int token_is_str(struct token *t) {return t->type == STR;} int token_is_str(struct token *t) {return t->type == STR;}
int token_is_bool(struct token *t) {return t->type == BOOL;} int token_is_bool(struct token *t) {return t->type == BOOL;}
int token_is_internal(struct token *t) {
if (strcmp(t->v.str, "def") == 0) return 1;
else if (strcmp(t->v.str, "lm") == 0) return 1;
else if (strcmp(t->v.str, "if") == 0) return 1;
else if (strcmp(t->v.str, "inv") == 0) return 1;
else if (strcmp(t->v.str, "add") == 0) return 1;
else if (strcmp(t->v.str, "lt") == 0) return 1;
else if (strcmp(t->v.str, "nand") == 0) return 1;
else if (strcmp(t->v.str, "q") == 0) return 1;
else return 0;
}
/* upon parsing a list of tokens like: /* upon parsing a list of tokens like:
* "(" -> "def" -> "(" -> "b" -> ")" -> "c" -> ")" * "(" -> "def" -> "(" -> "b" -> ")" -> "c" -> ")"
@ -351,7 +363,7 @@ eval_inv(struct ast *a, struct env *e)
} }
struct ast * struct ast *
eval_sym(struct ast *a, struct env *e) eval_internal_sym(struct ast *a, struct env *e)
{ {
if (strcmp(a->v.token->v.str, "def") == 0) if (strcmp(a->v.token->v.str, "def") == 0)
return eval_def(a, e); return eval_def(a, e);
@ -368,18 +380,18 @@ eval_sym(struct ast *a, struct env *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;
} 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; return NULL;
} }
struct ast *
eval_defined_sym(struct ast *a, struct env *e)
{
struct ast *var = lookup(e, a->v.token->v.str);
assert(var != NULL); /* variable found? */
return var;
}
struct ast * struct ast *
eval(struct ast *a, struct env *e) eval(struct ast *a, struct env *e)
{ {
@ -390,13 +402,22 @@ eval(struct ast *a, struct env *e)
if (token_is_num(a->v.token)) 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 (token_is_sym(a->v.token))
return eval_sym(a, e); return eval_defined_sym(a, e);
else if (token_is_str(a->v.token)) else if (token_is_str(a->v.token))
return make_ast(AST_TOK, a->v.token); return make_ast(AST_TOK, a->v.token);
else if (token_is_bool(a->v.token)) else if (token_is_bool(a->v.token))
return make_ast(AST_TOK, a->v.token); return make_ast(AST_TOK, a->v.token);
case AST_LIST: case AST_LIST:
return eval(a->v.list, e); /* XXX either it's an internal function, a custom defined function
* or an lambda expression ((lm (x) (* x x)) 2) */
assert ((a->v.list->type == AST_TOK &&
a->v.list->v.token->type == SYM) ||
(a->v.list->type == AST_LIST));
if (token_is_internal(a->v.list->v.token))
return eval_internal_sym(a->v.list, e);
/* else if ((r = eval_defined_function(a->v.list, e)) != NULL) */
/* return r; */
assert(0);
default: default:
fprintf(stderr, "%d\n", a->type); fprintf(stderr, "%d\n", a->type);
assert(0); assert(0);