Skip to content
Snippets Groups Projects
Select Git revision
  • 11c957a6cd0a5df44e46df7dd9f70d10a5548e16
  • develop default protected
  • feature/advection
  • feature/composite-scheme-other-fluxes
  • origin/stage/bouguettaia
  • save_clemence
  • feature/local-dt-fsi
  • feature/variational-hydro
  • feature/gmsh-reader
  • feature/reconstruction
  • feature/kinetic-schemes
  • feature/composite-scheme-sources
  • 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
  • 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

GmshReader.cpp

Blame
  • ASTNodeCFunctionExpressionBuilder.cpp 5.60 KiB
    #include <ASTNodeCFunctionExpressionBuilder.hpp>
    #include <PEGGrammar.hpp>
    
    #include <SymbolTable.hpp>
    
    #include <ASTNodeDataTypeFlattener.hpp>
    #include <ASTNodeNaturalConversionChecker.hpp>
    
    #include <node_processor/CFunctionProcessor.hpp>
    
    PUGS_INLINE std::unique_ptr<IFunctionArgumentConverter>
    ASTNodeCFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeDataType& parameter_type,
                                                             const ASTNodeSubDataType& argument_node_sub_data_type,
                                                             const size_t argument_number)
    {
      auto get_function_argument_converter_for =
        [&](const auto& parameter_v) -> std::unique_ptr<IFunctionArgumentConverter> {
        using ParameterT = std::decay_t<decltype(parameter_v)>;
        switch (argument_node_sub_data_type.m_data_type) {
        case ASTNodeDataType::bool_t: {
          return std::make_unique<FunctionArgumentConverter<ParameterT, bool>>(argument_number);
        }
        case ASTNodeDataType::unsigned_int_t: {
          return std::make_unique<FunctionArgumentConverter<ParameterT, uint64_t>>(argument_number);
        }
        case ASTNodeDataType::int_t: {
          return std::make_unique<FunctionArgumentConverter<ParameterT, int64_t>>(argument_number);
        }
        case ASTNodeDataType::double_t: {
          return std::make_unique<FunctionArgumentConverter<ParameterT, double>>(argument_number);
        }
          // LCOV_EXCL_START
        default: {
          throw parse_error("unexpected error: invalid argument type for function",
                            std::vector{argument_node_sub_data_type.m_parent_node.begin()});
        }
          // LCOV_EXCL_STOP
        }
      };
    
      auto get_function_argument_converter_for_argument_type = [&]() {
        switch (parameter_type) {
        case ASTNodeDataType::bool_t: {
          return get_function_argument_converter_for(bool{});
        }
        case ASTNodeDataType::unsigned_int_t: {
          return get_function_argument_converter_for(uint64_t{});
        }
        case ASTNodeDataType::int_t: {
          return get_function_argument_converter_for(int64_t{});
        }
        case ASTNodeDataType::double_t: {
          return get_function_argument_converter_for(double{});
        }
          // LCOV_EXCL_START
        default: {
          throw parse_error("unexpected error: undefined parameter type for function",
                            std::vector{argument_node_sub_data_type.m_parent_node.begin()});
        }
          // LCOV_EXCL_STOP
        }
      };
    
      ASTNodeNaturalConversionChecker{argument_node_sub_data_type.m_parent_node, argument_node_sub_data_type.m_data_type,
                                      parameter_type};
    
      return get_function_argument_converter_for_argument_type();
    }
    
    PUGS_INLINE
    void
    ASTNodeCFunctionExpressionBuilder::_storeArgumentProcessor(
      const std::vector<ASTNodeDataType>& parameter_type_list,
      const ASTNodeDataTypeFlattener::FlattenedDataTypeList& flattened_datatype_list,
      const size_t argument_number,
      CFunctionProcessor& c_function_processor)
    {
      c_function_processor.addArgumentConverter(this->_getArgumentConverter(parameter_type_list[argument_number],
                                                                            flattened_datatype_list[argument_number],
                                                                            argument_number));
    }
    
    PUGS_INLINE
    void
    ASTNodeCFunctionExpressionBuilder::_buildArgumentProcessors(const std::vector<ASTNodeDataType>& parameter_type_list,
                                                                ASTNode& node,
                                                                CFunctionProcessor& c_function_processor)
    {
      ASTNode& argument_nodes = *node.children[1];
    
      ASTNodeDataTypeFlattener::FlattenedDataTypeList flattened_datatype_list;
      ASTNodeDataTypeFlattener{argument_nodes, flattened_datatype_list};
    
      const size_t arguments_number  = flattened_datatype_list.size();
      const size_t parameters_number = parameter_type_list.size();
    
      if (arguments_number != parameters_number) {
        std::ostringstream error_message;
        error_message << "bad number of arguments: expecting " << rang::fgB::yellow << parameters_number
                      << rang::style::reset << ", provided " << rang::fgB::yellow << arguments_number << rang::style::reset;
        throw parse_error(error_message.str(), argument_nodes.begin());
      }
    
      if (arguments_number > 1) {
        for (size_t i = 0; i < arguments_number; ++i) {
          this->_storeArgumentProcessor(parameter_type_list, flattened_datatype_list, i, c_function_processor);
        }
      } else {
        this->_storeArgumentProcessor(parameter_type_list, flattened_datatype_list, 0, c_function_processor);
      }
    }
    
    ASTNodeCFunctionExpressionBuilder::ASTNodeCFunctionExpressionBuilder(ASTNode& node)
    {
      auto [i_function_symbol, found] = node.m_symbol_table->find(node.children[0]->string(), node.begin());
      Assert(found);
      Assert(i_function_symbol->attributes().dataType() == ASTNodeDataType::c_function_t);
    
      uint64_t c_function_id = std::get<uint64_t>(i_function_symbol->attributes().value());
    
      CFunctionEmbedderTable& c_function_embedder_table = node.m_symbol_table->cFunctionEbedderTable();
      std::shared_ptr c_function_embedder               = c_function_embedder_table[c_function_id];
    
      std::vector<ASTNodeDataType> c_function_parameter_type_list = c_function_embedder->getParameterDataTypes();
    
      ASTNode& argument_nodes              = *node.children[1];
      std::unique_ptr c_function_processor = std::make_unique<CFunctionProcessor>(argument_nodes);
    
      this->_buildArgumentProcessors(c_function_parameter_type_list, node, *c_function_processor);
    
      c_function_processor->setFunctionExpressionProcessor(
        std::make_unique<CFunctionExpressionProcessor>(c_function_embedder));
    
      node.m_node_processor = std::move(c_function_processor);
    }