diff --git a/include/chaiscript/dispatchkit/bootstrap_stl.hpp b/include/chaiscript/dispatchkit/bootstrap_stl.hpp index 6f59ff07..e2ec267f 100644 --- a/include/chaiscript/dispatchkit/bootstrap_stl.hpp +++ b/include/chaiscript/dispatchkit/bootstrap_stl.hpp @@ -37,7 +37,7 @@ namespace chaiscript /// Bidir_Range, based on the D concept of ranges. /// \todo Update the Range code to base its capabilities on /// the user_typetraits of the iterator passed in - template + template struct Bidir_Range { typedef Container container_type; @@ -79,64 +79,6 @@ namespace chaiscript return (*m_begin); } - decltype(auto) back() const - { - if (empty()) - { - throw std::range_error("Range empty"); - } - typename Container::iterator pos = m_end; - --pos; - return (*(pos)); - } - - typename Container::iterator m_begin; - typename Container::iterator m_end; - }; - - template - struct Const_Bidir_Range - { - typedef const Container container_type; - typedef typename std::iterator_traits::reference const_reference_type; - - Const_Bidir_Range(const Container &c) - : m_begin(c.begin()), m_end(c.end()) - { - } - - bool empty() const - { - return m_begin == m_end; - } - - void pop_front() - { - if (empty()) - { - throw std::range_error("Range empty"); - } - ++m_begin; - } - - void pop_back() - { - if (empty()) - { - throw std::range_error("Range empty"); - } - --m_end; - } - - decltype(auto) front() const - { - if (empty()) - { - throw std::range_error("Range empty"); - } - return (*m_begin); - } - decltype(auto) back() const { if (empty()) @@ -148,8 +90,8 @@ namespace chaiscript return (*(pos)); } - typename Container::const_iterator m_begin; - typename Container::const_iterator m_end; + IterType m_begin; + IterType m_end; }; namespace detail { @@ -229,8 +171,8 @@ namespace chaiscript template void input_range_type(const std::string &type, Module& m) { - detail::input_range_type_impl >(type,m); - detail::input_range_type_impl >("Const_" + type, m); + detail::input_range_type_impl >(type,m); + detail::input_range_type_impl >("Const_" + type,m); } template ModulePtr input_range_type(const std::string &type) diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 2cf5c0cc..1b16b31c 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -62,7 +62,7 @@ namespace chaiscript Array_Call, Dot_Access, Lambda, Block, Scopeless_Block, Def, While, If, For, Ranged_For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Inline_Range, Try, Catch, Finally, Method, Attr_Decl, - Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant, Compiled + Logical_And, Logical_Or, Reference, Switch, Case, Default, Noop, Class, Binary, Arg, Global_Decl, Constant, Compiled }; enum class Operator_Precidence { Ternary_Cond, Logical_Or, diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 899a535a..20919f71 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -270,60 +270,13 @@ namespace chaiscript mutable std::atomic_uint_fast32_t m_loc = {0}; }; - template - struct Unused_Return_Fun_Call_AST_Node final : AST_Node_Impl { - Unused_Return_Fun_Call_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::Unused_Return_Fun_Call, std::move(t_loc), std::move(t_children)) { } - - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override - { - chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); - - std::vector params; - - params.reserve(this->children[1]->children.size()); - for (const auto &child : this->children[1]->children) { - params.push_back(child->eval(t_ss)); - } - - Boxed_Value fn(this->children[0]->eval(t_ss)); - - try { - return (*t_ss->boxed_cast(fn))(params, t_ss.conversions()); - } - catch(const exception::dispatch_error &e){ - throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'", e.parameters, e.functions, false, *t_ss); - } - catch(const exception::bad_boxed_cast &){ - try { - Const_Proxy_Function f = t_ss->boxed_cast(fn); - // handle the case where there is only 1 function to try to call and dispatch fails on it - throw exception::eval_error("Error calling function '" + this->children[0]->text + "'", params, {f}, false, *t_ss); - } catch (const exception::bad_boxed_cast &) { - throw exception::eval_error("'" + this->children[0]->pretty_print() + "' does not evaluate to a function."); - } - } - catch(const exception::arity_error &e){ - throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'"); - } - catch(const exception::guard_error &e){ - throw exception::eval_error(std::string(e.what()) + " with function '" + this->children[0]->text + "'"); - } - catch(detail::Return_Value &rv) { - return rv.retval; - } - } - }; - - - - template - struct Fun_Call_AST_Node final : AST_Node_Impl { + struct Fun_Call_AST_Node : AST_Node_Impl { Fun_Call_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::Fun_Call, std::move(t_loc), std::move(t_children)) { } - Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override + template + Boxed_Value do_eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { chaiscript::eval::detail::Function_Push_Pop fpp(t_ss); @@ -334,7 +287,9 @@ namespace chaiscript params.push_back(child->eval(t_ss)); } - fpp.save_params(params); + if (Save_Params) { + fpp.save_params(params); + } Boxed_Value fn(this->children[0]->eval(t_ss)); @@ -364,10 +319,28 @@ namespace chaiscript } } + Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override + { + return do_eval_internal(t_ss); + } }; + template + struct Unused_Return_Fun_Call_AST_Node final : Fun_Call_AST_Node { + Unused_Return_Fun_Call_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : + Fun_Call_AST_Node(std::move(t_ast_node_text), std::move(t_loc), std::move(t_children)) { } + + Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override + { + return this->template do_eval_internal(t_ss); + } + }; + + + + template struct Arg_AST_Node final : AST_Node_Impl { @@ -808,21 +781,6 @@ namespace chaiscript } }; - template - struct Ternary_Cond_AST_Node final : AST_Node_Impl { - Ternary_Cond_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::Ternary_Cond, std::move(t_loc), std::move(t_children)) - { 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), t_ss)) { - return this->children[1]->eval(t_ss); - } else { - return this->children[2]->eval(t_ss); - } - } - }; - template struct If_AST_Node final : AST_Node_Impl { diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 95b59bc2..54e1fdbc 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -196,7 +196,7 @@ namespace chaiscript { struct If { template auto optimize(const eval::AST_Node_Impl_Ptr &node) { - if ((node->identifier == AST_Node_Type::If || node->identifier == AST_Node_Type::Ternary_Cond) + if ((node->identifier == AST_Node_Type::If) && node->children.size() >= 2 && node->children[0]->identifier == AST_Node_Type::Constant) { diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 75dce561..a69adebe 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -2292,7 +2292,7 @@ namespace chaiscript throw exception::eval_error("Incomplete '" + oper + "' expression", File_Position(m_position.line, m_position.col), *m_filename); } - build_match>(prev_stack_top); + build_match>(prev_stack_top); } else { throw exception::eval_error("Incomplete '" + oper + "' expression",