1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 15:38:10 +00:00

LibJS: Add spreading in array literals

Implement the syntax and behavor necessary to support array literals
such as [...[1, 2, 3]]. A type error is thrown if the target of the
spread operator does not evaluate to an array (though it should
eventually just check for an iterable).

Note that the spread token's name is TripleDot, since the '...' token is
used for two features: spread and rest. Calling it anything involving
'spread' or 'rest' would be a bit confusing.
This commit is contained in:
mattco98 2020-04-26 23:05:37 -07:00 committed by Andreas Kling
parent 49c438ce32
commit 80fecc615a
6 changed files with 101 additions and 2 deletions

View file

@ -736,6 +736,17 @@ void Identifier::dump(int indent) const
printf("Identifier \"%s\"\n", m_string.characters());
}
void SpreadExpression::dump(int indent) const
{
ASTNode::dump(indent);
m_target->dump(indent + 1);
}
Value SpreadExpression::execute(Interpreter& interpreter) const
{
return m_target->execute(interpreter);
}
Value ThisExpression::execute(Interpreter& interpreter) const
{
return interpreter.this_value();
@ -1085,8 +1096,27 @@ Value ArrayExpression::execute(Interpreter& interpreter) const
auto value = Value();
if (element) {
value = element->execute(interpreter);
if (interpreter.exception())
return {};
if (element->is_spread_expression()) {
if (!value.is_array()) {
interpreter.throw_exception<TypeError>(String::format("%s is not iterable", value.to_string().characters()));
return {};
}
auto& array_to_spread = static_cast<Array&>(value.as_object());
for (auto& it : array_to_spread.elements()) {
if (it.is_empty()) {
array->elements().append(js_undefined());
} else {
array->elements().append(it);
}
}
continue;
}
}
array->elements().append(value);
}