summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-11-25 09:28:02 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-11-25 09:28:02 -0500
commit76f800ae81d5530e2b07a1edf97e57710bac0d13 (patch)
tree75962ff5f0fb4bec1ff466360c4b746da5173f93
parentd238a47bb8b324084a81748e2d320e0bc2973d25 (diff)
fixed multiple idents in one param decl
-rw-r--r--main.c4
-rw-r--r--parse.c9
-rw-r--r--test.toc8
-rw-r--r--types.c17
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);