multiple assign

This commit is contained in:
agra
2026-02-16 01:13:34 +02:00
parent fb60818424
commit 58e2a5bdb1
9 changed files with 171 additions and 13 deletions

View File

@@ -834,6 +834,12 @@ pub const Parser = struct {
return self.parseTypedBinding(name, start);
}
// Multi-target assignment: ident, expr, ... = expr, expr, ...;
if (self.current.tag == .comma) {
const first_target = try self.createNode(start, .{ .identifier = .{ .name = name } });
return try self.parseMultiAssign(first_target, start);
}
// Check for assignment operators
if (self.isAssignOp()) {
const op = self.assignOp();
@@ -918,6 +924,11 @@ pub const Parser = struct {
// Expression statement
const expr = try self.parseExpr();
// Multi-target assignment: expr, expr, ... = expr, expr, ...;
if (self.current.tag == .comma) {
return try self.parseMultiAssign(expr, expr.span.start);
}
// Check for field assignment: expr = value; (e.g. a.b = 1;)
if (self.isAssignOp()) {
const op = self.assignOp();
@@ -1623,6 +1634,45 @@ pub const Parser = struct {
};
}
fn parseMultiAssign(self: *Parser, first_target: *Node, start: u32) !*Node {
var targets = std.ArrayList(*Node).empty;
try targets.append(self.allocator, first_target);
// Consume remaining targets separated by commas
while (self.current.tag == .comma) {
self.advance();
const target = try self.parseExpr();
try targets.append(self.allocator, target);
}
// Only plain '=' is allowed
if (self.current.tag != .equal) {
return self.fail("multi-target assignment requires '='");
}
self.advance();
// Parse RHS values separated by commas
var values = std.ArrayList(*Node).empty;
const first_val = try self.parseExpr();
try values.append(self.allocator, first_val);
while (self.current.tag == .comma) {
self.advance();
const val = try self.parseExpr();
try values.append(self.allocator, val);
}
if (targets.items.len != values.items.len) {
return self.fail("multi-target assignment: target count does not match value count");
}
try self.expect(.semicolon);
return try self.createNode(start, .{ .multi_assign = .{
.targets = try targets.toOwnedSlice(self.allocator),
.values = try values.toOwnedSlice(self.allocator),
} });
}
fn binaryPrec(self: *const Parser) u8 {
return switch (self.current.tag) {
.kw_or => 1,