diff options
author | Andreas Kling <kling@serenityos.org> | 2020-03-19 11:52:56 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-03-19 11:54:11 +0100 |
commit | 07679e347cbe58aa90ea039013c0f884cf9ee7b2 (patch) | |
tree | ff2ab3fa4aaf7cc11d9fdf23c1b9481d24fa8fd4 /Libraries/LibJS/Parser.cpp | |
parent | b1b4c9844e63a65a19f5772c614df29015b37ce1 (diff) | |
download | serenity-07679e347cbe58aa90ea039013c0f884cf9ee7b2.zip |
LibJS: Parse FunctionExpressions
FunctionExpression is mostly like FunctionDeclaration, except the name
is optional. Share the parsing logic in parse_function_node<NodeType>.
This allows us to do nice things like:
document.addEventListener("DOMContentLoaded", function() {
alert("Hello friends!");
});
Diffstat (limited to 'Libraries/LibJS/Parser.cpp')
-rw-r--r-- | Libraries/LibJS/Parser.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/Libraries/LibJS/Parser.cpp b/Libraries/LibJS/Parser.cpp index 051fec8983..e474abb6ed 100644 --- a/Libraries/LibJS/Parser.cpp +++ b/Libraries/LibJS/Parser.cpp @@ -187,7 +187,7 @@ NonnullRefPtr<Statement> Parser::parse_statement() switch (m_current_token.type()) { case TokenType::Function: - return parse_function_declaration(); + return parse_function_node<FunctionDeclaration>(); case TokenType::CurlyOpen: return parse_block_statement(); case TokenType::Return: @@ -231,6 +231,8 @@ NonnullRefPtr<Expression> Parser::parse_primary_expression() return create_ast_node<UndefinedLiteral>(); case TokenType::CurlyOpen: return parse_object_expression(); + case TokenType::Function: + return parse_function_node<FunctionExpression>(); default: m_has_errors = true; expected("primary expression (missing switch case)"); @@ -416,10 +418,17 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement() return block; } -NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration() +template<typename FunctionNodeType> +NonnullRefPtr<FunctionNodeType> Parser::parse_function_node() { consume(TokenType::Function); - auto name = consume(TokenType::Identifier).value(); + String name; + if (FunctionNodeType::must_have_name()) { + name = consume(TokenType::Identifier).value(); + } else { + if (match(TokenType::Identifier)) + name = consume(TokenType::Identifier).value(); + } consume(TokenType::ParenOpen); Vector<String> parameters; while (match(TokenType::Identifier)) { @@ -432,7 +441,7 @@ NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration() } consume(TokenType::ParenClose); auto body = parse_block_statement(); - return create_ast_node<FunctionDeclaration>(name, move(body), move(parameters)); + return create_ast_node<FunctionNodeType>(name, move(body), move(parameters)); } NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration() @@ -526,6 +535,7 @@ bool Parser::match_expression() const || type == TokenType::CurlyOpen || type == TokenType::BracketOpen || type == TokenType::ParenOpen + || type == TokenType::Function || match_unary_prefixed_expression(); } |