aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 04ec9e00..dc00d01e 100644
--- a/compile.c
+++ b/compile.c
@@ -1543,6 +1543,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
// Special case for improving performance for numeric iteration:
if (for_->iter->tag == MethodCall && streq(Match(for_->iter, MethodCall)->name, "to") &&
get_type(env, Match(for_->iter, MethodCall)->self)->tag == BigIntType) {
+ // TODO: support other integer types
arg_ast_t *args = Match(for_->iter, MethodCall)->args;
if (!args) code_err(for_->iter, "to() needs at least one argument");
@@ -1587,6 +1588,19 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
"\t", naked_body,
"}",
stop);
+ } else if (for_->iter->tag == MethodCall && streq(Match(for_->iter, MethodCall)->name, "onward") &&
+ get_type(env, Match(for_->iter, MethodCall)->self)->tag == BigIntType) {
+ // Special case for Int:onward()
+ arg_ast_t *args = Match(for_->iter, MethodCall)->args;
+ arg_t *arg_spec = new(arg_t, .name="step", .type=INT_TYPE, .default_val=FakeAST(Int, .str="1"), .next=NULL);
+ CORD step = compile_arguments(env, for_->iter, arg_spec, args);
+ CORD value = for_->vars ? compile(body_scope, for_->vars->ast) : "i";
+ return CORD_all(
+ "for (Int_t ", value, " = ", compile(env, Match(for_->iter, MethodCall)->self), ", ",
+ "step = ", step, "; ; ", value, " = Int$plus(", value, ", step)) {\n"
+ "\t", naked_body,
+ "}",
+ stop);
}
type_t *iter_t = value_type(get_type(env, for_->iter));