Implement constant expression folding

This commit is contained in:
Jason Turner 2016-04-11 08:19:02 -06:00
parent 40694c798c
commit fe8f8a89a7
2 changed files with 32 additions and 1 deletions

View File

@ -737,6 +737,7 @@ namespace chaiscript
} else {
if (children.size() > 2) {
size_t i = 2;
/// \todo these string comparisons are clunky
while (i < children.size()) {
if (children[i]->text == "else") {
return children[i+1]->eval(t_ss);

View File

@ -2252,7 +2252,37 @@ namespace chaiscript
case(AST_Node_Type::Bitwise_Xor) :
case(AST_Node_Type::Bitwise_Or) :
case(AST_Node_Type::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);
}
}
break;
case(AST_Node_Type::Logical_And) :