Skip to content
Snippets Groups Projects
Select Git revision
  • 34d37b4999c881f1d8352dca0d6ac0b29a9bb7bf
  • develop default protected
  • origin/stage/bouguettaia
  • feature/kinetic-schemes
  • feature/reconstruction
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/variational-hydro
  • 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
  • feature/escobar-smoother
  • feature/hypoelasticity-clean
  • 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

BuiltinFunctionProcessor.hpp

Blame
    • Stéphane Del Pino's avatar
      34d37b49
      Improve numerical function evaluation in C++ · 34d37b49
      Stéphane Del Pino authored
      - code is now generic (even if more testing remains).
      - data types are now check accordingly to catch error in a clean way
      
      In some cases (generally?) data types can only be checked at
      runtime. This is the case for instance if function definition depends
      on the dimension (which is likely to happen in many cases). Thus a
      special procedure has been developed to indicate where the semantic
      error occurs at runtime. (this is in some way related to issue #19)
      34d37b49
      History
      Improve numerical function evaluation in C++
      Stéphane Del Pino authored
      - code is now generic (even if more testing remains).
      - data types are now check accordingly to catch error in a clean way
      
      In some cases (generally?) data types can only be checked at
      runtime. This is the case for instance if function definition depends
      on the dimension (which is likely to happen in many cases). Thus a
      special procedure has been developed to indicate where the semantic
      error occurs at runtime. (this is in some way related to issue #19)
    ASTNodeExpressionBuilder.cpp 7.18 KiB
    #include <language/ast/ASTNodeExpressionBuilder.hpp>
    
    #include <language/PEGGrammar.hpp>
    #include <language/ast/ASTNodeAffectationExpressionBuilder.hpp>
    #include <language/ast/ASTNodeArraySubscriptExpressionBuilder.hpp>
    #include <language/ast/ASTNodeBinaryOperatorExpressionBuilder.hpp>
    #include <language/ast/ASTNodeFunctionEvaluationExpressionBuilder.hpp>
    #include <language/ast/ASTNodeIncDecExpressionBuilder.hpp>
    #include <language/ast/ASTNodeListAffectationExpressionBuilder.hpp>
    #include <language/ast/ASTNodeUnaryOperatorExpressionBuilder.hpp>
    #include <language/node_processor/ASTNodeExpressionListProcessor.hpp>
    #include <language/node_processor/ASTNodeListProcessor.hpp>
    #include <language/node_processor/BreakProcessor.hpp>
    #include <language/node_processor/ContinueProcessor.hpp>
    #include <language/node_processor/DoWhileProcessor.hpp>
    #include <language/node_processor/FakeProcessor.hpp>
    #include <language/node_processor/ForProcessor.hpp>
    #include <language/node_processor/IfProcessor.hpp>
    #include <language/node_processor/LocalNameProcessor.hpp>
    #include <language/node_processor/NameProcessor.hpp>
    #include <language/node_processor/OStreamProcessor.hpp>
    #include <language/node_processor/TupleToTinyVectorProcessor.hpp>
    #include <language/node_processor/TupleToVectorProcessor.hpp>
    #include <language/node_processor/ValueProcessor.hpp>
    #include <language/node_processor/WhileProcessor.hpp>
    #include <language/utils/ParseError.hpp>
    
    void
    ASTNodeExpressionBuilder::_buildExpression(ASTNode& n)
    {
      if (n.is_type<language::block>()) {
        n.m_node_processor = std::make_unique<ASTNodeListProcessor>(n);
      } else if ((n.is_type<language::eq_op>() or n.is_type<language::multiplyeq_op>() or
                  n.is_type<language::divideeq_op>() or n.is_type<language::pluseq_op>() or
                  n.is_type<language::minuseq_op>())) {
        if (n.children[0]->is_type<language::name_list>() or n.children[0]->is_type<language::lvalue_list>()) {
          ASTNodeListAffectationExpressionBuilder{n};
        } else {
          ASTNodeAffectationExpressionBuilder{n};
        }
    
      } else if (n.is_type<language::tuple_expression>()) {
        n.m_node_processor = std::make_unique<TupleToVectorProcessor<ASTNodeExpressionListProcessor>>(n);
      } else if (n.is_type<language::function_definition>()) {
        n.m_node_processor = std::make_unique<FakeProcessor>();
    
      } else if (n.is_type<language::function_evaluation>()) {
        ASTNodeFunctionEvaluationExpressionBuilder{n};
    
      } else if (n.is_type<language::subscript_expression>()) {
        ASTNodeArraySubscriptExpressionBuilder{n};
    
      } else if (n.is_type<language::real>()) {
        n.m_node_processor = std::make_unique<ValueProcessor>(n);
      } else if (n.is_type<language::integer>()) {
        n.m_node_processor = std::make_unique<ValueProcessor>(n);
      } else if (n.is_type<language::literal>()) {
        n.m_node_processor = std::make_unique<ValueProcessor>(n);
      } else if (n.is_type<language::true_kw>()) {
        n.m_node_processor = std::make_unique<ValueProcessor>(n);
      } else if (n.is_type<language::false_kw>()) {
        n.m_node_processor = std::make_unique<ValueProcessor>(n);
    
      } else if ((n.is_type<language::function_argument_list>()) or (n.is_type<language::expression_list>())) {
        n.m_node_processor = std::make_unique<ASTNodeExpressionListProcessor>(n);
    
      } else if (n.is_type<language::name_list>() or n.is_type<language::lvalue_list>()) {
        n.m_node_processor = std::make_unique<FakeProcessor>();
    
      } else if (n.is_type<language::name>()) {
        // Dealing with contexts
        auto [i_symbol, success] = n.m_symbol_table->find(n.string(), n.begin());
        if (i_symbol->attributes().hasLocalContext()) {
          n.m_node_processor = std::make_unique<LocalNameProcessor>(n);
        } else {
          n.m_node_processor = std::make_unique<NameProcessor>(n);
        }
      } else if (n.is_type<language::unary_minus>() or n.is_type<language::unary_not>()) {
        ASTNodeUnaryOperatorExpressionBuilder{n};
    
      } else if (n.is_type<language::unary_minusminus>() or n.is_type<language::unary_plusplus>() or
                 n.is_type<language::post_minusminus>() or n.is_type<language::post_plusplus>()) {
        ASTNodeIncDecExpressionBuilder{n};
    
      } else if (n.is_type<language::multiply_op>() or n.is_type<language::divide_op>() or n.is_type<language::plus_op>() or
                 n.is_type<language::minus_op>() or n.is_type<language::or_op>() or n.is_type<language::and_op>() or
                 n.is_type<language::xor_op>() or n.is_type<language::greater_op>() or
                 n.is_type<language::greater_or_eq_op>() or n.is_type<language::lesser_op>() or
                 n.is_type<language::lesser_or_eq_op>() or n.is_type<language::eqeq_op>() or
                 n.is_type<language::not_eq_op>()) {
        ASTNodeBinaryOperatorExpressionBuilder{n};
    
      } else if (n.is_type<language::cout_kw>()) {
        n.m_node_processor = std::make_unique<OStreamProcessor>(n, std::cout);
      } else if (n.is_type<language::cerr_kw>()) {
        n.m_node_processor = std::make_unique<OStreamProcessor>(n, std::cerr);
      } else if (n.is_type<language::clog_kw>()) {
        n.m_node_processor = std::make_unique<OStreamProcessor>(n, std::clog);
      } else if (n.is_type<language::if_statement>()) {
        n.m_node_processor = std::make_unique<IfProcessor>(n);
      } else if (n.is_type<language::statement_block>()) {
        n.m_node_processor = std::make_unique<ASTNodeListProcessor>(n);
      } else if (n.is_type<language::do_while_statement>()) {
        n.m_node_processor = std::make_unique<DoWhileProcessor>(n);
      } else if (n.is_type<language::while_statement>()) {
        n.m_node_processor = std::make_unique<WhileProcessor>(n);
      } else if (n.is_type<language::for_statement>()) {
        n.m_node_processor = std::make_unique<ForProcessor>(n);
      } else if (n.is_type<language::for_statement_block>()) {
        n.m_node_processor = std::make_unique<ASTNodeListProcessor>(n);
      } else if (n.is_type<language::for_init>()) {
        n.m_node_processor = std::make_unique<FakeProcessor>();
      } else if (n.is_type<language::for_post>()) {
        n.m_node_processor = std::make_unique<FakeProcessor>();
      } else if (n.is_type<language::for_test>()) {
        n.m_node_processor = std::make_unique<ValueProcessor>(n);
      } else if (n.is_type<language::break_kw>()) {
        n.m_node_processor = std::make_unique<BreakProcessor>();
      } else if (n.is_type<language::continue_kw>()) {
        n.m_node_processor = std::make_unique<ContinueProcessor>();
      } else {
        std::ostringstream error_message;
        error_message << "undefined node processor type '" << rang::fgB::red << n.name() << rang::fg::reset << "'";
        throw ParseError{error_message.str(), std::vector{n.begin()}};
      }
    
      for (auto& child : n.children) {
        this->_buildExpression(*child);
      }
    }
    
    ASTNodeExpressionBuilder::ASTNodeExpressionBuilder(ASTNode& node)
    {
      Assert(node.is_root());
      node.m_node_processor = std::make_unique<ASTNodeListProcessor>(node);
      for (auto& child : node.children) {
        this->_buildExpression(*child);
      }
    
      // Build expressions of functions
      FunctionTable& function_table = node.m_symbol_table->functionTable();
      for (size_t function_id = 0; function_id < function_table.size(); ++function_id) {
        FunctionDescriptor& function_descriptor = function_table[function_id];
        ASTNode& function_expression            = function_descriptor.definitionNode();
        this->_buildExpression(function_expression);
      }
    }