From 6075f33768b3a160fa1a06e54253f9cd565241ec Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Tue, 8 Oct 2019 14:32:22 -0400 Subject: eval fn calling (eval is done./runv) --- .swp | Bin 0 -> 12288 bytes eval.c | 27 ++++++++++++++++++++++++++- main.c | 3 --- parse.c | 5 ++++- scope.c | 15 +++++++++++++++ test.toc | 13 ++++++++++++- types.c | 10 ++-------- 7 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 .swp diff --git a/.swp b/.swp new file mode 100644 index 0000000..3e60901 Binary files /dev/null and b/.swp differ diff --git a/eval.c b/eval.c index 7754f57..2613c28 100644 --- a/eval.c +++ b/eval.c @@ -771,6 +771,31 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { else v->ptr = err_calloc(1, compiler_sizeof(&e->new.type)); break; + case EXPR_CALL: { + Value fnv; + if (!eval_expr(ev, e->call.fn, &fnv)) + return false; + FnExpr *fn = fnv.fn; + /* set parameter declaration values */ + long arg = 0; + Declaration *params = fn->params; + fn_enter(fn); + arr_foreach(params, Declaration, p) { + arr_foreach(p->idents, Identifier, i) { + IdentDecl *id = ident_decl(*i); + Value *paramval = &id->val; + if (!eval_expr(ev, &e->call.arg_exprs[arg], paramval)) + return false; + id->flags |= IDECL_FLAG_HAS_VAL; + arg++; + } + } + if (!eval_block(ev, &fn->body, v)) { + fn_exit(fn); + return false; + } + fn_exit(fn); + } break; } return true; } @@ -786,7 +811,6 @@ static bool eval_decl(Evaluator *ev, Declaration *d) { long index = 0; arr_foreach(d->idents, Identifier, i) { IdentDecl *id = ident_decl(*i); - id->flags |= IDECL_FLAG_HAS_VAL; if (has_expr && d->expr.kind == EXPR_TUPLE) { id->val = val.tuple[index++]; } else if (!has_expr && d->type.kind == TYPE_ARR) { @@ -795,6 +819,7 @@ static bool eval_decl(Evaluator *ev, Declaration *d) { } else { id->val = val; } + id->flags |= IDECL_FLAG_HAS_VAL; } return true; } diff --git a/main.c b/main.c index 9024d1d..fef518a 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,5 @@ /* TODO: -fix double eval_expr problem -call fns at compile time -finish evaluator improve casting: do you really need "as"? fix void fn type re-do cgen diff --git a/parse.c b/parse.c index 0ee8b8a..a4a5b2b 100644 --- a/parse.c +++ b/parse.c @@ -670,7 +670,10 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { return false; if (t->token != end) { - tokr_err(t, "Direct function calling in an expression is not supported.\nYou can wrap the function in parentheses."); + if (token_is_kw(t->token, KW_LPAREN)) + tokr_err(t, "Direct function calling in an expression is not supported.\nYou can wrap the function in parentheses."); + else + tokr_err(t, "Expected end of expression."); return false; } return true; diff --git a/scope.c b/scope.c index 5d01c6f..8ecda21 100644 --- a/scope.c +++ b/scope.c @@ -54,3 +54,18 @@ static void block_exit(Block *b, Statement *stmts) { } } } + +/* does NOT enter function's block body */ +static void fn_enter(FnExpr *f) { + arr_foreach(f->params, Declaration, decl) + add_ident_decls(&f->body, decl); + arr_foreach(f->ret_decls, Declaration, decl) + add_ident_decls(&f->body, decl); +} + +static void fn_exit(FnExpr *f) { + arr_foreach(f->params, Declaration, decl) + remove_ident_decls(&f->body, decl); + arr_foreach(f->ret_decls, Declaration, decl) + remove_ident_decls(&f->body, decl); +} diff --git a/test.toc b/test.toc index 81dbee0..83f01d3 100644 --- a/test.toc +++ b/test.toc @@ -1,3 +1,14 @@ main @= fn() { - ASDF : [{x:[3]int; p, q := &x[0], &x[2]; *q = 3412; *q}]f32; + add3 @= fn(x : int, y : int, z : int) int { + x + y + z + }; + add2 @= fn(x : int, y : int) int { + x + y + }; + id @= fn(x : int) int { x }; + + a1 : [id(7)]int; + a2 : [add2(53, 3)]int; + a3 : [add3(3,1,2)]f32; + GHJK : [{x := 5; x}]f32; }; \ No newline at end of file diff --git a/types.c b/types.c index b23fbcd..98a47dd 100644 --- a/types.c +++ b/types.c @@ -423,16 +423,10 @@ static bool types_expr(Typer *tr, Expression *e) { tr->ret_type = t->fn.types[0]; } tr->can_ret = true; - arr_foreach(f->params, Declaration, decl) - add_ident_decls(&f->body, decl); - arr_foreach(f->ret_decls, Declaration, decl) - add_ident_decls(&f->body, decl); + fn_enter(f); bool block_success = true; block_success = types_block(tr, &e->fn.body); - arr_foreach(f->params, Declaration, decl) - remove_ident_decls(&f->body, decl); - arr_foreach(f->ret_decls, Declaration, decl) - remove_ident_decls(&f->body, decl); + fn_exit(f); if (!block_success) { success = false; goto fn_ret; -- cgit v1.2.3