diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.cpp b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.cpp index 842c4922..a553e5c4 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.cpp +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.cpp @@ -9,27 +9,22 @@ SequenceArchitecture::SequenceArchitecture() AddMatchers({ create.Keyword("architecture"), - create.Or({ - create.Keyword("x86").Tag(TAG_X86), - create.Keyword("x64").Tag(TAG_X64) - }), + create.Identifier().Capture(CAPTURE_ARCHITECTURE), create.Char(';') }); + + m_architecture_mapping["x86"] = Architecture::X86; + m_architecture_mapping["x64"] = Architecture::X64; } void SequenceArchitecture::ProcessMatch(CommandsParserState* state, SequenceResult& result) const { - switch (result.NextTag()) - { - case TAG_X86: - state->SetArchitecture(Architecture::X86); - break; + const auto& architectureToken = result.NextCapture(CAPTURE_ARCHITECTURE); - case TAG_X64: - state->SetArchitecture(Architecture::X64); - break; + const auto foundArchitecture = m_architecture_mapping.find(architectureToken.IdentifierValue()); - default: - throw ParsingException(TokenPos(), "Unknown architecture!"); - } + if(foundArchitecture == m_architecture_mapping.end()) + throw ParsingException(architectureToken.GetPos(), "Unknown architecture"); + + state->SetArchitecture(foundArchitecture->second); } diff --git a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.h b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.h index a9f19f92..4dd0b5bd 100644 --- a/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.h +++ b/src/ZoneCodeGeneratorLib/Parsing/Commands/Sequence/SequenceArchitecture.h @@ -4,8 +4,9 @@ class SequenceArchitecture final : public CommandsParser::sequence_t { - static constexpr auto TAG_X86 = 1; - static constexpr auto TAG_X64 = 2; + static constexpr auto CAPTURE_ARCHITECTURE = 1; + + std::unordered_map m_architecture_mapping; protected: void ProcessMatch(CommandsParserState* state, SequenceResult& result) const override; diff --git a/test/ZoneCodeGeneratorLibTests/Parsing/Commands/Sequence/SequenceArchitectureTests.cpp b/test/ZoneCodeGeneratorLibTests/Parsing/Commands/Sequence/SequenceArchitectureTests.cpp index e69de29b..a00f2118 100644 --- a/test/ZoneCodeGeneratorLibTests/Parsing/Commands/Sequence/SequenceArchitectureTests.cpp +++ b/test/ZoneCodeGeneratorLibTests/Parsing/Commands/Sequence/SequenceArchitectureTests.cpp @@ -0,0 +1,89 @@ +#include + +#include "Utils/ClassUtils.h" +#include "Parsing/Commands/Sequence/SequenceArchitecture.h" +#include "Parsing/Mock/MockLexer.h" +#include "Persistence/InMemory/InMemoryRepository.h" + +namespace test::parsing::commands::sequence::sequence_architecture +{ + class CommandsSequenceTestsHelper + { + public: + std::unique_ptr m_repository; + std::unique_ptr m_state; + std::unique_ptr> m_lexer; + + unsigned m_consumed_token_count; + + CommandsSequenceTestsHelper() + : m_repository(std::make_unique()), + m_state(std::make_unique(m_repository.get())), + m_consumed_token_count(0u) + { + } + + void Tokens(std::initializer_list> tokens) + { + m_lexer = std::make_unique>(tokens, CommandsParserValue::EndOfFile(TokenPos())); + } + + bool PerformTest() + { + REQUIRE(m_lexer); + const auto sequence = std::make_unique(); + return sequence->MatchSequence(m_lexer.get(), m_state.get(), m_consumed_token_count); + } + }; + + TEST_CASE("SequenceAction: Ensure can set x86", "[parsing][parsingstream]") + { + CommandsSequenceTestsHelper helper; + const TokenPos pos; + helper.Tokens({ + CommandsParserValue::Identifier(pos, new std::string("architecture")), + CommandsParserValue::Identifier(pos, new std::string("x86")), + CommandsParserValue::Character(pos, ';'), + CommandsParserValue::EndOfFile(pos) + }); + + auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 3); + REQUIRE(helper.m_repository->GetArchitecture() == Architecture::X86); + } + + TEST_CASE("SequenceAction: Ensure can set x64", "[parsing][parsingstream]") + { + CommandsSequenceTestsHelper helper; + const TokenPos pos; + helper.Tokens({ + CommandsParserValue::Identifier(pos, new std::string("architecture")), + CommandsParserValue::Identifier(pos, new std::string("x86")), + CommandsParserValue::Character(pos, ';'), + CommandsParserValue::EndOfFile(pos) + }); + + auto result = helper.PerformTest(); + + REQUIRE(result); + REQUIRE(helper.m_consumed_token_count == 3); + REQUIRE(helper.m_repository->GetArchitecture() == Architecture::X86); + } + + TEST_CASE("SequenceAction: Ensure cannot match unknown value", "[parsing][parsingstream]") + { + CommandsSequenceTestsHelper helper; + const TokenPos pos; + helper.Tokens({ + CommandsParserValue::Identifier(pos, new std::string("architecture")), + CommandsParserValue::Identifier(pos, new std::string("x1337")), + CommandsParserValue::Character(pos, ';'), + CommandsParserValue::EndOfFile(pos) + }); + + REQUIRE_THROWS_AS(helper.PerformTest(), ParsingException); + REQUIRE(helper.m_repository->GetArchitecture() == Architecture::UNKNOWN); + } +}