1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 22:37:34 +00:00

LibJS: Parse labelled statements

All statements now have an optional label string that can be null.
This commit is contained in:
Matthew Olsson 2020-05-28 11:09:19 -07:00 committed by Andreas Kling
parent 5cd01ed79e
commit 10bf4ba3dc
4 changed files with 44 additions and 0 deletions

View file

@ -70,6 +70,12 @@ private:
}; };
class Statement : public ASTNode { class Statement : public ASTNode {
public:
const FlyString& label() const { return m_label; }
void set_label(FlyString string) { m_label = string; }
protected:
FlyString m_label;
}; };
class EmptyStatement final : public Statement { class EmptyStatement final : public Statement {

View file

@ -269,6 +269,9 @@ NonnullRefPtr<Statement> Parser::parse_statement()
consume(); consume();
return create_ast_node<EmptyStatement>(); return create_ast_node<EmptyStatement>();
default: default:
auto result = try_parse_labelled_statement();
if (!result.is_null())
return result.release_nonnull();
if (match_expression()) { if (match_expression()) {
auto expr = parse_expression(0); auto expr = parse_expression(0);
consume_or_insert_semicolon(); consume_or_insert_semicolon();
@ -383,6 +386,27 @@ RefPtr<FunctionExpression> Parser::try_parse_arrow_function_expression(bool expe
return nullptr; return nullptr;
} }
RefPtr<Statement> Parser::try_parse_labelled_statement()
{
save_state();
ArmedScopeGuard state_rollback_guard = [&] {
load_state();
};
auto identifier = consume(TokenType::Identifier).value();
if (!match(TokenType::Colon))
return {};
consume(TokenType::Colon);
if (!match_statement())
return {};
auto statement = parse_statement();
statement->set_label(identifier);
state_rollback_guard.disarm();
return statement;
}
NonnullRefPtr<Expression> Parser::parse_primary_expression() NonnullRefPtr<Expression> Parser::parse_primary_expression()
{ {
if (match_unary_prefixed_expression()) if (match_unary_prefixed_expression())

View file

@ -78,6 +78,7 @@ public:
NonnullRefPtr<CallExpression> parse_call_expression(NonnullRefPtr<Expression>); NonnullRefPtr<CallExpression> parse_call_expression(NonnullRefPtr<Expression>);
NonnullRefPtr<NewExpression> parse_new_expression(); NonnullRefPtr<NewExpression> parse_new_expression();
RefPtr<FunctionExpression> try_parse_arrow_function_expression(bool expect_parens); RefPtr<FunctionExpression> try_parse_arrow_function_expression(bool expect_parens);
RefPtr<Statement> try_parse_labelled_statement();
struct Error { struct Error {
String message; String message;

View file

@ -0,0 +1,13 @@
load("test-common.js");
try {
test:
{
let o = 1;
assert(o === 1);
}
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);
}