From 41bb75cea1821ad2b676fdbb4847ce5441f00f42 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 13 Nov 2019 14:35:26 -0500 Subject: evaluating default arguments --- cgen.c | 24 +++++++++++++++++++++--- main.c | 3 ++- test.toc | 9 ++++++++- types.c | 24 ++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/cgen.c b/cgen.c index 956fd83..0e27220 100644 --- a/cgen.c +++ b/cgen.c @@ -982,8 +982,14 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { break; case EXPR_CALL: { if (!cgen_expr_pre(g, e->call.fn)) return false; - arr_foreach(e->call.arg_exprs, Expression, arg) - if (!cgen_expr_pre(g, arg)) return false; + int i = 0; + bool *constant = e->call.fn->type.fn.constant; + arr_foreach(e->call.arg_exprs, Expression, arg) { + if (!constant || !constant[i]) { + if (!cgen_expr_pre(g, arg)) return false; + } + i++; + } if (cgen_uses_ptr(&e->type)) { e->call.c.id = g->ident_counter++; if (!cgen_type_pre(g, &e->type, e->where)) return false; @@ -1078,6 +1084,18 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { return false; break; case EXPR_VAL: + if (!cgen_val_pre(g, e->val, &e->type, e->where)) + return false; + if (!cgen_type_pre(g, &e->type, e->where)) return false; + e->val_c_id = g->ident_counter++; + cgen_write(g, " "); + cgen_ident_id(g, e->val_c_id); + if (!cgen_type_post(g, &e->type, e->where)) return false; + cgen_write(g, " = "); + if (!cgen_val(g, e->val, &e->type, e->where)) + return false; + cgen_write(g, ";"); + cgen_nl(g); break; case EXPR_LITERAL_INT: case EXPR_LITERAL_FLOAT: @@ -1399,7 +1417,7 @@ static bool cgen_expr(CGenerator *g, Expression *e) { cgen_ident_id(g, e->slice.c.id); break; case EXPR_VAL: - assert(!*"Value expressions cannot be cgenerated!!!"); + cgen_ident_id(g, e->val_c_id); break; } return true; diff --git a/main.c b/main.c index 1378718..a7a0888 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,9 @@ /* TODO: +evaluate default arguments +make sure they're only evaluated once compile time arguments + out parameters (in C) double check that val_get_ptr is being used everywhere it should be -evaluate default arguments compile-time arguments for out parameter functions compile-time arguments for functions returning tuples deal with x, y @= fn(x: int, y @ int){} diff --git a/test.toc b/test.toc index 8e52b1b..dda957a 100644 --- a/test.toc +++ b/test.toc @@ -22,15 +22,22 @@ puti @= fn(x: int) { // f.z += 43.2; // }; -f @= fn(x @ int) i: int { +f @= fn(x @ int = 3+5) i: int { i = x; }; +g @= fn(x, y : (int, int) = (3+5, 4+9)) i: int { + i = x + y; +}; + main @= fn() { puti(f(313)); puti(f(128)); puti(f(231)); puti(f(100+213)); + puti(f()); + puti(g()); + }; // b := bar(); diff --git a/types.c b/types.c index 00f72e8..dcfbfd8 100644 --- a/types.c +++ b/types.c @@ -254,6 +254,15 @@ static bool type_of_fn(Typer *tr, Expression *e, Type *t) { } } } + if (decl->flags & DECL_HAS_EXPR) { + Value val; + if (!eval_expr(tr->evalr, &decl->expr, &val)) { + info_print(decl->where, "Was trying to evaluate default arguments (which must be constants!)"); + return false; + } + decl->expr.kind = EXPR_VAL; + decl->expr.val = val; + } for (size_t i = 0; i < arr_len(decl->idents); i++) { Type *param_type = typer_arr_add(tr, &t->fn.types); *param_type = decl->type; @@ -1050,6 +1059,7 @@ static bool types_expr(Typer *tr, Expression *e) { arr_foreach(fn_decl->params, Declaration, param) { bool is_required = !(param->flags & DECL_HAS_EXPR); + long ident_idx = 0; arr_foreach(param->idents, Identifier, ident) { if (index == i) { if (is_required) { @@ -1058,9 +1068,18 @@ static bool types_expr(Typer *tr, Expression *e) { free(s); return false; } else { - new_args[i] = param->expr; + assert(param->expr.kind == EXPR_VAL); /* evaluated in type_of_fn */ + new_args[i].kind = EXPR_VAL; + new_args[i].flags = param->expr.flags; + new_args[i].type = param->type.kind == TYPE_TUPLE + ? param->type.tuple[ident_idx] + : param->type; + new_args[i].val = param->type.kind == TYPE_TUPLE + ? param->expr.val.tuple[ident_idx] + : param->expr.val; } } + ident_idx++; index++; } } @@ -1449,7 +1468,8 @@ static bool types_expr(Typer *tr, Expression *e) { t->tuple = NULL; arr_foreach(e->tuple, Expression, x) { Type *x_type = typer_arr_add(tr, &t->tuple); - types_expr(tr, x); + if (!types_expr(tr, x)) + return false; *x_type = x->type; } break; -- cgit v1.2.3