LibJS: Support empty statements

We already skipped random semicolons in Parser::parse_program(), but now
they are properly matched and parsed as empty statements - and thus
recognized as a valid body of an if / else / while / ... statement.
This commit is contained in:
Linus Groh 2020-05-03 10:59:00 +01:00 committed by Andreas Kling
parent 3b432eed98
commit 32742709dc
Notes: sideshowbarker 2024-07-19 07:01:35 +09:00
3 changed files with 23 additions and 4 deletions

View file

@ -71,6 +71,12 @@ private:
class Statement : public ASTNode {
};
class EmptyStatement final : public Statement {
public:
Value execute(Interpreter&) const override { return js_undefined(); }
const char* class_name() const override { return "EmptyStatement"; }
};
class ErrorStatement final : public Statement {
public:
Value execute(Interpreter&) const override { return js_undefined(); }

View file

@ -206,9 +206,7 @@ NonnullRefPtr<Program> Parser::parse_program()
ScopePusher scope(*this, ScopePusher::Var | ScopePusher::Let);
auto program = adopt(*new Program);
while (!done()) {
if (match(TokenType::Semicolon)) {
consume();
} else if (match_statement()) {
if (match_statement()) {
program->append(parse_statement());
} else {
expected("statement");
@ -255,6 +253,9 @@ NonnullRefPtr<Statement> Parser::parse_statement()
return parse_while_statement();
case TokenType::Debugger:
return parse_debugger_statement();
case TokenType::Semicolon:
consume();
return create_ast_node<EmptyStatement>();
default:
if (match_expression()) {
auto expr = parse_expression(0);
@ -1176,7 +1177,8 @@ bool Parser::match_statement() const
|| type == TokenType::Break
|| type == TokenType::Continue
|| type == TokenType::Var
|| type == TokenType::Debugger;
|| type == TokenType::Debugger
|| type == TokenType::Semicolon;
}
bool Parser::match_identifier_name() const

View file

@ -0,0 +1,11 @@
try {
;;;
if (true);
if (false); else if (false); else;
while (false);
do; while (false);
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}