Select Git revision
MeshDataBaseForTests.cpp
ASTNodeNaturalConversionChecker.cpp 3.05 KiB
#include <language/ast/ASTNodeNaturalConversionChecker.hpp>
#include <language/PEGGrammar.hpp>
#include <utils/Exceptions.hpp>
void
ASTNodeNaturalConversionChecker::_checkIsNaturalTypeConversion(const ASTNode& node,
const ASTNodeDataType& data_type,
const ASTNodeDataType& target_data_type) const
{
if (not isNaturalConversion(data_type, target_data_type)) {
std::ostringstream error_message;
error_message << "invalid implicit conversion: ";
error_message << rang::fgB::red << dataTypeName(data_type) << " -> " << dataTypeName(target_data_type)
<< rang::fg::reset;
if ((data_type == ASTNodeDataType::undefined_t) or (target_data_type == ASTNodeDataType::undefined_t)) {
throw UnexpectedError(error_message.str());
} else {
throw parse_error(error_message.str(), node.begin());
}
}
}
void
ASTNodeNaturalConversionChecker::_checkIsNaturalExpressionConversion(const ASTNode& node,
const ASTNodeDataType& data_type,
const ASTNodeDataType& target_data_type) const
{
if (target_data_type == ASTNodeDataType::vector_t) {
// Only R^d data is considered
switch (node.m_data_type) {
case ASTNodeDataType::list_t: {
if (node.children.size() != target_data_type.dimension()) {
throw parse_error("incompatible dimensions in affectation", std::vector{node.begin()});
}
for (const auto& child : node.children) {
this->_checkIsNaturalExpressionConversion(*child, child->m_data_type, ASTNodeDataType::double_t);
}
break;
}
case ASTNodeDataType::vector_t: {
if (data_type.dimension() != target_data_type.dimension()) {
throw parse_error("incompatible dimensions in affectation", std::vector{node.begin()});
}
break;
}
case ASTNodeDataType::int_t: {
if (node.is_type<language::integer>()) {
if (std::stoi(node.string()) == 0) {
break;
}
}
[[fallthrough]];
}
default: {
this->_checkIsNaturalTypeConversion(node, data_type, target_data_type);
}
}
} else {
this->_checkIsNaturalTypeConversion(node, data_type, target_data_type);
}
}
ASTNodeNaturalConversionChecker::ASTNodeNaturalConversionChecker(const ASTNode& data_node,
const ASTNodeDataType& target_data_type)
{
this->_checkIsNaturalExpressionConversion(data_node, data_node.m_data_type, target_data_type);
}
ASTNodeNaturalConversionChecker::ASTNodeNaturalConversionChecker(const ASTNodeSubDataType& data_node_sub_data_type,
const ASTNodeDataType& target_data_type)
{
this->_checkIsNaturalExpressionConversion(data_node_sub_data_type.m_parent_node, data_node_sub_data_type.m_data_type,
target_data_type);
}