From ca8c171a1a8c4675a6cdf65ebc67104de0f96b2b Mon Sep 17 00:00:00 2001 From: Stephane Del Pino <stephane.delpino44@gmail.com> Date: Thu, 21 Nov 2019 16:38:00 +0100 Subject: [PATCH] Rewrite string affectations works also for strings being embedded into tuples --- .../ASTNodeAffectationExpressionBuilder.cpp | 11 ++- ...STNodeListAffectationExpressionBuilder.cpp | 84 +++++++++---------- .../node_processor/AffectationProcessor.hpp | 28 +++++-- .../AffectationToStringProcessor.hpp | 45 ---------- ...st_ASTNodeAffectationExpressionBuilder.cpp | 46 +++++----- 5 files changed, 90 insertions(+), 124 deletions(-) delete mode 100644 src/language/node_processor/AffectationToStringProcessor.hpp diff --git a/src/language/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ASTNodeAffectationExpressionBuilder.cpp index c515da24d..3475e2c00 100644 --- a/src/language/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeAffectationExpressionBuilder.cpp @@ -2,7 +2,6 @@ #include <PEGGrammar.hpp> #include <node_processor/AffectationProcessor.hpp> -#include <node_processor/AffectationToStringProcessor.hpp> ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n) { @@ -40,23 +39,23 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) { switch (data_type) { case ASTNodeDataType::bool_t: { - n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, bool>>(n); + n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, bool>>(n); break; } case ASTNodeDataType::unsigned_int_t: { - n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, uint64_t>>(n); + n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, uint64_t>>(n); break; } case ASTNodeDataType::int_t: { - n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, int64_t>>(n); + n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, int64_t>>(n); break; } case ASTNodeDataType::double_t: { - n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, double>>(n); + n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, double>>(n); break; } case ASTNodeDataType::string_t: { - n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, std::string>>(n); + n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, std::string>>(n); break; } default: { diff --git a/src/language/ASTNodeListAffectationExpressionBuilder.cpp b/src/language/ASTNodeListAffectationExpressionBuilder.cpp index 9850ca24a..da3473367 100644 --- a/src/language/ASTNodeListAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeListAffectationExpressionBuilder.cpp @@ -2,7 +2,6 @@ #include <PEGGrammar.hpp> #include <node_processor/AffectationProcessor.hpp> -#include <node_processor/AffectationToStringProcessor.hpp> template <typename OperatorT> void @@ -10,8 +9,8 @@ ASTNodeListAffectationExpressionBuilder::_buildListAffectationProcessor(ASTNode& { using ListAffectationProcessorT = ListAffectationProcessor<OperatorT>; - auto add_affectation_processor = [](ASTNode& value_node, ASTNode& data_node, - std::unique_ptr<ListAffectationProcessorT>& list_affectation_processor) { + auto add_affectation_processor = [&](ASTNode& value_node, ASTNode& data_node, + std::unique_ptr<ListAffectationProcessorT>& list_affectation_processor) { auto add_affectation_processor_for_data = [&](const auto& value, const ASTNodeDataType& data_type) { using ValueT = std::decay_t<decltype(value)>; switch (data_type) { @@ -37,38 +36,39 @@ ASTNodeListAffectationExpressionBuilder::_buildListAffectationProcessor(ASTNode& } }; - // auto add_affectation_processor_for_string_data = [&](const ASTNodeDataType& data_type) { - // if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) { - // switch (data_type) { - // case ASTNodeDataType::bool_t: { - // node.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, bool>>(node); - // break; - // } - // case ASTNodeDataType::unsigned_int_t: { - // node.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, uint64_t>>(node); - // break; - // } - // case ASTNodeDataType::int_t: { - // node.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, int64_t>>(node); - // break; - // } - // case ASTNodeDataType::double_t: { - // node.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, double>>(node); - // break; - // } - // case ASTNodeDataType::string_t: { - // node.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, std::string>>(node); - // break; - // } - // default: { - // throw parse_error("unexpected error: undefined operand type for string affectation", - // std::vector{node.children[1]->begin()}); - // } - // } - // } else { - // throw parse_error("unexpected error: undefined operator type", std::vector{node.children[0]->begin()}); - // } - // }; + auto add_affectation_processor_for_string_data = [&](const ASTNodeDataType& data_type) { + if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) { + switch (data_type) { + case ASTNodeDataType::bool_t: { + list_affectation_processor->template add<std::string, bool>(value_node, data_node); + break; + } + case ASTNodeDataType::unsigned_int_t: { + list_affectation_processor->template add<std::string, uint64_t>(value_node, data_node); + break; + } + case ASTNodeDataType::int_t: { + list_affectation_processor->template add<std::string, int64_t>(value_node, data_node); + break; + } + case ASTNodeDataType::double_t: { + list_affectation_processor->template add<std::string, double>(value_node, data_node); + break; + } + case ASTNodeDataType::string_t: { + list_affectation_processor->template add<std::string, std::string>(value_node, data_node); + break; + } + default: { + throw parse_error("unexpected error: undefined operand type for string affectation", + std::vector{data_node.begin()}); + } + } + } else { + throw parse_error("unexpected error: undefined operator type for string affectation", + std::vector{node.begin()}); + } + }; auto add_affectation_processor_for_value = [&](const ASTNodeDataType& value_type, const ASTNodeDataType& data_type) { @@ -90,12 +90,12 @@ ASTNodeListAffectationExpressionBuilder::_buildListAffectationProcessor(ASTNode& break; } case ASTNodeDataType::string_t: { - // add_affectation_processor_for_string_data(data_type); - throw parse_error("unexpected error: string in list NIY", std::vector{value_node.begin()}); + add_affectation_processor_for_string_data(data_type); break; } default: { - throw parse_error("unexpected error: undefined value type for affectation", std::vector{value_node.begin()}); + throw parse_error("unexpected error: undefined value type for tuple affectation", + std::vector{value_node.begin()}); } } }; @@ -127,20 +127,16 @@ ASTNodeListAffectationExpressionBuilder::ASTNodeListAffectationExpressionBuilder if (n.children[1]->is_type<language::expression_list>()) { if (n.is_type<language::eq_op>()) { this->_buildListAffectationProcessor<language::eq_op>(n); - } else if (n.is_type<language::multiplyeq_op>()) { - this->_buildListAffectationProcessor<language::multiplyeq_op>(n); - } else if (n.is_type<language::divideeq_op>()) { - this->_buildListAffectationProcessor<language::divideeq_op>(n); } else if (n.is_type<language::pluseq_op>()) { this->_buildListAffectationProcessor<language::pluseq_op>(n); } else if (n.is_type<language::minuseq_op>()) { this->_buildListAffectationProcessor<language::minuseq_op>(n); } else { - throw parse_error("unexpected error: undefined affectation operator", std::vector{n.begin()}); + throw parse_error("undefined affectation operator for tuples", std::vector{n.begin()}); } } else { - throw parse_error("unexpected error: invalid right hand side in list affectation", + throw parse_error("unexpected error: invalid right hand side in tuple affectation", std::vector{n.children[1]->begin()}); } } diff --git a/src/language/node_processor/AffectationProcessor.hpp b/src/language/node_processor/AffectationProcessor.hpp index b22af5df3..a538c351a 100644 --- a/src/language/node_processor/AffectationProcessor.hpp +++ b/src/language/node_processor/AffectationProcessor.hpp @@ -86,14 +86,31 @@ class AffectationExecutor final : public IAffectationExecutor execute() { if constexpr (_is_defined) { - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<ValueT, DataT>) { - *m_lhs = *m_rhs; + if constexpr (std::is_same_v<ValueT, std::string>) { + if constexpr (std::is_same_v<OperatorT, language::eq_op>) { + if constexpr (std::is_same_v<std::string, DataT>) { + *m_lhs = *m_rhs; + } else { + *m_lhs = std::to_string(std::get<DataT>(*m_rhs)); + } } else { - *m_lhs = static_cast<ValueT>(std::get<DataT>(*m_rhs)); + static_assert(std::is_same_v<OperatorT, language::pluseq_op>, "unexpected operator type"); + if constexpr (std::is_same_v<std::string, DataT>) { + std::get<std::string>(*m_lhs) += std::get<std::string>(*m_rhs); + } else { + std::get<std::string>(*m_lhs) += std::to_string(std::get<DataT>(*m_rhs)); + } } } else { - AffOp<OperatorT>().eval(std::get<ValueT>(*m_lhs), std::get<DataT>(*m_rhs)); + if constexpr (std::is_same_v<OperatorT, language::eq_op>) { + if constexpr (std::is_same_v<ValueT, DataT>) { + *m_lhs = *m_rhs; + } else { + *m_lhs = static_cast<ValueT>(std::get<DataT>(*m_rhs)); + } + } else { + AffOp<OperatorT>().eval(std::get<ValueT>(*m_lhs), std::get<DataT>(*m_rhs)); + } } } } @@ -106,7 +123,6 @@ class AffectationProcessor final : public INodeProcessor ASTNode& m_node; using AffectationExecutorT = AffectationExecutor<OperatorT, ValueT, DataT>; - std::unique_ptr<AffectationExecutorT> m_affectation_executor; public: diff --git a/src/language/node_processor/AffectationToStringProcessor.hpp b/src/language/node_processor/AffectationToStringProcessor.hpp deleted file mode 100644 index 7c22c095d..000000000 --- a/src/language/node_processor/AffectationToStringProcessor.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef AFFECTATION_TO_STRING_PROCESSOR_HPP -#define AFFECTATION_TO_STRING_PROCESSOR_HPP - -#include <node_processor/INodeProcessor.hpp> - -#include <SymbolTable.hpp> - -template <typename OperatorT, typename DataT> -class AffectationToStringProcessor final : public INodeProcessor -{ - private: - ASTNode& m_node; - ASTNodeDataVariant* p_value{nullptr}; - - public: - void - execute(ExecUntilBreakOrContinue& exec_policy) - { - m_node.children[1]->execute(exec_policy); - - if constexpr (std::is_same_v<OperatorT, language::eq_op>) { - if constexpr (std::is_same_v<std::string, DataT>) { - *p_value = m_node.children[1]->m_value; - } else { - *p_value = std::to_string(std::get<DataT>(m_node.children[1]->m_value)); - } - } else if constexpr (std::is_same_v<OperatorT, language::pluseq_op>) { - if constexpr (std::is_same_v<std::string, DataT>) { - std::get<std::string>(*p_value) += std::get<std::string>(m_node.children[1]->m_value); - } else { - std::get<std::string>(*p_value) += std::to_string(std::get<DataT>(m_node.children[1]->m_value)); - } - } - } - - AffectationToStringProcessor(ASTNode& node) : m_node{node} - { - const std::string& symbol = m_node.children[0]->string(); - auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin()); - Assert(found); - p_value = &i_symbol->attributes().value(); - } -}; - -#endif // AFFECTATION_TO_STRING_PROCESSOR_HPP diff --git a/tests/test_ASTNodeAffectationExpressionBuilder.cpp b/tests/test_ASTNodeAffectationExpressionBuilder.cpp index 9758fbbb1..cdceab453 100644 --- a/tests/test_ASTNodeAffectationExpressionBuilder.cpp +++ b/tests/test_ASTNodeAffectationExpressionBuilder.cpp @@ -46,6 +46,8 @@ TEST_CASE("ASTNodeAffectationExpressionBuilder", "[language]") { + const std::string demangled_stdstring = demangle(typeid(std::string{}).name()); + SECTION("Affectations") { SECTION("boolean affectation") @@ -381,9 +383,10 @@ R r="foo"; string s=true; )"; - std::string_view result = R"( + std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, bool>) + `-(language::eq_op:AffectationProcessor<language::eq_op, )" + + demangled_stdstring + R"(, bool>) +-(language::name:s:NameProcessor) `-(language::true_kw:FakeProcessor) )"; @@ -397,9 +400,10 @@ string s=true; N n; string s=n; )"; - std::string_view result = R"( + std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, unsigned long>) + `-(language::eq_op:AffectationProcessor<language::eq_op, )" + + demangled_stdstring + R"(, unsigned long>) +-(language::name:s:NameProcessor) `-(language::name:n:NameProcessor) )"; @@ -413,9 +417,11 @@ N n; string s=n; Z z; string s=z; )"; - std::string_view result = R"( + std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, long>) + `-(language::eq_op:AffectationProcessor<language::eq_op, )" + + demangled_stdstring + + R"(, long>) +-(language::name:s:NameProcessor) `-(language::name:z:NameProcessor) )"; @@ -429,9 +435,11 @@ Z z; string s=z; R r; string s=r; )"; - std::string_view result = R"( + std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, double>) + `-(language::eq_op:AffectationProcessor<language::eq_op, )" + + demangled_stdstring + + R"(, double>) +-(language::name:s:NameProcessor) `-(language::name:r:NameProcessor) )"; @@ -445,12 +453,10 @@ R r; string s=r; string s="foo"; )"; - std::string string_name = demangle(typeid(std::string{}).name()); - std::string result = R"( (root:ASTNodeListProcessor) - `-(language::eq_op:AffectationToStringProcessor<language::eq_op, )" + - string_name + R"( >) + `-(language::eq_op:AffectationProcessor<language::eq_op, )" + + demangled_stdstring + ", " + demangled_stdstring + R"( >) +-(language::name:s:NameProcessor) `-(language::literal:"foo":FakeProcessor) )"; @@ -506,15 +512,15 @@ R x=1; x+=2; string s="foo"; s+=2; )"; - std::string string_name = demangle(typeid(std::string{}).name()); - std::string result = R"( (root:ASTNodeListProcessor) - +-(language::eq_op:AffectationToStringProcessor<language::eq_op, )" + - string_name + R"( >) + +-(language::eq_op:AffectationProcessor<language::eq_op, )" + + demangled_stdstring + ", " + demangled_stdstring + R"( >) | +-(language::name:s:NameProcessor) | `-(language::literal:"foo":FakeProcessor) - `-(language::pluseq_op:AffectationToStringProcessor<language::pluseq_op, long>) + `-(language::pluseq_op:AffectationProcessor<language::pluseq_op, )" + + demangled_stdstring + + R"(, long>) +-(language::name:s:NameProcessor) `-(language::integer:2:FakeProcessor) )"; @@ -569,8 +575,6 @@ R x=1; x-=2.3; string s="foo"; s-="bar"; )"; - std::string string_name = demangle(typeid(std::string{}).name()); - string_input input{data, "test.pgs"}; auto ast = ASTBuilder::build(input); @@ -631,8 +635,6 @@ R x=1; x*=2.3; string s="foo"; s*=2; )"; - std::string string_name = demangle(typeid(std::string{}).name()); - string_input input{data, "test.pgs"}; auto ast = ASTBuilder::build(input); @@ -693,8 +695,6 @@ R x=1; x/=2.3; string s="foo"; s/="bar"; )"; - std::string string_name = demangle(typeid(std::string{}).name()); - string_input input{data, "test.pgs"}; auto ast = ASTBuilder::build(input); -- GitLab