diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-12 19:53:31 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-12 19:54:47 +0100 |
commit | 7912f33ea0c223b88ff79ad4c072ec87dd0c29c4 (patch) | |
tree | c5c1b67c6dcf6605b02d2eb4a5f52be4fc956499 /Libraries/LibJS/Interpreter.cpp | |
parent | cc8e3048bc7d807154765297d4bf381f368bf3ed (diff) | |
download | serenity-7912f33ea0c223b88ff79ad4c072ec87dd0c29c4.zip |
LibJS: Add NativeFunction, a callable wrapper around a C++ lambda
This can be used to implement arbitrary functionality, callable from
JavaScript.
To make this work, I had to change the way CallExpression passes
arguments to the callee. Instead of a HashMap<String, Value>, we now
pass an ordered list of Argument { String name; Value value; }.
This patch includes a native "print(argument)" function. :^)
Diffstat (limited to 'Libraries/LibJS/Interpreter.cpp')
-rw-r--r-- | Libraries/LibJS/Interpreter.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index 8a569e0fe3..b62c7db5ca 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -27,8 +27,10 @@ #include <AK/Badge.h> #include <LibJS/AST.h> #include <LibJS/Interpreter.h> +#include <LibJS/NativeFunction.h> #include <LibJS/Object.h> #include <LibJS/Value.h> +#include <stdio.h> namespace JS { @@ -36,15 +38,20 @@ Interpreter::Interpreter() : m_heap(*this) { m_global_object = heap().allocate<Object>(); + m_global_object->put("print", Value(heap().allocate<NativeFunction>([](Vector<Argument> arguments) -> Value { + for (auto& argument : arguments) + printf("%s ", argument.value.to_string().characters()); + return js_undefined(); + }))); } Interpreter::~Interpreter() { } -Value Interpreter::run(const ScopeNode& scope_node, HashMap<String, Value> scope_variables, ScopeType scope_type) +Value Interpreter::run(const ScopeNode& scope_node, Vector<Argument> arguments, ScopeType scope_type) { - enter_scope(scope_node, move(scope_variables), scope_type); + enter_scope(scope_node, move(arguments), scope_type); Value last_value = js_undefined(); for (auto& node : scope_node.children()) { @@ -55,13 +62,12 @@ Value Interpreter::run(const ScopeNode& scope_node, HashMap<String, Value> scope return last_value; } -void Interpreter::enter_scope(const ScopeNode& scope_node, HashMap<String, Value> scope_variables, ScopeType scope_type) +void Interpreter::enter_scope(const ScopeNode& scope_node, Vector<Argument> arguments, ScopeType scope_type) { HashMap<String, Variable> scope_variables_with_declaration_type; - for (String name : scope_variables.keys()) { - scope_variables_with_declaration_type.set(name, { scope_variables.get(name).value(), DeclarationType::Var }); + for (auto& argument : arguments) { + scope_variables_with_declaration_type.set(argument.name, { argument.value, DeclarationType::Var }); } - m_scope_stack.append({ scope_type, scope_node, move(scope_variables_with_declaration_type) }); } |