1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 17:25:07 +00:00

LibJS: Allow the choice of a scope of declaration for a variable (#1408)

Previously, we were assuming all declared variables were bound to a
block scope, now, with the addition of declaration types, we can bind
a variable to a block scope using `let`, or a function scope (the scope
of the inner-most enclosing function of a `var` declaration) using
`var`.
This commit is contained in:
0xtechnobabble 2020-03-11 21:09:20 +02:00 committed by GitHub
parent 542108421e
commit df40c85f80
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 16 deletions

View file

@ -42,9 +42,9 @@ Interpreter::~Interpreter()
{
}
Value Interpreter::run(const ScopeNode& scope_node)
Value Interpreter::run(const ScopeNode& scope_node, ScopeType scope_type)
{
enter_scope(scope_node);
enter_scope(scope_node, scope_type);
Value last_value = js_undefined();
for (auto& node : scope_node.children()) {
@ -55,9 +55,9 @@ Value Interpreter::run(const ScopeNode& scope_node)
return last_value;
}
void Interpreter::enter_scope(const ScopeNode& scope_node)
void Interpreter::enter_scope(const ScopeNode& scope_node, ScopeType scope_type)
{
m_scope_stack.append({ scope_node, {} });
m_scope_stack.append({ scope_type, scope_node, {} });
}
void Interpreter::exit_scope(const ScopeNode& scope_node)
@ -71,9 +71,24 @@ void Interpreter::do_return()
dbg() << "FIXME: Implement Interpreter::do_return()";
}
void Interpreter::declare_variable(String name)
void Interpreter::declare_variable(String name, DeclarationType declaration_type)
{
m_scope_stack.last().variables.set(move(name), js_undefined());
switch (declaration_type) {
case DeclarationType::Var:
for (ssize_t i = m_scope_stack.size() - 1; i >= 0; --i) {
auto& scope = m_scope_stack.at(i);
if (scope.type == ScopeType::Function) {
scope.variables.set(move(name), js_undefined());
return;
}
}
global_object().put(move(name), js_undefined());
break;
case DeclarationType::Let:
m_scope_stack.last().variables.set(move(name), js_undefined());
break;
}
}
void Interpreter::set_variable(String name, Value value)