Skip to content
Snippets Groups Projects
Select Git revision
  • da523f3d6fb1784863693f1a678839df16f5084f
  • 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

SetTest.cpp

Blame
  • ModuleRepository.cpp 9.28 KiB
    #include <language/modules/ModuleRepository.hpp>
    
    #include <language/ast/ASTNode.hpp>
    #include <language/modules/CoreModule.hpp>
    #include <language/modules/LinearSolverModule.hpp>
    #include <language/modules/MathModule.hpp>
    #include <language/modules/MeshModule.hpp>
    #include <language/modules/SchemeModule.hpp>
    #include <language/modules/SocketModule.hpp>
    #include <language/modules/UtilsModule.hpp>
    #include <language/modules/WriterModule.hpp>
    #include <language/utils/BasicAffectationRegistrerFor.hpp>
    #include <language/utils/BuiltinFunctionEmbedder.hpp>
    #include <language/utils/ParseError.hpp>
    #include <language/utils/SymbolTable.hpp>
    #include <language/utils/TypeDescriptor.hpp>
    #include <language/utils/ValueDescriptor.hpp>
    
    #include <utils/PugsAssert.hpp>
    
    #include <algorithm>
    
    void
    ModuleRepository::_subscribe(std::unique_ptr<IModule> m)
    {
      auto is_keyword = [](const std::string& s) -> bool {
        if (s.size() == 0) {
          return false;
        } else {
          if (not(std::isalpha(s[0]) or s[0] == '_')) {
            return false;
          }
          for (size_t i = 1; i < s.size(); ++i) {
            if (not(std::isalnum(s[0]) or s[0] == '_')) {
              return false;
            }
          }
        }
    
        return true;
      };
    
      if (not is_keyword(std::string{m->name()})) {
        std::ostringstream os;
        os << "cannot subscribe module with invalid name: '" << m->name() << "'\n";
        throw UnexpectedError(os.str());
      }
    
      auto [i_module, success] = m_module_set.emplace(m->name(), std::move(m));
      Assert(success, "module has already been subscribed");
    }
    
    ModuleRepository::ModuleRepository()
    {
      this->_subscribe(std::make_unique<CoreModule>());
      this->_subscribe(std::make_unique<LinearSolverModule>());
      this->_subscribe(std::make_unique<MathModule>());
      this->_subscribe(std::make_unique<MeshModule>());
      this->_subscribe(std::make_unique<SchemeModule>());
      this->_subscribe(std::make_unique<SocketModule>());
      this->_subscribe(std::make_unique<UtilsModule>());
      this->_subscribe(std::make_unique<WriterModule>());
    }
    
    template <typename NameEmbedderMapT, typename EmbedderTableT>
    void
    ModuleRepository::_populateEmbedderTableT(const ASTNode& module_node,
                                              const std::string& module_name,
                                              const NameEmbedderMapT& name_embedder_map,
                                              const ASTNodeDataType& data_type,
                                              SymbolTable& symbol_table,
                                              EmbedderTableT& embedder_table)
    {
      for (auto [symbol_name, embedded] : name_embedder_map) {
        auto [i_symbol, success] = symbol_table.add(symbol_name, module_node.begin());
    
        if (not success) {
          std::ostringstream error_message;
          error_message << "importing module '" << module_name << "', cannot add symbol '" << symbol_name
                        << "', it is already defined!";
          throw ParseError(error_message.str(), module_node.begin());
        }
    
        i_symbol->attributes().setDataType(data_type);
        i_symbol->attributes().setIsInitialized();
        i_symbol->attributes().value() = embedder_table.size();
    
        embedder_table.add(embedded);
      }
    }
    
    void
    ModuleRepository::_populateSymbolTable(const ASTNode& module_node,
                                           const std::string& module_name,
                                           const IModule::NameValueMap& name_value_descriptor_map,
                                           SymbolTable& symbol_table)
    {
      for (auto [symbol_name, value_descriptor] : name_value_descriptor_map) {
        auto [i_symbol, success] = symbol_table.add(symbol_name, module_node.begin());
    
        if (not success) {
          std::ostringstream error_message;
          error_message << "importing module '" << module_name << "', cannot add symbol '" << symbol_name
                        << "', it is already defined!";
          throw ParseError(error_message.str(), module_node.begin());
        }
    
        i_symbol->attributes().setDataType(value_descriptor->type());
        i_symbol->attributes().setIsInitialized();
        i_symbol->attributes().value() = value_descriptor->value();
      }
    }
    
    void
    ModuleRepository::populateSymbolTable(const ASTNode& module_name_node, SymbolTable& symbol_table)
    {
      const std::string& module_name = module_name_node.string();
    
      auto i_module = m_module_set.find(module_name);
      if (i_module != m_module_set.end()) {
        const IModule& populating_module = *i_module->second;
    
        if (populating_module.isMandatory()) {
          std::ostringstream error_message;
          error_message << "module '" << rang::fgB::blue << module_name << rang::style::reset << rang::style::bold
                        << "' is an autoload " << rang::fgB::yellow << "mandatory" << rang::style::reset
                        << rang::style::bold << " module. It cannot be imported explicitly!";
          throw ParseError(error_message.str(), module_name_node.begin());
        }
    
        this->_populateEmbedderTableT(module_name_node, module_name, populating_module.getNameBuiltinFunctionMap(),
                                      ASTNodeDataType::build<ASTNodeDataType::builtin_function_t>(), symbol_table,
                                      symbol_table.builtinFunctionEmbedderTable());
    
        this->_populateEmbedderTableT(module_name_node, module_name, populating_module.getNameTypeMap(),
                                      ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>(), symbol_table,
                                      symbol_table.typeEmbedderTable());
    
        this->_populateSymbolTable(module_name_node, module_name, populating_module.getNameValueMap(), symbol_table);
    
        for (auto [symbol_name, embedded] : populating_module.getNameTypeMap()) {
          BasicAffectationRegisterFor<EmbeddedData>(ASTNodeDataType::build<ASTNodeDataType::type_id_t>(symbol_name));
        }
    
      } else {
        throw ParseError(std::string{"could not find module "} + module_name, std::vector{module_name_node.begin()});
      }
    }
    
    void
    ModuleRepository::populateMandatorySymbolTable(const ASTNode& root_node, SymbolTable& symbol_table)
    {
      for (auto&& [module_name, i_module] : m_module_set) {
        if (i_module->isMandatory()) {
          this->_populateEmbedderTableT(root_node, module_name, i_module->getNameBuiltinFunctionMap(),
                                        ASTNodeDataType::build<ASTNodeDataType::builtin_function_t>(), symbol_table,
                                        symbol_table.builtinFunctionEmbedderTable());
    
          this->_populateEmbedderTableT(root_node, module_name, i_module->getNameTypeMap(),
                                        ASTNodeDataType::build<ASTNodeDataType::type_name_id_t>(), symbol_table,
                                        symbol_table.typeEmbedderTable());
    
          this->_populateSymbolTable(root_node, module_name, i_module->getNameValueMap(), symbol_table);
    
          for (auto [symbol_name, embedded] : i_module->getNameTypeMap()) {
            BasicAffectationRegisterFor<EmbeddedData>(ASTNodeDataType::build<ASTNodeDataType::type_id_t>(symbol_name));
          }
    
          i_module->registerOperators();
        }
      }
    }
    
    std::string
    ModuleRepository::getAvailableModules() const
    {
      std::stringstream os;
      os << rang::fgB::yellow << "Available modules" << rang::fg::blue << " [modules tagged with a " << rang::style::reset
         << rang::style::bold << '*' << rang::style::reset << rang::fg::blue << " are automatically imported]"
         << rang::style::reset << '\n';
      for (auto& [name, i_module] : m_module_set) {
        if (i_module->isMandatory()) {
          os << rang::style::bold << " *" << rang::style::reset;
        } else {
          os << "  ";
        }
        os << rang::fgB::green << name << rang::style::reset << '\n';
      }
    
      return os.str();
    }
    
    void
    ModuleRepository::registerOperators(const std::string& module_name)
    {
      auto i_module = m_module_set.find(module_name);
      if (i_module != m_module_set.end()) {
        i_module->second->registerOperators();
      } else {
        throw NormalError(std::string{"could not find module "} + module_name);
      }
    }
    
    std::string
    ModuleRepository::getModuleInfo(const std::string& module_name) const
    {
      auto demangleBuiltinFunction = [](const std::string& mangled_name) -> std::string {
        size_t i = 0;
        for (; i < mangled_name.size(); ++i) {
          if (mangled_name[i] == ':')
            break;
        }
        return mangled_name.substr(0, i);
      };
    
      std::stringstream os;
      auto i_module = m_module_set.find(module_name);
      if (i_module != m_module_set.end()) {
        os << rang::fgB::yellow << "Module '" << rang::fgB::blue << module_name << rang::fgB::yellow << "' provides"
           << rang::style::reset << '\n';
        const auto& builtin_function_map = i_module->second->getNameBuiltinFunctionMap();
        if (builtin_function_map.size() > 0) {
          os << "  functions\n";
          for (auto& [mangled_name, function] : builtin_function_map) {
            os << "    " << rang::fgB::green << demangleBuiltinFunction(mangled_name) << rang::style::reset << ": ";
            os << dataTypeName(function->getParameterDataTypes());
            os << rang::fgB::yellow << " -> " << rang::style::reset;
            os << dataTypeName(function->getReturnDataType()) << '\n';
          }
        }
    
        const auto& builtin_type_map = i_module->second->getNameTypeMap();
        if (builtin_type_map.size() > 0) {
          os << "  types\n";
          for (auto& [name, descriptor] : builtin_type_map) {
            os << "    " << rang::fgB::green << name << rang::style::reset << '\n';
          }
        }
    
      } else {
        throw NormalError(std::string{"could not find module "} + module_name);
      }
    
      return os.str();
    }