Pull out Return_Optimizer

This commit is contained in:
Jason Turner 2016-04-23 22:12:08 -06:00
parent 4324a700ad
commit 4dbf1ee2bd
3 changed files with 41 additions and 33 deletions

View File

@ -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())
{

View File

@ -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) {

View File

@ -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();
}
};
}