lang: range bound markers — '=' inclusive / '<' exclusive on either side of '..'
Each side of '..' takes an optional bound marker, defaulting to
start-inclusive, end-exclusive (a..b == a=..<b; a..=b stays the short
end-inclusive spelling):
for 0<..<N (i) { } // 1 .. N-1 (both exclusive)
for 0=..=N (i) { } // 0 .. N (both inclusive)
for 0<..=N (i) { } // 1 .. N
for 0..<N (i) { } // 0 .. N-1 (explicit default)
for xs, 2<.. (x, i) // open range, exclusive start: i = 3, 4, ...
The nine lexemes are single tokens (maximal munch on '<'/'='/'..'), so
expression parsing never sees the leading marker as a comparison; '<',
'<<', '<=', '==', '=>' lex unchanged. An explicit end marker makes the
end expression mandatory; open forms are a.. / a<.. / a=... Works in
runtime, multi-iterable, and inline-for headers.
Regression: examples/0051-basic-for-range-bounds.sx (full matrix, open
start-marked ranges, comptime unroll, runtime bounds, lexer
non-regression); 1152's pinned message generalized.
This commit is contained in:
16
src/ast.zig
16
src/ast.zig
@@ -646,13 +646,19 @@ pub const WhileExpr = struct {
|
||||
pub const ForIterable = struct {
|
||||
/// Collection expression, or the range START for the range forms.
|
||||
expr: *Node,
|
||||
/// `a..b` / `a..=b` end. Null for a plain collection AND for the
|
||||
/// open-ended range `a..` (distinguished by `is_range`).
|
||||
/// Range end. Null for a plain collection AND for the open-ended range
|
||||
/// `a..` (distinguished by `is_range`).
|
||||
range_end: ?*Node = null,
|
||||
/// True for any range form (`a..`, `a..b`, `a..=b`).
|
||||
/// True for any range form. Each side of `..` takes an optional bound
|
||||
/// marker — `=` inclusive, `<` exclusive — with defaults start-inclusive,
|
||||
/// end-exclusive: `a..b` ≡ `a=..<b`; `a<..<b` is 1-past-start to
|
||||
/// end-1; `a=..=b` includes both ends; `a..=b` keeps the short
|
||||
/// end-inclusive spelling.
|
||||
is_range: bool = false,
|
||||
/// `a..=b` — end is inclusive.
|
||||
inclusive: bool = false,
|
||||
/// `<..` family — start is exclusive (cursor begins at start+1).
|
||||
start_exclusive: bool = false,
|
||||
/// `..=` family — end is inclusive.
|
||||
end_inclusive: bool = false,
|
||||
};
|
||||
|
||||
/// One capture of a `for` header: `(x)`, `(*x)`, `(x, y, ...)`.
|
||||
|
||||
Reference in New Issue
Block a user