Select Git revision
ASTNodeAffectationExpressionBuilder.cpp
ASTNodeAffectationExpressionBuilder.cpp 2.40 KiB
#include <language/ast/ASTNodeAffectationExpressionBuilder.hpp>
#include <algebra/TinyVector.hpp>
#include <language/PEGGrammar.hpp>
#include <language/node_processor/INodeProcessor.hpp>
#include <language/utils/ASTNodeNaturalConversionChecker.hpp>
#include <language/utils/AffectationMangler.hpp>
#include <language/utils/OperatorRepository.hpp>
#include <language/utils/ParseError.hpp>
#include <utils/Exceptions.hpp>
ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& node)
{
const ASTNodeDataType& target_data_type = node.children[0]->m_data_type;
const ASTNodeDataType& source_data_type = node.children[1]->m_data_type;
const std::string affectation_name = [&] {
if (node.is_type<language::eq_op>()) {
return affectationMangler<language::eq_op>(target_data_type, source_data_type);
} else if (node.is_type<language::multiplyeq_op>()) {
return affectationMangler<language::multiplyeq_op>(target_data_type, source_data_type);
} else if (node.is_type<language::divideeq_op>()) {
return affectationMangler<language::divideeq_op>(target_data_type, source_data_type);
} else if (node.is_type<language::pluseq_op>()) {
return affectationMangler<language::pluseq_op>(target_data_type, source_data_type);
} else if (node.is_type<language::minuseq_op>()) {
return affectationMangler<language::minuseq_op>(target_data_type, source_data_type);
} else {
throw ParseError("unexpected error: undefined affectation operator", std::vector{node.begin()});
}
}();
const auto& optional_processor_builder =
OperatorRepository::instance().getAffectationProcessorBuilder(affectation_name);
if (optional_processor_builder.has_value()) {
ASTNode& lhs_node = *node.children[0];
ASTNode& rhs_node = *node.children[1];
if (rhs_node.m_data_type == ASTNodeDataType::list_t) {
if ((lhs_node.m_data_type == ASTNodeDataType::vector_t) or (lhs_node.m_data_type == ASTNodeDataType::matrix_t)) {
ASTNodeNaturalConversionChecker(rhs_node, lhs_node.m_data_type);
}
}
node.m_node_processor = optional_processor_builder.value()->getNodeProcessor(lhs_node, rhs_node);
} else {
std::ostringstream error_message;
error_message << "undefined affectation type: ";
error_message << rang::fgB::red << affectation_name << rang::fg::reset;
throw ParseError(error_message.str(), std::vector{node.children[0]->begin()});
}
}