summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-12-06 21:50:52 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-12-06 21:50:52 -0500
commit80b928a8a4993654a9ad8bf1336c049d6ce36ef9 (patch)
treed237a770068c6009c349a9eaa735646717abe5ba
parent651d8e3214f198524c254b560defa146cf06aadf (diff)
fixed a problem with ret decls but found another
-rw-r--r--cgen.c9
-rw-r--r--main.c3
-rw-r--r--parse.c1
-rw-r--r--test.toc6
-rw-r--r--types.c4
5 files changed, 14 insertions, 9 deletions
diff --git a/cgen.c b/cgen.c
index 57e3891..cda3c7a 100644
--- a/cgen.c
+++ b/cgen.c
@@ -1520,10 +1520,6 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Valu
g->fn = f;
cgen_write(g, " {");
cgen_nl(g);
- arr_foreach(f->ret_decls, Declaration, d) {
- if (!cgen_decl(g, d))
- return false;
- }
if (compile_time_args) {
int carg_idx = 0;
compile_time_args++; /* move past which_are_const */
@@ -1558,6 +1554,11 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where, U64 instance, Valu
}
}
+ /* retdecls need to be after compile time arguments to allow fn(x::int) y := x */
+ arr_foreach(f->ret_decls, Declaration, d) {
+ if (!cgen_decl(g, d))
+ return false;
+ }
if (!cgen_block_enter(g, &f->body)) return false;
if (!cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOENTER | CGEN_BLOCK_NOBRACES))
return false;
diff --git a/main.c b/main.c
index 9cdb5cf..adcd7f9 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,9 @@
/*
TODO:
check fn(x :: int) y := x (run + compile)
+reduce copying (don't copy body of fn_copy unless the instance doesn't
+exist yet)
+
make sure you can't have a tuple parameter (check const tuple params)
check arr.toc's Arr works @ compile time
new version of copy_val for copying types??
diff --git a/parse.c b/parse.c
index 5b6beff..66d472e 100644
--- a/parse.c
+++ b/parse.c
@@ -877,6 +877,7 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) {
t->token--; /* move back to { */
/* just set return type to void. the actual return type will be set by types.c:type_of_fn */
f->ret_type.kind = TYPE_VOID;
+ f->ret_type.flags = 0;
} else {
if (!parse_type(p, &f->ret_type)) {
ret = false;
diff --git a/test.toc b/test.toc
index 8a9b00e..61ddcb1 100644
--- a/test.toc
+++ b/test.toc
@@ -10,15 +10,15 @@ putf ::= fn(x: float) {
main ::= fn() {
puti(f(3));
puti(f(7));
- puti(f(3,4));
+ puti(f(4));
- f ::= fn(x :: int, y := x) int { y };
+ f ::= fn(x : int) y := x { };
r ::= f(3);
puti(r);
s ::= f(7);
puti(s);
- t ::= f(3,4);
+ t ::= f(4);
puti(t);
}; \ No newline at end of file
diff --git a/types.c b/types.c
index 846494a..aff951a 100644
--- a/types.c
+++ b/types.c
@@ -208,7 +208,6 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
size_t idx = 0;
bool has_constant_params = false;
Type *ret_type = typer_arr_add(tr, &t->fn.types);
-
if (!fn_enter(f, SCOPE_CHECK_REDECL))
return false;
tr->fn = f;
@@ -280,7 +279,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
}
}
- if (f->ret_decls && f->ret_type.kind == TYPE_VOID /* haven't found return type yet */) {
+ if (f->ret_decls && !generic && f->ret_type.kind == TYPE_VOID /* haven't found return type yet */) {
/* find return type */
arr_foreach(f->ret_decls, Declaration, d) {
if (!types_decl(tr, d, 0)) {
@@ -317,6 +316,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Location where, Type *t, U16 flags)
goto ret;
}
}
+
ret:
/* cleanup */
if (entered_fn) {