diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-05 12:41:13 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-05 12:41:13 -0400 |
| commit | 34d98f067eff63d9f10031f6b2b42103d2e3db51 (patch) | |
| tree | 44d97dcf23a2b2ae347b24d87fd6ea8fa414becd | |
| parent | e91b53f07018608f2eba7d11748708b97b2cb4e9 (diff) | |
For big or arbitrarily big integers not known to be constant, do full
Int$plus(a,b) logic so it's definitely correct and doesn't error.
| -rw-r--r-- | compile.c | 29 | ||||
| -rw-r--r-- | test/reductions.tm | 4 |
2 files changed, 22 insertions, 11 deletions
@@ -1092,18 +1092,30 @@ CORD compile_statement(env_t *env, ast_t *ast) n = mpz_get_str(NULL, 10, i); else goto big_n; - } else { - big_n: - n = CORD_all("Int_to_Int64(", compile(env, for_->iter), ", false)"); + + + if (for_->empty && mpz_cmp_si(i, 0) == 0) { + return compile_statement(env, for_->empty); + } else { + return CORD_all( + "for (int64_t i = 1; i <= ", n, "; ++i) {\n", + for_->vars ? CORD_all("\tInt_t ", compile(body_scope, for_->vars->ast), " = I_small(i);\n") : CORD_EMPTY, + "\t", naked_body, + "}\n", + stop, "\n"); + } } + big_n: + n = compile(env, for_->iter); + CORD i = for_->vars ? compile(body_scope, for_->vars->ast) : "i"; + CORD n_var = for_->vars ? CORD_all("max", i) : "n"; if (for_->empty) { return CORD_all( "{\n" - "int64_t n = ", n, ";\n" - "if (n > 0) {\n" - "for (int64_t i = 1; i <= n; ++i) {\n", - for_->vars ? CORD_all("\tInt_t ", compile(body_scope, for_->vars->ast), " = I(i);\n") : CORD_EMPTY, + "Int_t ", n_var, " = ", compile(env, for_->iter), ";\n" + "if (!I_is_zero(", n_var, ")) {\n" + "for (Int_t ", i, " = I(1); Int$compare_value(", i, ", ", n_var, ") <= 0; ", i, " = Int$plus(", i, ", I(1))) {\n", "\t", naked_body, "}\n" "} else ", compile_statement(env, for_->empty), @@ -1111,8 +1123,7 @@ CORD compile_statement(env_t *env, ast_t *ast) "}\n"); } else { return CORD_all( - "for (int64_t i = 1, n = ", n, "; i <= n; ++i) {\n", - for_->vars ? CORD_all("\tInt_t ", compile(body_scope, for_->vars->ast), " = I(i);\n") : CORD_EMPTY, + "for (Int_t ", i, " = I(1), ", n_var, " = ", n, "; Int$compare_value(", i, ", ", n_var, ") <= 0; ", i, " = Int$plus(", i, ", I(1))) {\n", "\t", naked_body, "}\n", stop, "\n"); diff --git a/test/reductions.tm b/test/reductions.tm index 72db3d1b..47f1612a 100644 --- a/test/reductions.tm +++ b/test/reductions.tm @@ -18,8 +18,8 @@ func main(): = Foo(x=0, y=-999) !! (or) and (and) have early out behavior: - >> (or) i == 3 for i in 99999999999999999 + >> (or) i == 3 for i in 9999999999999999999999999999 = yes - >> (and) i < 10 for i in 99999999999999999 + >> (and) i < 10 for i in 9999999999999999999999999999 = no |
