Pull out Return_Optimizer
This commit is contained in:
		@@ -219,7 +219,7 @@ namespace chaiscript
 | 
			
		||||
               std::vector<std::string> t_modulepaths = std::vector<std::string>(),
 | 
			
		||||
                      std::vector<std::string> t_usepaths = std::vector<std::string>())
 | 
			
		||||
      : m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
 | 
			
		||||
        m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::For_Loop_Optimizer>>())
 | 
			
		||||
        m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::Optimizer<optimizer::Return_Optimizer, optimizer::For_Loop_Optimizer>>>())
 | 
			
		||||
    {
 | 
			
		||||
      if (m_module_paths.empty())
 | 
			
		||||
      {
 | 
			
		||||
@@ -244,7 +244,7 @@ namespace chaiscript
 | 
			
		||||
    ChaiScript( std::vector<std::string> t_modulepaths = std::vector<std::string>(),
 | 
			
		||||
                      std::vector<std::string> t_usepaths = std::vector<std::string>())
 | 
			
		||||
      : m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)),
 | 
			
		||||
        m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::For_Loop_Optimizer>>())
 | 
			
		||||
        m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::Optimizer<optimizer::Return_Optimizer, optimizer::For_Loop_Optimizer>>>())
 | 
			
		||||
    {
 | 
			
		||||
      if (m_module_paths.empty())
 | 
			
		||||
      {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,20 @@
 | 
			
		||||
namespace chaiscript {
 | 
			
		||||
  namespace optimizer {
 | 
			
		||||
 | 
			
		||||
    template<typename ... T>
 | 
			
		||||
      struct Optimizer : T...
 | 
			
		||||
    {
 | 
			
		||||
      Optimizer() = default;
 | 
			
		||||
      Optimizer(T ... t)
 | 
			
		||||
        : T(std::move(t))...
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      AST_NodePtr optimize(AST_NodePtr p) {
 | 
			
		||||
        (void)std::initializer_list<int>{ (p = T::optimize(p), 0)... };
 | 
			
		||||
        return p;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
      auto child_at(const T &node, const size_t offset) {
 | 
			
		||||
@@ -35,9 +49,32 @@ namespace chaiscript {
 | 
			
		||||
    template<typename T>
 | 
			
		||||
      AST_NodePtr make_compiled_node(const AST_NodePtr &original_node, std::vector<AST_NodePtr> children, T callable)
 | 
			
		||||
      {
 | 
			
		||||
        return chaiscript::make_shared<AST_Node, eval::Compiled_AST_Node>(original_node, children, std::move(callable));
 | 
			
		||||
        return chaiscript::make_shared<AST_Node, eval::Compiled_AST_Node>(original_node, std::move(children), std::move(callable));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    struct Return_Optimizer {
 | 
			
		||||
      AST_NodePtr optimize(const AST_NodePtr &p)
 | 
			
		||||
      {
 | 
			
		||||
        if (p->identifier == AST_Node_Type::Def
 | 
			
		||||
            && !p->children.empty())
 | 
			
		||||
        {
 | 
			
		||||
          auto &last_child = p->children.back();
 | 
			
		||||
          if (last_child->identifier == AST_Node_Type::Block) {
 | 
			
		||||
            auto &block_last_child = last_child->children.back();
 | 
			
		||||
            if (block_last_child->identifier == AST_Node_Type::Return) {
 | 
			
		||||
              if (block_last_child->children.size() == 1) {
 | 
			
		||||
                last_child->children.back() = block_last_child->children[0];
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return p;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    struct For_Loop_Optimizer {
 | 
			
		||||
      AST_NodePtr optimize(const AST_NodePtr &for_node) {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -318,35 +318,6 @@ namespace chaiscript
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /// Returns the front-most AST node
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      static void optimize_returns(AST_NodePtr &p)
 | 
			
		||||
      {
 | 
			
		||||
        for (auto &c : p->children)
 | 
			
		||||
        {
 | 
			
		||||
          if (c->identifier == AST_Node_Type::Def && c->children.size() > 0) {
 | 
			
		||||
            auto &last_child = c->children.back();
 | 
			
		||||
            if (last_child->identifier == AST_Node_Type::Block) {
 | 
			
		||||
              auto &block_last_child = last_child->children.back();
 | 
			
		||||
              if (block_last_child->identifier == AST_Node_Type::Return) {
 | 
			
		||||
                if (block_last_child->children.size() == 1) {
 | 
			
		||||
                  block_last_child = block_last_child->children[0];
 | 
			
		||||
                }
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          optimize_returns(c);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      AST_NodePtr ast(bool t_optimize_returns = true) {
 | 
			
		||||
        auto ptr = m_match_stack.front();
 | 
			
		||||
        if (t_optimize_returns) { optimize_returns(ptr); }
 | 
			
		||||
        return ptr;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      /// Helper function that collects ast_nodes from a starting position to the top of the stack into a new AST node
 | 
			
		||||
      template<typename NodeType>
 | 
			
		||||
@@ -2383,7 +2354,7 @@ namespace chaiscript
 | 
			
		||||
          m_match_stack.push_back(chaiscript::make_shared<AST_Node, eval::Noop_AST_Node>());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ast();
 | 
			
		||||
        return m_match_stack.front();
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user