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

IBoundaryConditionDescriptor.hpp

Blame
  • ASTSymbolTableBuilder.cpp 4.20 KiB
    #include <language/ast/ASTSymbolTableBuilder.hpp>
    
    #include <language/PEGGrammar.hpp>
    #include <language/utils/ParseError.hpp>
    #include <language/utils/SymbolTable.hpp>
    
    void
    ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>& symbol_table)
    {
      if (n.is_type<language::block>() or (n.is_type<language::for_statement>())) {
        if (!n.children.empty()) {
          std::shared_ptr block_symbol_table = std::make_shared<SymbolTable>(symbol_table);
          n.m_symbol_table                   = block_symbol_table;
    
          for (auto& child : n.children) {
            this->buildSymbolTable(*child, block_symbol_table);
          }
        }
      } else if (n.is_type<language::fct_declaration>()) {
        std::shared_ptr local_symbol_table =
          std::make_shared<SymbolTable>(symbol_table, std::make_shared<SymbolTable::Context>());
    
        n.m_symbol_table          = local_symbol_table;
        const std::string& symbol = n.children[0]->string();
        auto [i_symbol, success]  = symbol_table->add(symbol, n.children[0]->begin());
        if (not success) {
          std::ostringstream error_message;
          error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << "' was already defined!";
          throw ParseError(error_message.str(), std::vector{n.begin()});
        }
    
        for (auto& child : n.children) {
          this->buildSymbolTable(*child, local_symbol_table);
        }
    
        size_t function_id =
          symbol_table->functionTable().add(FunctionDescriptor{symbol, std::move(n.children[1]), std::move(n.children[2])});
        i_symbol->attributes().value() = function_id;
        n.children.resize(1);
      } else {
        n.m_symbol_table = symbol_table;
        if (n.has_content()) {
          if (n.is_type<language::var_declaration>()) {
            auto register_symbol = [&](const ASTNode& argument_node) {
              auto [i_symbol, success] = symbol_table->add(argument_node.string(), argument_node.begin());
              if (not success) {
                std::ostringstream error_message;
                error_message << "symbol '" << rang::fg::red << argument_node.string() << rang::fg::reset
                              << "' was already defined!";
                throw ParseError(error_message.str(), std::vector{argument_node.begin()});
              }
            };
    
            if (n.children[0]->is_type<language::name>()) {
              register_symbol(*n.children[0]);
            } else {   // treats the case of list of parameters
              Assert(n.children[0]->is_type<language::name_list>());
              for (auto& child : n.children[0]->children) {
                register_symbol(*child);
              }
            }
          } else if (n.is_type<language::function_definition>()) {
            auto register_and_initialize_symbol = [&](const ASTNode& argument_node) {
              auto [i_symbol, success] = symbol_table->add(argument_node.string(), argument_node.begin());
              if (not success) {
                std::ostringstream error_message;
                error_message << "symbol '" << rang::fg::red << argument_node.string() << rang::fg::reset
                              << "' was already defined!";
                throw ParseError(error_message.str(), std::vector{argument_node.begin()});
              }
              // Symbols will be initialized at call
              i_symbol->attributes().setIsInitialized();
            };
    
            if (n.children[0]->is_type<language::name>()) {
              register_and_initialize_symbol(*n.children[0]);
            } else {   // treats the case of list of parameters
              Assert(n.children[0]->is_type<language::name_list>());
              for (auto& child : n.children[0]->children) {
                register_and_initialize_symbol(*child);
              }
            }
          } else if (n.is_type<language::name>()) {
            if (not symbol_table->has(n.string(), n.begin())) {
              std::ostringstream error_message;
              error_message << "undefined symbol '" << rang::fg::red << n.string() << rang::fg::reset << '\'';
              throw ParseError(error_message.str(), std::vector{n.begin()});
            }
          }
        }
    
        for (auto& child : n.children) {
          this->buildSymbolTable(*child, symbol_table);
        }
      }
    }
    
    ASTSymbolTableBuilder::ASTSymbolTableBuilder(ASTNode& node)
    {
      Assert(node.is_root());
    
      this->buildSymbolTable(node, node.m_symbol_table);
      std::cout << " - checked symbols declaration\n";
    }