Pull constant folding optimizer out

This commit is contained in:
Jason Turner 2016-04-23 22:27:34 -06:00
parent 4dbf1ee2bd
commit 71caf5006f
3 changed files with 28 additions and 35 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::Optimizer<optimizer::Return_Optimizer, optimizer::For_Loop_Optimizer>>>())
m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::Optimizer<optimizer::Constant_Fold, optimizer::Return, optimizer::For_Loop>>>())
{
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::Optimizer<optimizer::Return_Optimizer, optimizer::For_Loop_Optimizer>>>())
m_parser(std::make_unique<parser::ChaiScript_Parser<optimizer::Optimizer<optimizer::Constant_Fold, optimizer::Return, optimizer::For_Loop>>>())
{
if (m_module_paths.empty())
{

View File

@ -53,7 +53,7 @@ namespace chaiscript {
}
struct Return_Optimizer {
struct Return {
AST_NodePtr optimize(const AST_NodePtr &p)
{
if (p->identifier == AST_Node_Type::Def
@ -74,8 +74,31 @@ namespace chaiscript {
}
};
struct Constant_Fold {
AST_NodePtr optimize(const AST_NodePtr &node) {
if (node->identifier == AST_Node_Type::Binary
&& node->children.size() == 2
&& node->children[0]->identifier == AST_Node_Type::Constant
&& node->children[1]->identifier == AST_Node_Type::Constant)
{
const auto oper = node->text;
const auto parsed = Operators::to_operator(oper);
if (parsed != Operators::Opers::invalid) {
const auto lhs = std::dynamic_pointer_cast<eval::Constant_AST_Node>(node->children[0])->m_value;
const auto rhs = std::dynamic_pointer_cast<eval::Constant_AST_Node>(node->children[1])->m_value;
if (lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) {
const auto val = Boxed_Number::do_oper(parsed, lhs, rhs);
const auto match = node->children[0]->text + " " + oper + " " + node->children[1]->text;
return chaiscript::make_shared<AST_Node, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val));
}
}
}
struct For_Loop_Optimizer {
return node;
}
};
struct For_Loop {
AST_NodePtr optimize(const AST_NodePtr &for_node) {
if (for_node->identifier != AST_Node_Type::For) {

View File

@ -2129,37 +2129,7 @@ namespace chaiscript
case(Operator_Precidence::Bitwise_Xor) :
case(Operator_Precidence::Bitwise_Or) :
case(Operator_Precidence::Comparison) :
{
bool folded = false;
const auto size = m_match_stack.size();
try {
if (m_match_stack[size - 1]->identifier == AST_Node_Type::Constant
&& m_match_stack[size - 2]->identifier == AST_Node_Type::Constant) {
const auto parsed = Operators::to_operator(oper);
if (parsed != Operators::Opers::invalid) {
const auto lhs = std::dynamic_pointer_cast<eval::Constant_AST_Node>(m_match_stack[size-2])->m_value;
const auto rhs = std::dynamic_pointer_cast<eval::Constant_AST_Node>(m_match_stack[size-1])->m_value;
if (lhs.get_type_info().is_arithmetic() && rhs.get_type_info().is_arithmetic()) {
const auto val = Boxed_Number::do_oper(parsed, lhs, rhs);
const auto start = m_match_stack[size-2]->location;
const auto match = m_match_stack[size-2]->text + " " + oper + " " + m_match_stack[size-1]->text;
m_match_stack.resize(size-2);
m_match_stack.push_back(
make_node<eval::Constant_AST_Node>(std::move(match), start.start.line, start.start.column, std::move(val)));
folded = true;
}
}
}
} catch (const std::exception &) {
//failure to fold
}
if (!folded) {
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper);
}
}
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, oper);
break;
case(Operator_Precidence::Logical_And) :