From fea5617e4ef2eba701e6cfabd61f1e455e680534 Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 10 Jun 2026 22:12:45 +0300 Subject: [PATCH] lang: slice ranges take the same bound markers as for-header ranges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xs[1..=3] (end inclusive), xs[0<..<4] (both exclusive), xs[..=2] (prefix form with markers, implicit 0 start), xs[2<..] (open end, exclusive start), and xs[..] (whole collection) — lowered as lo+1 / hi+1 on the existing subslice op. Strings slice through the same path. An explicit end marker requires an end expression, matching the for-header rule. Regression: examples/0052-basic-slice-range-bounds.sx. --- examples/0052-basic-slice-range-bounds.sx | 32 ++++++++++++++++++ .../0052-basic-slice-range-bounds.exit | 1 + .../0052-basic-slice-range-bounds.stderr | 1 + .../0052-basic-slice-range-bounds.stdout | 9 +++++ readme.md | 1 + specs.md | 13 ++++++++ src/ast.zig | 8 +++-- src/ir/lower/expr.zig | 6 ++-- src/parser.zig | 33 +++++++++++++++---- 9 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 examples/0052-basic-slice-range-bounds.sx create mode 100644 examples/expected/0052-basic-slice-range-bounds.exit create mode 100644 examples/expected/0052-basic-slice-range-bounds.stderr create mode 100644 examples/expected/0052-basic-slice-range-bounds.stdout diff --git a/examples/0052-basic-slice-range-bounds.sx b/examples/0052-basic-slice-range-bounds.sx new file mode 100644 index 0000000..66e94cb --- /dev/null +++ b/examples/0052-basic-slice-range-bounds.sx @@ -0,0 +1,32 @@ +// Slice range bound markers — same matrix as for-header ranges: each side +// of `..` takes `=` (inclusive) or `<` (exclusive), defaults 0-inclusive +// start / exclusive end. Prefix form takes markers too ([..=2], [<..3]); +// [..] is the whole slice; bounds are arbitrary expressions; strings slice +// through the same path. + +#import "modules/std.sx"; + +dump :: (s: []s64, tag: string) { + print("{}: ", tag); + for s (v) { print("{} ", v); } + print("(len {})\n", s.len); +} + +main :: () -> s32 { + xs : [6]s64 = .[10, 11, 12, 13, 14, 15]; + full : []s64 = xs[0..6]; + + dump(full[1..=3], "1..=3"); // 11 12 13 + dump(full[0<..<4], "0<..<4"); // 11 12 13 + dump(full[..=2], "..=2"); // 10 11 12 + dump(full[<..3], "<..3"); // 11 12 + dump(full[2<..], "2<.."); // 13 14 15 + dump(full[..], ".."); // all six + x := 3; + dump(full[x-1..=x+1], "x-1..=x+1"); // 12 13 14 + + s := "abcdef"; + print("str 1..=3: {}\n", s[1..=3]); // bcd + print("str 0<..<4: {}\n", s[0<..<4]); // bcd + 0 +} diff --git a/examples/expected/0052-basic-slice-range-bounds.exit b/examples/expected/0052-basic-slice-range-bounds.exit new file mode 100644 index 0000000..573541a --- /dev/null +++ b/examples/expected/0052-basic-slice-range-bounds.exit @@ -0,0 +1 @@ +0 diff --git a/examples/expected/0052-basic-slice-range-bounds.stderr b/examples/expected/0052-basic-slice-range-bounds.stderr new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/expected/0052-basic-slice-range-bounds.stderr @@ -0,0 +1 @@ + diff --git a/examples/expected/0052-basic-slice-range-bounds.stdout b/examples/expected/0052-basic-slice-range-bounds.stdout new file mode 100644 index 0000000..fdf1b10 --- /dev/null +++ b/examples/expected/0052-basic-slice-range-bounds.stdout @@ -0,0 +1,9 @@ +1..=3: 11 12 13 (len 3) +0<..<4: 11 12 13 (len 3) +..=2: 10 11 12 (len 3) +<..3: 11 12 (len 2) +2<..: 13 14 15 (len 3) +..: 10 11 12 13 14 15 (len 6) +x-1..=x+1: 12 13 14 (len 3) +str 1..=3: bcd +str 0<..<4: bcd diff --git a/readme.md b/readme.md index 2fa7919..461d4b4 100644 --- a/readme.md +++ b/readme.md @@ -347,6 +347,7 @@ for 1..=5, 0.. (a, b) { print("{}:{}\n", a, b); } // a: 1..5, b follows for items (val) => total += val; // arrow body for 0<..