mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
JSSpecCompiler: Simplify value handling in TextParser::parse_expression
This commit is contained in:
parent
e1a1f4ed1a
commit
a9f3a14a13
Notes:
sideshowbarker
2024-07-17 07:25:39 +09:00
Author: https://github.com/DanShaders Commit: https://github.com/SerenityOS/serenity/commit/a9f3a14a13 Pull-request: https://github.com/SerenityOS/serenity/pull/23123 Reviewed-by: https://github.com/ADKaster ✅
2 changed files with 48 additions and 39 deletions
|
@ -118,7 +118,7 @@ TextParseErrorOr<void> TextParser::expect_eof()
|
|||
return {};
|
||||
}
|
||||
|
||||
// (the)? <record_name> { (<name>: <value>,)* }
|
||||
// <record_initialization> :== (the)? <record_name> { (<name>: <value>,)* }
|
||||
TextParseErrorOr<Tree> TextParser::parse_record_direct_list_initialization()
|
||||
{
|
||||
auto rollback = rollback_point();
|
||||
|
@ -194,16 +194,52 @@ TextParseErrorOr<Tree> TextParser::parse_list_initialization()
|
|||
return make_ref_counted<List>(move(elements));
|
||||
}
|
||||
|
||||
// <value> :== <identifier> | <well_known_value> | <enumerator> | <number> | <string> | <list_initialization> | <record_initialization>
|
||||
TextParseErrorOr<Tree> TextParser::parse_value()
|
||||
{
|
||||
if (auto identifier = consume_token_with_type(TokenType::Identifier); !identifier.is_error())
|
||||
return make_ref_counted<UnresolvedReference>(identifier.release_value().data);
|
||||
|
||||
if (auto well_known_value = consume_token_with_type(TokenType::WellKnownValue); !well_known_value.is_error()) {
|
||||
static constexpr struct {
|
||||
StringView name;
|
||||
WellKnownNode::Type type;
|
||||
} translations[] = {
|
||||
{ "false"sv, WellKnownNode::Type::False },
|
||||
{ "null"sv, WellKnownNode::Type::Null },
|
||||
{ "this"sv, WellKnownNode::Type::This },
|
||||
{ "true"sv, WellKnownNode::Type::True },
|
||||
{ "undefined"sv, WellKnownNode::Type::Undefined },
|
||||
};
|
||||
for (auto [name, type] : translations)
|
||||
if (well_known_value.value().data == name)
|
||||
return make_ref_counted<WellKnownNode>(type);
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
if (auto enumerator = consume_token_with_type(TokenType::Enumerator); !enumerator.is_error())
|
||||
return m_ctx.translation_unit()->get_node_for_enumerator_value(enumerator.value().data);
|
||||
|
||||
if (auto number = consume_token_with_type(TokenType::Number); !number.is_error())
|
||||
return make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(number.value().data)));
|
||||
|
||||
if (auto string = consume_token_with_type(TokenType::String); !string.is_error())
|
||||
return make_ref_counted<StringLiteral>(string.value().data);
|
||||
|
||||
if (auto list_initialization = parse_list_initialization(); !list_initialization.is_error())
|
||||
return list_initialization.release_value();
|
||||
|
||||
if (auto record_initialization = parse_record_direct_list_initialization(); !record_initialization.is_error())
|
||||
return record_initialization.release_value();
|
||||
|
||||
return TextParseError {};
|
||||
}
|
||||
|
||||
// <expr>
|
||||
TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||
{
|
||||
auto rollback = rollback_point();
|
||||
|
||||
if (auto record_init = parse_record_direct_list_initialization(); !record_init.is_error()) {
|
||||
rollback.disarm();
|
||||
return record_init.release_value();
|
||||
}
|
||||
|
||||
#define THROW_PARSE_ERROR_IF(expr) \
|
||||
do { \
|
||||
if (expr) { \
|
||||
|
@ -320,9 +356,6 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
|
|||
// This is just an opening '(' in expression.
|
||||
stack.append(token);
|
||||
}
|
||||
} else if (token.type == TokenType::ListStart) {
|
||||
stack.append(TRY(parse_list_initialization()));
|
||||
is_consumed = true;
|
||||
} else if (token.is_pre_merged_binary_operator()) {
|
||||
THROW_PARSE_ERROR_IF(last_element_type != ExpressionType);
|
||||
stack.append(token);
|
||||
|
@ -345,39 +378,14 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
|
|||
stack.append(token);
|
||||
}
|
||||
} else {
|
||||
NullableTree expression;
|
||||
if (token.type == TokenType::Identifier) {
|
||||
expression = make_ref_counted<UnresolvedReference>(token.data);
|
||||
} else if (token.type == TokenType::WellKnownValue) {
|
||||
static constexpr struct {
|
||||
StringView name;
|
||||
WellKnownNode::Type type;
|
||||
} translations[] = {
|
||||
{ "false"sv, WellKnownNode::Type::False },
|
||||
{ "null"sv, WellKnownNode::Type::Null },
|
||||
{ "this"sv, WellKnownNode::Type::This },
|
||||
{ "true"sv, WellKnownNode::Type::True },
|
||||
{ "undefined"sv, WellKnownNode::Type::Undefined },
|
||||
};
|
||||
for (auto [name, type] : translations) {
|
||||
if (token.data == name) {
|
||||
expression = make_ref_counted<WellKnownNode>(type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
VERIFY(expression);
|
||||
} else if (token.type == TokenType::Enumerator) {
|
||||
expression = m_ctx.translation_unit()->get_node_for_enumerator_value(token.data);
|
||||
} else if (token.type == TokenType::Number) {
|
||||
expression = make_ref_counted<MathematicalConstant>(MUST(Crypto::BigFraction::from_string(token.data)));
|
||||
} else if (token.type == TokenType::String) {
|
||||
expression = make_ref_counted<StringLiteral>(token.data);
|
||||
if (auto expression = parse_value(); !expression.is_error()) {
|
||||
is_consumed = true;
|
||||
THROW_PARSE_ERROR_IF(last_element_type == ExpressionType);
|
||||
stack.append(expression.release_value());
|
||||
merge_pre_merged();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
THROW_PARSE_ERROR_IF(last_element_type == ExpressionType);
|
||||
stack.append(expression.release_nonnull());
|
||||
merge_pre_merged();
|
||||
}
|
||||
|
||||
if (!is_consumed)
|
||||
|
|
|
@ -74,6 +74,7 @@ private:
|
|||
TextParseErrorOr<Tree> parse_record_direct_list_initialization();
|
||||
TextParseErrorOr<Vector<Tree>> parse_function_arguments();
|
||||
TextParseErrorOr<Tree> parse_list_initialization();
|
||||
TextParseErrorOr<Tree> parse_value();
|
||||
TextParseErrorOr<Tree> parse_expression();
|
||||
TextParseErrorOr<Tree> parse_condition();
|
||||
TextParseErrorOr<Tree> parse_return_statement();
|
||||
|
|
Loading…
Reference in a new issue