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

test_PolynomialReconstruction.cpp

Blame
  • ASTSymbolInitializationChecker.cpp 5.82 KiB
    #include <language/ast/ASTSymbolInitializationChecker.hpp>
    
    #include <language/PEGGrammar.hpp>
    #include <language/utils/ParseError.hpp>
    #include <language/utils/SymbolTable.hpp>
    
    void
    ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node)
    {
      if (node.is_type<language::var_declaration>()) {
        auto set_is_initialized = [&](ASTNode& name_node) {
          const std::string& symbol = name_node.string();
          auto [i_symbol, found]    = node.m_symbol_table->find(symbol, name_node.begin());
          Assert(found, "unexpected error, should have been detected through declaration checking");
          i_symbol->attributes().setIsInitialized();
        };
    
        auto check_correct_name_in_definition = [](ASTNode& decl_name_node, ASTNode& def_name_node) {
          if (def_name_node.is_type<language::name_list>()) {
            throw ParseError("unexpected variable list, expecting one identifier", std::vector{def_name_node.begin()});
          }
          Assert(def_name_node.is_type<language::name>());
          if (decl_name_node.string() != def_name_node.string()) {
            std::ostringstream os;
            os << "invalid identifier, expecting '" << decl_name_node.string() << '\'';
            throw ParseError(os.str(), std::vector{def_name_node.begin()});
          }
        };
    
        if (node.children[0]->is_type<language::name>()) {
          if (node.children.size() == 4) {
            this->_checkSymbolInitialization(*node.children[3]);
            check_correct_name_in_definition(*node.children[0], *node.children[2]);
            set_is_initialized(*node.children[0]);
          }
        } else if (node.children[0]->is_type<language::name_list>()) {
          if (node.children.size() == 4) {
            ASTNode& decl_name_list_node = *node.children[0];
            ASTNode& def_name_list_node  = *node.children[2];
    
            if (not def_name_list_node.is_type<language::name_list>()) {
              throw ParseError("expecting a list of identifiers", std::vector{def_name_list_node.begin()});
            }
    
            if (decl_name_list_node.children.size() != def_name_list_node.children.size()) {
              std::ostringstream os;
              os << "invalid number of definition identifiers, expecting " << decl_name_list_node.children.size()
                 << " found " << def_name_list_node.children.size();
              throw ParseError(os.str(), std::vector{def_name_list_node.begin()});
            }
    
            ASTNode& expression_list_node = *node.children[3];
    
            this->_checkSymbolInitialization(expression_list_node);
            for (size_t i = 0; i < decl_name_list_node.children.size(); ++i) {
              check_correct_name_in_definition(*decl_name_list_node.children[i], *def_name_list_node.children[i]);
              set_is_initialized(*decl_name_list_node.children[i]);
            }
          }
        }
      } else if (node.is_type<language::fct_declaration>()) {
        const std::string& symbol = node.children[0]->string();
        auto [i_symbol, found]    = node.m_symbol_table->find(symbol, node.children[0]->begin());
        Assert(found, "unexpected error, should have been detected through declaration checking");
    
        i_symbol->attributes().setIsInitialized();
    
        auto& function_table = node.m_symbol_table->functionTable();
    
        uint64_t function_id      = std::get<uint64_t>(i_symbol->attributes().value());
        auto& function_descriptor = function_table[function_id];
        this->_checkSymbolInitialization(function_descriptor.definitionNode());
    
      } else if (node.is_type<language::function_definition>()) {
        this->_checkSymbolInitialization(*node.children[1]);
      } else if (node.is_type<language::eq_op>()) {
        // first checks for right hand side
        this->_checkSymbolInitialization(*node.children[1]);
    
        auto set_is_initialized = [&](ASTNode& name_node) {
          const std::string& symbol = name_node.string();
          auto [i_symbol, found]    = node.m_symbol_table->find(symbol, name_node.begin());
          Assert(found, "unexpected error, should have been detected through declaration checking");
          i_symbol->attributes().setIsInitialized();
        };
    
        if (node.children[0]->is_type<language::name>()) {
          set_is_initialized(*node.children[0]);
        } else if (node.children[0]->is_type<language::subscript_expression>()) {
          ASTNode& subscript_node = *node.children[0];
          ASTNode& name_node      = *subscript_node.children[0];
    
          Assert(name_node.is_type<language::name>());
          set_is_initialized(name_node);
        } else if (node.children[0]->is_type<language::name_list>() or node.children[0]->is_type<language::lvalue_list>()) {
          ASTNode& list_node = *node.children[0];
          for (auto& child_node : list_node.children) {
            if (child_node->is_type<language::name>()) {
              set_is_initialized(*child_node);
            } else {
              Assert(child_node->is_type<language::subscript_expression>());
              ASTNode& name_node = *child_node->children[0];
              Assert(name_node.is_type<language::name>());
              set_is_initialized(name_node);
            }
          }
        }
      } else if (node.is_type<language::name>()) {
        auto [i_symbol, found] = node.m_symbol_table->find(node.string(), node.begin());
        Assert(node.m_symbol_table->has(node.string(), node.begin()),
               "unexpected error, should have been detected through declaration checking");
        if (found and not i_symbol->attributes().isInitialized()) {
          std::ostringstream error_message;
          error_message << "uninitialized symbol '" << rang::fg::red << node.string() << rang::fg::reset << '\'';
          throw ParseError(error_message.str(), std::vector{node.begin()});
        }
      }
    
      if (not(node.is_type<language::var_declaration>() or node.is_type<language::fct_declaration>() or
              node.is_type<language::eq_op>())) {
        for (auto& child : node.children) {
          this->_checkSymbolInitialization(*child);
        }
      }
    }
    
    ASTSymbolInitializationChecker::ASTSymbolInitializationChecker(ASTNode& root_node)
    {
      Assert(root_node.is_root());
      this->_checkSymbolInitialization(root_node);
    }