diff options
-rw-r--r-- | eval.c | 27 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | parse.c | 5 | ||||
-rw-r--r-- | scope.c | 15 | ||||
-rw-r--r-- | test.toc | 13 | ||||
-rw-r--r-- | types.c | 10 |
6 files changed, 59 insertions, 14 deletions
@@ -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; } @@ -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 @@ -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; @@ -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); +} @@ -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 @@ -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; |