mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
LibJS: Implement basic execution of "switch" statements
The "break" keyword now unwinds to the nearest ScopeType::Breakable. There's no support for break labels yet, but we'll get there too.
This commit is contained in:
parent
1923051c5b
commit
2285f84596
Notes:
sideshowbarker
2024-07-19 08:04:58 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/2285f845969
6 changed files with 57 additions and 2 deletions
|
@ -873,7 +873,31 @@ Value ThrowStatement::execute(Interpreter& interpreter) const
|
|||
|
||||
Value SwitchStatement::execute(Interpreter& interpreter) const
|
||||
{
|
||||
(void)interpreter;
|
||||
auto discriminant_result = m_discriminant->execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
|
||||
bool falling_through = false;
|
||||
|
||||
for (auto& switch_case : m_cases) {
|
||||
if (!falling_through && switch_case.test()) {
|
||||
auto test_result = switch_case.test()->execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (!eq(discriminant_result, test_result).to_boolean())
|
||||
continue;
|
||||
}
|
||||
falling_through = true;
|
||||
|
||||
for (auto& statement : switch_case.consequent()) {
|
||||
statement.execute(interpreter);
|
||||
if (interpreter.exception())
|
||||
return {};
|
||||
if (interpreter.should_unwind())
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -885,7 +909,7 @@ Value SwitchCase::execute(Interpreter& interpreter) const
|
|||
|
||||
Value BreakStatement::execute(Interpreter& interpreter) const
|
||||
{
|
||||
(void)interpreter;
|
||||
interpreter.unwind(ScopeType::Breakable);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -715,6 +715,9 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
const Expression* test() const { return m_test; }
|
||||
const NonnullRefPtrVector<Statement>& consequent() const { return m_consequent; }
|
||||
|
||||
virtual void dump(int indent) const override;
|
||||
virtual Value execute(Interpreter&) const override;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ enum class ScopeType {
|
|||
Function,
|
||||
Block,
|
||||
Try,
|
||||
Breakable,
|
||||
};
|
||||
|
||||
struct Variable {
|
||||
|
@ -78,6 +79,7 @@ public:
|
|||
Heap& heap() { return m_heap; }
|
||||
|
||||
void unwind(ScopeType type) { m_unwind_until = type; }
|
||||
bool should_unwind() const { return m_unwind_until != ScopeType::None; }
|
||||
|
||||
Optional<Value> get_variable(const FlyString& name);
|
||||
void set_variable(const FlyString& name, Value, bool first_assignment = false);
|
||||
|
|
10
Libraries/LibJS/Tests/switch-basic-2.js
Normal file
10
Libraries/LibJS/Tests/switch-basic-2.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
var a = "foo";
|
||||
|
||||
switch (a + "bar") {
|
||||
case 1:
|
||||
break;
|
||||
case "foobar":
|
||||
case 2:
|
||||
console.log("PASS");
|
||||
break;
|
||||
}
|
6
Libraries/LibJS/Tests/switch-basic-3.js
Normal file
6
Libraries/LibJS/Tests/switch-basic-3.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
var a = "foo";
|
||||
|
||||
switch (100) {
|
||||
default:
|
||||
console.log("PASS");
|
||||
}
|
10
Libraries/LibJS/Tests/switch-basic.js
Normal file
10
Libraries/LibJS/Tests/switch-basic.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
switch (1 + 2) {
|
||||
case 3:
|
||||
console.log("PASS");
|
||||
break;
|
||||
case 5:
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
Loading…
Add table
Reference in a new issue