Skip to content
Snippets Groups Projects
Select Git revision
  • 767f6549c51d25271073ed296b2b7d478ca917ad
  • develop default protected
  • feature/variational-hydro
  • origin/stage/bouguettaia
  • feature/gmsh-reader
  • feature/reconstruction
  • save_clemence
  • feature/kinetic-schemes
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

ASTNodeAffectationExpressionBuilder.cpp

Blame
  • ASTNodeAffectationExpressionBuilder.cpp 11.92 KiB
    #include <ASTNodeAffectationExpressionBuilder.hpp>
    #include <PEGGrammar.hpp>
    
    #include <ASTNodeNaturalConversionChecker.hpp>
    
    #include <node_processor/AffectationProcessor.hpp>
    
    #include <../algebra/TinyVector.hpp>
    
    ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n)
    {
      auto set_affectation_processor = [](ASTNode& n, const auto& operator_v) {
        auto set_affectation_processor_for_data = [&](const auto& value, const ASTNodeDataType& data_type) {
          using OperatorT = std::decay_t<decltype(operator_v)>;
          using ValueT    = std::decay_t<decltype(value)>;
    
          switch (data_type) {
          case ASTNodeDataType::bool_t: {
            n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n);
            break;
          }
          case ASTNodeDataType::unsigned_int_t: {
            n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, uint64_t>>(n);
            break;
          }
          case ASTNodeDataType::int_t: {
            n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n);
            break;
          }
          case ASTNodeDataType::double_t: {
            n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, double>>(n);
            break;
          }
            // LCOV_EXCL_START
          default: {
            throw parse_error("unexpected error: undefined operand type for affectation",
                              std::vector{n.children[1]->begin()});
          }
            // LCOV_EXCL_STOP
          }
        };
    
        auto set_affectation_processor_for_vector_data = [&](const auto& value, const ASTNodeDataType& data_type) {
          using OperatorT = std::decay_t<decltype(operator_v)>;
          using ValueT    = std::decay_t<decltype(value)>;
    
          if constexpr (std::is_same_v<OperatorT, language::eq_op>) {
            switch (data_type) {
            case ASTNodeDataType::vector_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, ValueT>>(n);
              break;
            }
            case ASTNodeDataType::list_t: {
              n.m_node_processor = std::make_unique<AffectationFromListProcessor<OperatorT, ValueT>>(n);
              break;
            }
            case ASTNodeDataType::bool_t: {
              if constexpr (std::is_same_v<ValueT, TinyVector<1>>) {
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n);
                break;
              }
            }
            case ASTNodeDataType::unsigned_int_t: {
              if constexpr (std::is_same_v<ValueT, TinyVector<1>>) {
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, uint64_t>>(n);
                break;
              }
            }
            case ASTNodeDataType::int_t: {
              if constexpr (std::is_same_v<ValueT, TinyVector<1>>) {
                if (n.children[1]->is_type<language::integer>()) {
                  if (std::stoi(n.children[1]->string()) == 0) {
                    n.m_node_processor = std::make_unique<AffectationFromZeroProcessor<ValueT>>(n);
                    break;
                  }
                }
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n);
                break;
              } else if (n.children[1]->is_type<language::integer>()) {
                if (std::stoi(n.children[1]->string()) == 0) {
                  n.m_node_processor = std::make_unique<AffectationFromZeroProcessor<ValueT>>(n);
                  break;
                }
              }
              // LCOV_EXCL_START
              throw parse_error("unexpected error: invalid integral value", std::vector{n.children[1]->begin()});
              // LCOV_EXCL_STOP
            }
            case ASTNodeDataType::double_t: {
              if constexpr (std::is_same_v<ValueT, TinyVector<1>>) {
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, double>>(n);
                break;
              }
            }
              // LCOV_EXCL_START
            default: {
              throw parse_error("unexpected error: invalid operand type", std::vector{n.children[1]->begin()});
            }
              // LCOV_EXCL_STOP
            }
          } else if constexpr (std::is_same_v<OperatorT, language::pluseq_op> or
                               std::is_same_v<OperatorT, language::minuseq_op>) {
            switch (data_type) {
            case ASTNodeDataType::vector_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, ValueT>>(n);
              break;
            }
              // LCOV_EXCL_START
            default: {
              throw parse_error("unexpected error: invalid operand type", std::vector{n.children[1]->begin()});
            }
              // LCOV_EXCL_STOP
            }
          } else if constexpr (std::is_same_v<OperatorT, language::multiplyeq_op>) {
            switch (data_type) {
            case ASTNodeDataType::bool_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, bool>>(n);
              break;
            }
            case ASTNodeDataType::unsigned_int_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, uint64_t>>(n);
              break;
            }
            case ASTNodeDataType::int_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, int64_t>>(n);
              break;
            }
            case ASTNodeDataType::double_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, double>>(n);
              break;
            }
            default: {
              throw parse_error("expecting scalar operand type", std::vector{n.children[1]->begin()});
            }
            }
          } else {
            throw parse_error("invalid affectation operator for " + dataTypeName(n.m_data_type), std::vector{n.begin()});
          }
        };
    
        auto set_affectation_processor_for_string_data = [&](const ASTNodeDataType& 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 ASTNodeDataType::bool_t: {
              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<AffectationProcessor<OperatorT, std::string, uint64_t>>(n);
              break;
            }
            case ASTNodeDataType::int_t: {
              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<AffectationProcessor<OperatorT, std::string, double>>(n);
              break;
            }
            case ASTNodeDataType::string_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, std::string>>(n);
              break;
            }
            case ASTNodeDataType::vector_t: {
              switch (data_type.dimension()) {
              case 1: {
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, TinyVector<1>>>(n);
                break;
              }
              case 2: {
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, TinyVector<2>>>(n);
                break;
              }
              case 3: {
                n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, std::string, TinyVector<3>>>(n);
                break;
              }
                // LCOV_EXCL_START
              default: {
                throw parse_error("unexpected error: invalid vector dimension for string affectation",
                                  std::vector{n.children[1]->begin()});
              }
                // LCOV_EXCL_STOP
              }
              break;
            }
              // LCOV_EXCL_START
            default: {
              throw parse_error("unexpected error: undefined operand type for string affectation",
                                std::vector{n.children[1]->begin()});
            }
              // LCOV_EXCL_STOP
            }
          } else {
            throw parse_error("invalid operator for string affectation", std::vector{n.begin()});
          }
        };
    
        auto set_affectation_processor_for_embedded_data = [&](const ASTNodeDataType& data_type) {
          using OperatorT = std::decay_t<decltype(operator_v)>;
    
          if constexpr (std::is_same_v<OperatorT, language::eq_op>) {
            switch (data_type) {
            case ASTNodeDataType::type_id_t: {
              n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, EmbeddedData, EmbeddedData>>(n);
              break;
            }
              // LCOV_EXCL_START
            default: {
              throw parse_error("unexpected error: undefined operand type for string affectation",
                                std::vector{n.children[1]->begin()});
            }
              // LCOV_EXCL_STOP
            }
          } else {
            throw parse_error("invalid operator for '" + data_type.typeName() + "' affectation", std::vector{n.begin()});
          }
        };
    
        auto set_affectation_processor_for_value = [&](const ASTNodeDataType& value_type) {
          const ASTNodeDataType data_type = n.children[1]->m_data_type;
    
          switch (value_type) {
          case ASTNodeDataType::bool_t: {
            set_affectation_processor_for_data(bool{}, data_type);
            break;
          }
          case ASTNodeDataType::unsigned_int_t: {
            set_affectation_processor_for_data(uint64_t{}, data_type);
            break;
          }
          case ASTNodeDataType::int_t: {
            set_affectation_processor_for_data(int64_t{}, data_type);
            break;
          }
          case ASTNodeDataType::double_t: {
            set_affectation_processor_for_data(double{}, data_type);
            break;
          }
          case ASTNodeDataType::vector_t: {
            switch (value_type.dimension()) {
            case 1: {
              set_affectation_processor_for_vector_data(TinyVector<1>{}, data_type);
              break;
            }
            case 2: {
              set_affectation_processor_for_vector_data(TinyVector<2>{}, data_type);
              break;
            }
            case 3: {
              set_affectation_processor_for_vector_data(TinyVector<3>{}, data_type);
              break;
            }
              // LCOV_EXCL_START
            default: {
              throw parse_error("unexpected error: unexpected vector dimension", std::vector{n.begin()});
            }
              // LCOV_EXCL_STOP
            }
            break;
          }
          case ASTNodeDataType::string_t: {
            set_affectation_processor_for_string_data(data_type);
            break;
          }
          case ASTNodeDataType::type_id_t: {
            set_affectation_processor_for_embedded_data(data_type);
            break;
          }
          default: {
            throw parse_error("unexpected error: undefined value type for affectation", std::vector{n.begin()});
          }
          }
        };
    
        using OperatorT = std::decay_t<decltype(operator_v)>;
        // Special treatment dedicated to R^1 to be able to initialize them
        if (((n.m_data_type != n.children[1]->m_data_type) and (n.m_data_type == ASTNodeDataType::vector_t) and
             (n.m_data_type.dimension() == 1)) or
            // Special treatment for R^d vectors and operator *=
            ((n.m_data_type == ASTNodeDataType::vector_t) and (n.children[1]->m_data_type != ASTNodeDataType::vector_t) and
             std::is_same_v<OperatorT, language::multiplyeq_op>)) {
          ASTNodeNaturalConversionChecker{*n.children[1], ASTNodeDataType::double_t};
        } else {
          ASTNodeNaturalConversionChecker{*n.children[1], n.m_data_type};
        }
    
        set_affectation_processor_for_value(n.m_data_type);
      };
    
      if (n.is_type<language::eq_op>()) {
        set_affectation_processor(n, language::eq_op{});
      } else if (n.is_type<language::multiplyeq_op>()) {
        set_affectation_processor(n, language::multiplyeq_op{});
      } else if (n.is_type<language::divideeq_op>()) {
        set_affectation_processor(n, language::divideeq_op{});
      } else if (n.is_type<language::pluseq_op>()) {
        set_affectation_processor(n, language::pluseq_op{});
      } else if (n.is_type<language::minuseq_op>()) {
        set_affectation_processor(n, language::minuseq_op{});
      } else {
        throw parse_error("unexpected error: undefined affectation operator", std::vector{n.begin()});
      }
    }