multiple assign
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user