summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test.toc36
-rw-r--r--types.c15
2 files changed, 35 insertions, 16 deletions
diff --git a/test.toc b/test.toc
index 1bc7c34..8372265 100644
--- a/test.toc
+++ b/test.toc
@@ -1,20 +1,28 @@
#include "std/io.toc", io;
-main ::= fn() {
- defer io.puts("deferred from main");
- for i := 0..10 {
- defer io.puti(i);
- if i == 7 {
- defer io.puts("break!!!");
- break;
+prime_sieve ::= fn(N::=10000) sieve: [N]bool {
+ for x, i := &sieve {
+ *x = i%2 != 0;
+ }
+ sieve[1] = false;
+ sieve[2] = true;
+ i := 3;
+ while i*i <= N {
+ defer i += 2;
+ if !sieve[i] { continue; }
+ j := 2*i;
+ while j < N {
+ sieve[j] = false;
+ j += i;
}
- if i % 2 == 0 {
- defer io.puts("continue!!!");
- continue;
+ }
+}
+
+main ::= fn() {
+ sieve := prime_sieve();
+ for x, i := sieve {
+ if x {
+ io.puti(i);
}
- io.puts("number...");
}
- return;
- io.puts("end of main");
}
-main();
diff --git a/types.c b/types.c
index 06d11f9..c66cd6a 100644
--- a/types.c
+++ b/types.c
@@ -2128,12 +2128,23 @@ static Status types_expr(Typer *tr, Expression *e) {
I16 arg_idx = order[i];
if (arg_idx == -1) {
if (param->flags & DECL_HAS_EXPR) {
- assert(param->expr.kind == EXPR_VAL); /* evaluated in type_of_fn */
arg_exprs[i].kind = EXPR_VAL;
arg_exprs[i].where = param->where;
arg_exprs[i].flags = param->expr.flags;
arg_exprs[i].type = param->type;
- arg_exprs[i].val = param->expr.val;
+ if (has_varargs || f->type.fn.constness) {
+ /* param->expr hasn't been typed or evaluated, because we passed type_of_fn a "generic" function */
+ /* we actually need to make a copy of this, so that copy_fn_expr still works later */
+ Expression default_arg;
+ Copier cop = copier_create(tr->allocr, tr->block);
+ copy_expr(&cop, &default_arg, &param->expr);
+ if (!types_expr(tr, &default_arg))
+ return false;
+ if (!eval_expr(tr->evalr, &default_arg, &arg_exprs[i].val))
+ return false;
+ } else {
+ arg_exprs[i].val = param->expr.val;
+ }
}
/* else, it's inferred */
} else {