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:
parent
5cd01ed79e
commit
10bf4ba3dc
4 changed files with 44 additions and 0 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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;
|
||||||
|
|
13
Libraries/LibJS/Tests/labels.js
Normal file
13
Libraries/LibJS/Tests/labels.js
Normal 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);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue