diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-25 09:28:02 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-25 09:28:02 -0500 |
commit | 76f800ae81d5530e2b07a1edf97e57710bac0d13 (patch) | |
tree | 75962ff5f0fb4bec1ff466360c4b746da5173f93 | |
parent | d238a47bb8b324084a81748e2d320e0bc2973d25 (diff) |
fixed multiple idents in one param decl
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | parse.c | 9 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | types.c | 17 |
4 files changed, 27 insertions, 11 deletions
@@ -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 @@ -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; } @@ -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 @@ -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); |