From a9f3a14a13fabd35918ff82ebef9f3c017512b59 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Sun, 21 Jan 2024 14:34:41 -0500 Subject: [PATCH] JSSpecCompiler: Simplify value handling in TextParser::parse_expression --- .../JSSpecCompiler/Parser/TextParser.cpp | 86 ++++++++++--------- .../JSSpecCompiler/Parser/TextParser.h | 1 + 2 files changed, 48 insertions(+), 39 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp index 1e1f9a7df0..1330cf0ff1 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.cpp @@ -118,7 +118,7 @@ TextParseErrorOr TextParser::expect_eof() return {}; } -// (the)? { (: ,)* } +// :== (the)? { (: ,)* } TextParseErrorOr TextParser::parse_record_direct_list_initialization() { auto rollback = rollback_point(); @@ -194,16 +194,52 @@ TextParseErrorOr TextParser::parse_list_initialization() return make_ref_counted(move(elements)); } +// :== | | | | | | +TextParseErrorOr TextParser::parse_value() +{ + if (auto identifier = consume_token_with_type(TokenType::Identifier); !identifier.is_error()) + return make_ref_counted(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(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(MUST(Crypto::BigFraction::from_string(number.value().data))); + + if (auto string = consume_token_with_type(TokenType::String); !string.is_error()) + return make_ref_counted(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 {}; +} + // TextParseErrorOr 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 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 TextParser::parse_expression() stack.append(token); } } else { - NullableTree expression; - if (token.type == TokenType::Identifier) { - expression = make_ref_counted(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(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(MUST(Crypto::BigFraction::from_string(token.data))); - } else if (token.type == TokenType::String) { - expression = make_ref_counted(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) diff --git a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h index 4457ea4435..c1a6655525 100644 --- a/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h +++ b/Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Parser/TextParser.h @@ -74,6 +74,7 @@ private: TextParseErrorOr parse_record_direct_list_initialization(); TextParseErrorOr> parse_function_arguments(); TextParseErrorOr parse_list_initialization(); + TextParseErrorOr parse_value(); TextParseErrorOr parse_expression(); TextParseErrorOr parse_condition(); TextParseErrorOr parse_return_statement();