diff --git a/src/language/ASTNodeAffectationExpressionBuilder.cpp b/src/language/ASTNodeAffectationExpressionBuilder.cpp index da39901cba81b76fe72db3652878e1b8f23e8439..50607980e2bdab299249979c9b8ec9437b9a321a 100644 --- a/src/language/ASTNodeAffectationExpressionBuilder.cpp +++ b/src/language/ASTNodeAffectationExpressionBuilder.cpp @@ -147,6 +147,58 @@ class AffectationProcessor final : public INodeProcessor } }; +template <typename OperatorT, typename DataT> +class AffectationToStringProcessor final : public INodeProcessor +{ + private: + Node& m_node; + DataVariant* p_value{nullptr}; + + static inline const bool _is_defined{[] { + if constexpr (std::is_same_v<OperatorT, language::bit_andeq_op> or + std::is_same_v<OperatorT, language::bit_xoreq_op> or std::is_same_v<OperatorT, language::bit_oreq_op>) + return false; + else { + return true; + } + }()}; + + public: + AffectationToStringProcessor(Node& node) : m_node{node} + { + if constexpr (_is_defined) { + const std::string& symbol = m_node.children[0]->string(); + auto [i_symbol, found] = m_node.m_symbol_table->find(symbol); + Assert(found); + p_value = &i_symbol->second.value(); + } else { + throw parse_error("invalid operands to binary expression", std::vector{m_node.begin()}); + } + } + + void + execute(ExecUntilBreakOrContinue& exec_policy) + { + if constexpr (_is_defined) { + 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)); + } + } + } + } +}; // namespace language + ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(Node& n) { auto set_affectation_processor = [](Node& n, const auto& operator_v) { @@ -176,6 +228,40 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(Node& n } }; + auto set_affectation_processor_for_string_data = [&](const DataType& data_type) { + using OperatorT = std::decay_t<decltype(operator_v)>; + + if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) { + switch (data_type) { + case DataType::bool_t: { + n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, bool>>(n); + break; + } + case DataType::unsigned_int_t: { + n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, uint64_t>>(n); + break; + } + case DataType::int_t: { + n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, int64_t>>(n); + break; + } + case DataType::double_t: { + n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, double>>(n); + break; + } + case DataType::string_t: { + n.m_node_processor = std::make_unique<AffectationToStringProcessor<OperatorT, std::string>>(n); + break; + } + default: { + throw parse_error("undefined operand type for affectation", std::vector{n.children[0]->begin()}); + } + } + } else { + throw parse_error("undefined operator type", std::vector{n.children[0]->begin()}); + } + }; + auto set_affectation_processor_for_value = [&](const DataType& value_type) { const DataType data_type = n.children[1]->m_data_type; switch (value_type) { @@ -195,6 +281,10 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(Node& n set_affectation_processor_for_data(double{}, data_type); break; } + case DataType::string_t: { + set_affectation_processor_for_string_data(data_type); + break; + } default: { throw parse_error("undefined value type for affectation", std::vector{n.begin()}); } diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp index cfbe4646caa01b8ddd59eb59f1cdab99862a6d2f..5696d752824beac0590f5fa5845a7b3db98645f8 100644 --- a/src/language/PugsParser.cpp +++ b/src/language/PugsParser.cpp @@ -613,9 +613,7 @@ print(const Node& n) } }, n.m_value); - std::cout << rang::fg::reset; - - std::cout << ")\n"; + std::cout << rang::fg::reset << ")\n"; if (not n.children.empty()) { print(n.children);