mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 02:08:11 +00:00
JSSpecCompiler: Simplify value handling in TextParser::parse_expression
This commit is contained in:
parent
e1a1f4ed1a
commit
a9f3a14a13
2 changed files with 48 additions and 39 deletions
|
@ -118,7 +118,7 @@ TextParseErrorOr<void> TextParser::expect_eof()
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// (the)? <record_name> { (<name>: <value>,)* }
|
// <record_initialization> :== (the)? <record_name> { (<name>: <value>,)* }
|
||||||
TextParseErrorOr<Tree> TextParser::parse_record_direct_list_initialization()
|
TextParseErrorOr<Tree> TextParser::parse_record_direct_list_initialization()
|
||||||
{
|
{
|
||||||
auto rollback = rollback_point();
|
auto rollback = rollback_point();
|
||||||
|
@ -194,16 +194,52 @@ TextParseErrorOr<Tree> TextParser::parse_list_initialization()
|
||||||
return make_ref_counted<List>(move(elements));
|
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>
|
// <expr>
|
||||||
TextParseErrorOr<Tree> TextParser::parse_expression()
|
TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||||
{
|
{
|
||||||
auto rollback = rollback_point();
|
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) \
|
#define THROW_PARSE_ERROR_IF(expr) \
|
||||||
do { \
|
do { \
|
||||||
if (expr) { \
|
if (expr) { \
|
||||||
|
@ -320,9 +356,6 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||||
// This is just an opening '(' in expression.
|
// This is just an opening '(' in expression.
|
||||||
stack.append(token);
|
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()) {
|
} else if (token.is_pre_merged_binary_operator()) {
|
||||||
THROW_PARSE_ERROR_IF(last_element_type != ExpressionType);
|
THROW_PARSE_ERROR_IF(last_element_type != ExpressionType);
|
||||||
stack.append(token);
|
stack.append(token);
|
||||||
|
@ -345,39 +378,14 @@ TextParseErrorOr<Tree> TextParser::parse_expression()
|
||||||
stack.append(token);
|
stack.append(token);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
NullableTree expression;
|
if (auto expression = parse_value(); !expression.is_error()) {
|
||||||
if (token.type == TokenType::Identifier) {
|
is_consumed = true;
|
||||||
expression = make_ref_counted<UnresolvedReference>(token.data);
|
THROW_PARSE_ERROR_IF(last_element_type == ExpressionType);
|
||||||
} else if (token.type == TokenType::WellKnownValue) {
|
stack.append(expression.release_value());
|
||||||
static constexpr struct {
|
merge_pre_merged();
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
THROW_PARSE_ERROR_IF(last_element_type == ExpressionType);
|
|
||||||
stack.append(expression.release_nonnull());
|
|
||||||
merge_pre_merged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_consumed)
|
if (!is_consumed)
|
||||||
|
|
|
@ -74,6 +74,7 @@ private:
|
||||||
TextParseErrorOr<Tree> parse_record_direct_list_initialization();
|
TextParseErrorOr<Tree> parse_record_direct_list_initialization();
|
||||||
TextParseErrorOr<Vector<Tree>> parse_function_arguments();
|
TextParseErrorOr<Vector<Tree>> parse_function_arguments();
|
||||||
TextParseErrorOr<Tree> parse_list_initialization();
|
TextParseErrorOr<Tree> parse_list_initialization();
|
||||||
|
TextParseErrorOr<Tree> parse_value();
|
||||||
TextParseErrorOr<Tree> parse_expression();
|
TextParseErrorOr<Tree> parse_expression();
|
||||||
TextParseErrorOr<Tree> parse_condition();
|
TextParseErrorOr<Tree> parse_condition();
|
||||||
TextParseErrorOr<Tree> parse_return_statement();
|
TextParseErrorOr<Tree> parse_return_statement();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue