diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 601ad6f..85352f9 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -1184,7 +1184,7 @@ private: struct Break_AST_Node final : AST_Node_Impl { Break_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::Break, std::move(t_loc), std::move(t_children)) { } - + Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &) const override{ throw detail::Break_Loop(); } diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 991227b..be58157 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -137,7 +137,8 @@ namespace chaiscript { 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) + && child->identifier != AST_Node_Type::Constant + && child->identifier != AST_Node_Type::Noop) || i == num_children - 1) { keepers.push_back(i); } @@ -245,7 +246,46 @@ namespace chaiscript { template auto optimize(const eval::AST_Node_Impl_Ptr &node) { - if (node->identifier == AST_Node_Type::Binary + if (node->identifier == AST_Node_Type::Prefix + && node->children.size() == 1 + && node->children[0]->identifier == AST_Node_Type::Constant) + { + try { + const auto &oper = node->text; + const auto parsed = Operators::to_operator(oper, true); + const auto lhs = std::dynamic_pointer_cast>(node->children[0])->m_value; + const auto match = oper + node->children[0]->text; + + if (parsed != Operators::Opers::invalid && parsed != Operators::Opers::bitwise_and && lhs.get_type_info().is_arithmetic()) { + const auto val = Boxed_Number::do_oper(parsed, lhs); + return chaiscript::make_shared, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val)); + } else if (lhs.get_type_info().bare_equal_type_info(typeid(bool)) && oper == "!") { + return chaiscript::make_shared, eval::Constant_AST_Node>(std::move(match), node->location, Boxed_Value(!boxed_cast(lhs))); + } + } catch (const std::exception &e) { + //failure to fold, that's OK + } + } else if ((node->identifier == AST_Node_Type::Logical_And || node->identifier == AST_Node_Type::Logical_Or) + && node->children.size() == 2 + && node->children[0]->identifier == AST_Node_Type::Constant + && node->children[1]->identifier == AST_Node_Type::Constant) + { + try { + const auto lhs = std::dynamic_pointer_cast>(node->children[0])->m_value; + const auto rhs = std::dynamic_pointer_cast>(node->children[1])->m_value; + if (lhs.get_type_info().bare_equal_type_info(typeid(bool)) && rhs.get_type_info().bare_equal_type_info(typeid(bool))) { + const auto match = node->children[0]->text + " " + node->text + " " + node->children[1]->text; + const auto val = [lhs_val = boxed_cast(lhs), rhs_val = boxed_cast(rhs), id = node->identifier] { + if (id == AST_Node_Type::Logical_And) { return Boxed_Value(lhs_val && rhs_val); } + else { return Boxed_Value(lhs_val || rhs_val); } + }(); + + return chaiscript::make_shared, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val)); + } + } catch (const std::exception &) { + //failure to fold, that's OK + } + } else 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) @@ -289,8 +329,11 @@ namespace chaiscript { return make_constant(Boxed_Number(arg).get_as()); } else if (fun_name == "long") { return make_constant(Boxed_Number(arg).get_as()); + } else if (fun_name == "size_t") { + return make_constant(Boxed_Number(arg).get_as()); } + } }