summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/AST.cpp
diff options
context:
space:
mode:
authorMatthew Olsson <matthewcolsson@gmail.com>2020-05-05 22:36:24 -0700
committerAndreas Kling <kling@serenityos.org>2020-05-06 19:19:02 +0200
commit107ca2e4ba8f88f39f58c4a92d238ea642aa0d39 (patch)
tree2fee5756368b75095ed869eca804637d2434f30e /Libraries/LibJS/AST.cpp
parent8fe821fae29e790f0a8fa0bc27d14547a316aaa3 (diff)
downloadserenity-107ca2e4ba8f88f39f58c4a92d238ea642aa0d39.zip
LibJS: Add function call spreading
Adds support for the following syntax: myFunction(...x, ...[1, 2, 3], ...o.foo, ...'abcd')
Diffstat (limited to 'Libraries/LibJS/AST.cpp')
-rw-r--r--Libraries/LibJS/AST.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp
index 7c67f6097f..a3537577e9 100644
--- a/Libraries/LibJS/AST.cpp
+++ b/Libraries/LibJS/AST.cpp
@@ -137,12 +137,28 @@ Value CallExpression::execute(Interpreter& interpreter) const
arguments.values().append(function.bound_arguments());
for (size_t i = 0; i < m_arguments.size(); ++i) {
- auto value = m_arguments[i].execute(interpreter);
- if (interpreter.exception())
- return {};
- arguments.append(value);
+ auto value = m_arguments[i].value->execute(interpreter);
if (interpreter.exception())
return {};
+ if (m_arguments[i].is_spread) {
+ // FIXME: Support generic iterables
+ Vector<Value> iterables;
+ if (value.is_string()) {
+ for (auto ch : value.as_string().string())
+ iterables.append(Value(js_string(interpreter, String::format("%c", ch))));
+ } else if (value.is_object() && value.as_object().is_array()) {
+ iterables = static_cast<const Array&>(value.as_object()).elements();
+ } else if (value.is_object() && value.as_object().is_string_object()) {
+ for (auto ch : static_cast<const StringObject&>(value.as_object()).primitive_string().string())
+ iterables.append(Value(js_string(interpreter, String::format("%c", ch))));
+ } else {
+ interpreter.throw_exception<TypeError>(String::format("%s is not iterable", value.to_string()));
+ }
+ for (auto& value : iterables)
+ arguments.append(value);
+ } else {
+ arguments.append(value);
+ }
}
auto& call_frame = interpreter.push_call_frame();
@@ -657,7 +673,7 @@ void CallExpression::dump(int indent) const
printf("CallExpression %s\n", is_new_expression() ? "[new]" : "");
m_callee->dump(indent + 1);
for (auto& argument : m_arguments)
- argument.dump(indent + 1);
+ argument.value->dump(indent + 1);
}
void StringLiteral::dump(int indent) const