lang: for-loop by-ref element capture (for xs: (*x))
(*x) binds x to a pointer into the collection (index_gep) instead of a per-element value copy: passing it on (e.g. to a *T param) is zero-copy and mutations write back. In a value position x auto-derefs — a binary-op operand loads the element, a pointer-typed slot keeps the pointer, and an 'if x == {...}' match derefs the pointee for its tag/payload. Arrays GEP through their storage so writes hit the original. Regression test: examples/for-by-ref-capture.sx.
This commit is contained in:
@@ -2864,6 +2864,7 @@ pub const Parser = struct {
|
||||
|
||||
var capture_name: []const u8 = "";
|
||||
var index_name: ?[]const u8 = null;
|
||||
var capture_by_ref = false;
|
||||
|
||||
if (range_end != null) {
|
||||
// Range capture is the optional cursor: `(i)` or nothing.
|
||||
@@ -2875,9 +2876,14 @@ pub const Parser = struct {
|
||||
try self.expect(.r_paren);
|
||||
}
|
||||
} else {
|
||||
// Collection form: `: (capture, index?)`.
|
||||
// Collection form: `: (capture, index?)`. A leading `*` on the
|
||||
// capture (`(*x)`) binds it by pointer into the collection.
|
||||
try self.expect(.colon);
|
||||
try self.expect(.l_paren);
|
||||
if (self.current.tag == .star) {
|
||||
capture_by_ref = true;
|
||||
self.advance();
|
||||
}
|
||||
if (self.current.tag != .identifier) return self.fail("expected capture variable name");
|
||||
capture_name = self.tokenSlice(self.current);
|
||||
self.advance();
|
||||
@@ -2898,6 +2904,7 @@ pub const Parser = struct {
|
||||
.capture_name = capture_name,
|
||||
.index_name = index_name,
|
||||
.range_end = range_end,
|
||||
.capture_by_ref = capture_by_ref,
|
||||
} });
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user