diff options
author | Matthew Olsson <matthewcolsson@gmail.com> | 2020-05-05 22:36:24 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-06 19:19:02 +0200 |
commit | 107ca2e4ba8f88f39f58c4a92d238ea642aa0d39 (patch) | |
tree | 2fee5756368b75095ed869eca804637d2434f30e /Libraries/LibJS/AST.cpp | |
parent | 8fe821fae29e790f0a8fa0bc27d14547a316aaa3 (diff) | |
download | serenity-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.cpp | 26 |
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 |