diff --git a/boa/src/exec/operator/mod.rs b/boa/src/exec/operator/mod.rs index 3274f15383..cbbfd7617f 100644 --- a/boa/src/exec/operator/mod.rs +++ b/boa/src/exec/operator/mod.rs @@ -140,6 +140,10 @@ impl Executable for BinOp { } _ => Ok(Value::undefined()), }, + op::BinOp::Comma => { + self.lhs().run(interpreter)?; + Ok(self.rhs().run(interpreter)?) + } } } } diff --git a/boa/src/exec/tests.rs b/boa/src/exec/tests.rs index 9924ec82ac..0a4b089e91 100644 --- a/boa/src/exec/tests.rs +++ b/boa/src/exec/tests.rs @@ -1171,3 +1171,22 @@ fn not_a_function() { "\"TypeError: not a function\"" ); } + +#[test] +fn comma_operator() { + let scenario = r#" + var a, b; + b = 10; + a = (b++, b); + a + "#; + assert_eq!(&exec(scenario), "11"); + + let scenario = r#" + var a, b; + b = 10; + a = (b += 5, b /= 3, b - 3); + a + "#; + assert_eq!(&exec(scenario), "2"); +} diff --git a/boa/src/syntax/ast/op.rs b/boa/src/syntax/ast/op.rs index 69329c59fd..e759136abe 100644 --- a/boa/src/syntax/ast/op.rs +++ b/boa/src/syntax/ast/op.rs @@ -705,6 +705,9 @@ pub enum BinOp { /// /// see: [`AssignOp`](enum.AssignOp.html). Assign(AssignOp), + + /// Comma operation. + Comma, } impl From for BinOp { @@ -748,6 +751,7 @@ impl Display for BinOp { Self::Comp(ref op) => op.to_string(), Self::Log(ref op) => op.to_string(), Self::Assign(ref op) => op.to_string(), + Self::Comma => ",".to_string(), } ) } diff --git a/boa/src/syntax/ast/punctuator.rs b/boa/src/syntax/ast/punctuator.rs index dab0dfcf70..8201268a5b 100644 --- a/boa/src/syntax/ast/punctuator.rs +++ b/boa/src/syntax/ast/punctuator.rs @@ -167,6 +167,7 @@ impl Punctuator { Self::LeftSh => Some(BinOp::Bit(BitOp::Shl)), Self::RightSh => Some(BinOp::Bit(BitOp::Shr)), Self::URightSh => Some(BinOp::Bit(BitOp::UShr)), + Self::Comma => Some(BinOp::Comma), _ => None, } } diff --git a/boa/src/syntax/parser/expression/assignment/mod.rs b/boa/src/syntax/parser/expression/assignment/mod.rs index 4f71f21736..7351535ca0 100644 --- a/boa/src/syntax/parser/expression/assignment/mod.rs +++ b/boa/src/syntax/parser/expression/assignment/mod.rs @@ -116,7 +116,7 @@ impl TokenParser for AssignmentExpression { TokenKind::Punctuator(Punctuator::Assign) => { lhs = Assign::new(lhs, self.parse(cursor)?).into(); } - TokenKind::Punctuator(p) if p.as_binop().is_some() => { + TokenKind::Punctuator(p) if p.as_binop().is_some() && p != Punctuator::Comma => { let expr = self.parse(cursor)?; let binop = p.as_binop().expect("binop disappeared"); lhs = BinOp::new(binop, lhs, expr).into();