From 9e16cc2a7905e2685dc76f6389d18d77b6f2371f Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 27 Jun 2016 08:56:03 -0600 Subject: [PATCH] Simplify and normalize if block code --- .../chaiscript/language/chaiscript_engine.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 43 ++++++------------- .../language/chaiscript_optimizer.hpp | 34 +++++++++++++++ .../chaiscript/language/chaiscript_parser.hpp | 12 +++++- 4 files changed, 58 insertions(+), 35 deletions(-) diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 73e0784b..7429746c 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -219,7 +219,7 @@ namespace chaiscript std::vector t_modulepaths = std::vector(), std::vector t_usepaths = std::vector()) : m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)), - m_parser(std::make_unique>>()), + m_parser(std::make_unique>>()), m_engine(*m_parser) { @@ -246,7 +246,7 @@ namespace chaiscript ChaiScript( std::vector t_modulepaths = std::vector(), std::vector t_usepaths = std::vector()) : m_module_paths(std::move(t_modulepaths)), m_use_paths(std::move(t_usepaths)), - m_parser(std::make_unique>>()), + m_parser(std::make_unique>>()), m_engine(*m_parser) { if (m_module_paths.empty()) diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index ee9eba7d..601ad6f7 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -242,6 +242,12 @@ namespace chaiscript { } + Constant_AST_Node(Boxed_Value t_value) + : AST_Node_Impl("", AST_Node_Type::Constant, Parse_Location()), + m_value(std::move(t_value)) + { + } + Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override { return m_value; } @@ -823,46 +829,20 @@ namespace chaiscript }; - template - struct If_Init_AST_Node final : AST_Node_Impl { - If_Init_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : - AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children)) - { - assert(this->children.size() == 3 || this->children.size() == 4); - } - - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { - chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); - this->children[0]->eval(t_ss); - if (this->get_bool_condition(this->children[1]->eval(t_ss))) { - return this->children[2]->eval(t_ss); - } else { - if (this->children.size() == 4) { - return this->children[3]->eval(t_ss); - } else { - return void_var(); - } - } - } - }; template struct If_AST_Node final : AST_Node_Impl { If_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::If, std::move(t_loc), std::move(t_children)) { - assert(this->children.size() == 2 || this->children.size() == 3); + assert(this->children.size() == 3); } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { if (this->get_bool_condition(this->children[0]->eval(t_ss))) { return this->children[1]->eval(t_ss); } else { - if (this->children.size() == 3) { - return this->children[2]->eval(t_ss); - } else { - return void_var(); - } + return this->children[2]->eval(t_ss); } } }; @@ -1227,10 +1207,11 @@ private: { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{ - // It's a no-op, that evaluates to "true" - // the magic-static version of const_var(true) helps us here - return const_var(true); + // It's a no-op, that evaluates to "void" + return val; } + + Boxed_Value val = void_var(); }; template diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index aa4f0a24..991227b9 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -125,6 +125,40 @@ namespace chaiscript { } }; + struct Dead_Code { + template + auto optimize(const eval::AST_Node_Impl_Ptr &node) { + if (node->identifier == AST_Node_Type::Block) + { + std::vector keepers; + const auto num_children = node->children.size(); + keepers.reserve(num_children); + + for (size_t i = 0; i < num_children; ++i) { + auto child = node->children[i]; + if ( (child->identifier != AST_Node_Type::Id + && child->identifier != AST_Node_Type::Constant) + || i == num_children - 1) { + keepers.push_back(i); + } + } + + if (keepers.size() == num_children) { + return node; + } else { + std::vector> new_children; + for (const auto x : keepers) + { + new_children.push_back(node->children[x]); + } + return chaiscript::make_shared, eval::Block_AST_Node>(node->text, node->location, new_children); + } + } else { + return node; + } + } + }; + struct Unused_Return { template auto optimize(const eval::AST_Node_Impl_Ptr &node) { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 0601d906..48341dd0 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -1591,10 +1591,18 @@ namespace chaiscript } } + const auto num_children = m_match_stack.size() - prev_stack_top; + + if ((is_if_init && num_children == 3) + || (!is_if_init && num_children == 2)) { + m_match_stack.push_back(chaiscript::make_shared, eval::Noop_AST_Node>()); + } + if (!is_if_init) { build_match>(prev_stack_top); } else { - build_match>(prev_stack_top); + build_match>(prev_stack_top+1); + build_match>(prev_stack_top); } } @@ -1682,7 +1690,7 @@ namespace chaiscript { return false; } else { - m_match_stack.push_back(chaiscript::make_shared, eval::Noop_AST_Node>()); + m_match_stack.push_back(chaiscript::make_shared, eval::Constant_AST_Node>(Boxed_Value(true))); } }