From 76f800ae81d5530e2b07a1edf97e57710bac0d13 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Mon, 25 Nov 2019 09:28:02 -0500 Subject: fixed multiple idents in one param decl --- main.c | 4 ---- parse.c | 9 +++++++++ test.toc | 8 +++----- types.c | 17 +++++++++++++++-- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 6be7848..cfb010e 100644 --- a/main.c +++ b/main.c @@ -1,9 +1,5 @@ /* TODO: -get fn(x, y@ int) to work, you'll need to add back in tuple parameters (one decl multiple values) - -can we get the instance before calling type_of_fn? - get fn(x: int) y := x {} to work don't cgen decls etc. in parameter initializers (hey we have a parameter flag now) check for leaks diff --git a/parse.c b/parse.c index 11a698f..b56895a 100644 --- a/parse.c +++ b/parse.c @@ -822,12 +822,21 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { } else { if (!parse_decl_list(p, &f->params, DECL_END_RPAREN_COMMA)) return false; + Declaration *new_params = NULL; arr_foreach(f->params, Declaration, param) { if (param->type.kind == TYPE_TUPLE) { err_print(param->where, "Functions can't have tuple parameters."); return false; } + /* whenever there's (x, y: int), turn it into (x: int, y: int) */ + arr_foreach(param->idents, Identifier, ident) { + Declaration *new_param = parser_arr_add(p, &new_params); + *new_param = *param; + new_param->idents = NULL; + *(Identifier *)parser_arr_add(p, &new_param->idents) = *ident; + } } + f->params = new_params; arr_foreach(f->params, Declaration, param) param->flags |= DECL_IS_PARAM; } diff --git a/test.toc b/test.toc index 4933289..e0e1525 100644 --- a/test.toc +++ b/test.toc @@ -8,12 +8,10 @@ puti @= fn(x: int) { // }; -f @= fn(t @ Type, x: t) t { - x + 1 +f @= fn(x: int) y := x { + puti(x); }; - main @= fn() { - puti(f(int, 3)); - puti(f(u8, 255) as int); + puti(f(1238)); }; \ No newline at end of file diff --git a/types.c b/types.c index 7052e4a..4bb6506 100644 --- a/types.c +++ b/types.c @@ -689,7 +689,10 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where, char *got = type_to_str(&ret_expr->type); char *expected = type_to_str(ret_type); err_print(ret_expr->where, "Returning type %s, but function returns type %s.", got, expected); - info_print(where, "Function declaration is here."); + if (!instance) /* where will only actually be at the function declaration if it isn't + an instance. otherwise, where will be at the calling site, which will already be + printed */ + info_print(where, "Function declaration is here."); free(got); free(expected); success = false; goto ret; @@ -1191,6 +1194,7 @@ static bool types_expr(Typer *tr, Expression *e) { bool should_be_evald = arg_is_const(&new_args[i], fn_type->constness[i]); if (should_be_evald) { Value *arg_val = typer_arr_add(tr, &table_index.tuple); + if (!eval_expr(tr->evalr, &new_args[i], arg_val)) { if (tr->evalr->enabled) { info_print(new_args[i].where, "(error occured while trying to evaluate compile-time argument, argument #%lu)", 1+(unsigned long)i); @@ -1200,7 +1204,16 @@ static bool types_expr(Typer *tr, Expression *e) { Type *type = arr_add(&table_index_type.tuple); *type = fn_type->types[i+1]; - + /* we need to check the type here so copy_val doesn't mess up */ + Type *expected = type; + Type *got = &new_args[i].type; + if (!type_eq(type, &new_args[i].type)) { + char *estr = type_to_str(expected); + char *gstr = type_to_str(got); + err_print(new_args[i].where, "Expected type %s as %lu%s argument to function, but got %s.", estr, 1+(unsigned long)i, ordinals(1+i), gstr); + return false; + } + new_args[i].kind = EXPR_VAL; new_args[i].flags = EXPR_FOUND_TYPE; copy_val(&cop, &new_args[i].val, arg_val, type); -- cgit v1.2.3