aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-08-05 14:40:28 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-08-05 14:40:28 -0400
commitc045c54309dfaa7bb11f97dc3f36c595736eca3b (patch)
tree52c6b1602adf5d334be6e913273b609d1e88eaa4 /compile.c
parent8e2156ac483e7fa0f2007188b670eb11f2a44720 (diff)
Add a Range datatype with creation methods like `5:to(10)` and
modification methods like `range:by(2)` or `range:reversed()`
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 9f91161c..a141302b 100644
--- a/compile.c
+++ b/compile.c
@@ -817,6 +817,22 @@ CORD compile_statement(env_t *env, ast_t *ast)
body = CORD_all(body, "\n", loop_ctx.skip_label, ": continue;");
CORD stop = loop_ctx.stop_label ? CORD_all("\n", loop_ctx.stop_label, ":;") : CORD_EMPTY;
+ if (iter_t == RANGE_TYPE) {
+ CORD value = for_->vars ? compile(env, for_->vars->ast) : "i";
+ CORD range = compile(env, for_->iter);
+ if (for_->empty)
+ code_err(ast, "Ranges are never empty, they always contain at least their starting element");
+ return CORD_all(
+ "{\n"
+ "const Range_t range = ", range, ";\n"
+ "if (range.step == 0) fail(\"This range has a 'step' of zero and will loop infinitely!\");\n"
+ "for (int64_t ", value, " = range.first; range.step > 0 ? ", value, " <= range.last : ", value, " >= range.last; ", value, " += range.step) {\n"
+ "\t", body,
+ "\n}",
+ stop,
+ "\n}");
+ }
+
switch (iter_t->tag) {
case ArrayType: {
type_t *item_t = Match(iter_t, ArrayType)->item_type;