From 5a5600914c47a8c8cadb7c19d1b2f600a9a4aa55 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Wed, 21 Jun 2017 21:27:48 -0600 Subject: [PATCH] Move away from shared_ptr for parse nodes --- include/chaiscript/chaiscript_defines.hpp | 10 + include/chaiscript/dispatchkit/bootstrap.hpp | 10 +- .../dispatchkit/proxy_functions.hpp | 14 +- .../chaiscript/language/chaiscript_common.hpp | 93 ++++++-- .../chaiscript/language/chaiscript_engine.hpp | 4 +- .../chaiscript/language/chaiscript_eval.hpp | 224 ++++++++++-------- .../language/chaiscript_optimizer.hpp | 188 ++++++++------- .../chaiscript/language/chaiscript_parser.hpp | 54 ++--- src/main.cpp | 2 +- 9 files changed, 357 insertions(+), 242 deletions(-) diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index be837c26..5b2e84f4 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -93,6 +93,16 @@ namespace chaiscript { #endif } + template + inline std::unique_ptr make_unique(Arg && ... arg) + { +#ifdef CHAISCRIPT_USE_STD_MAKE_SHARED + return std::make_unique(std::forward(arg)...); +#else + return std::unique_ptr(static_cast(new D(std::forward(arg)...))); +#endif + } + struct Build_Info { static int version_major() { diff --git a/include/chaiscript/dispatchkit/bootstrap.hpp b/include/chaiscript/dispatchkit/bootstrap.hpp index cbb91a51..8aedb353 100644 --- a/include/chaiscript/dispatchkit/bootstrap.hpp +++ b/include/chaiscript/dispatchkit/bootstrap.hpp @@ -305,13 +305,13 @@ namespace chaiscript static bool has_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) { const auto pf = std::dynamic_pointer_cast(t_pf); - return pf && pf->get_parse_tree(); + return bool(pf); } - static chaiscript::AST_NodePtr get_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) + static const chaiscript::AST_Node &get_parse_tree(const chaiscript::Const_Proxy_Function &t_pf) { const auto pf = std::dynamic_pointer_cast(t_pf); - if (pf && pf->get_parse_tree()) + if (pf) { return pf->get_parse_tree(); } else { @@ -545,7 +545,7 @@ namespace chaiscript std::vector retval; std::transform(t_eval_error.call_stack.begin(), t_eval_error.call_stack.end(), std::back_inserter(retval), - &chaiscript::var &>); + &chaiscript::var); return retval; }), "call_stack"} } ); @@ -574,7 +574,7 @@ namespace chaiscript const auto children = t_node.get_children(); std::transform(children.begin(), children.end(), std::back_inserter(retval), - &chaiscript::var &>); + &chaiscript::var &>); return retval; }), "children"} } diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index bb57c698..2afda8dd 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -41,7 +41,7 @@ namespace chaiscript class Boxed_Number; struct AST_Node; - typedef std::shared_ptr AST_NodePtr; + typedef std::unique_ptr AST_NodePtr; namespace dispatch { @@ -346,8 +346,8 @@ namespace chaiscript { public: Dynamic_Proxy_Function( - int t_arity=-1, - AST_NodePtr t_parsenode = AST_NodePtr(), + const int t_arity, + std::shared_ptr t_parsenode, Param_Types t_param_types = Param_Types(), Proxy_Function t_guard = Proxy_Function()) : Proxy_Function_Base(build_param_type_list(t_param_types), t_arity), @@ -379,9 +379,9 @@ namespace chaiscript return m_guard; } - AST_NodePtr get_parse_tree() const + const AST_Node &get_parse_tree() const { - return m_parsenode; + return *m_parsenode; } @@ -445,7 +445,7 @@ namespace chaiscript private: Proxy_Function m_guard; - AST_NodePtr m_parsenode; + std::shared_ptr m_parsenode; }; @@ -457,7 +457,7 @@ namespace chaiscript Dynamic_Proxy_Function_Impl( Callable t_f, int t_arity=-1, - AST_NodePtr t_parsenode = AST_NodePtr(), + std::shared_ptr t_parsenode = AST_NodePtr(), Param_Types t_param_types = Param_Types(), Proxy_Function t_guard = Proxy_Function()) : Dynamic_Proxy_Function( diff --git a/include/chaiscript/language/chaiscript_common.hpp b/include/chaiscript/language/chaiscript_common.hpp index 602efd54..5fe377c4 100644 --- a/include/chaiscript/language/chaiscript_common.hpp +++ b/include/chaiscript/language/chaiscript_common.hpp @@ -124,8 +124,10 @@ namespace chaiscript /// \brief Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree - typedef std::shared_ptr AST_NodePtr; - typedef std::shared_ptr AST_NodePtr_Const; + typedef std::unique_ptr AST_NodePtr; + typedef std::unique_ptr AST_NodePtr_Const; + + struct AST_Node_Trace; /// \brief Classes which may be thrown during error cases when ChaiScript is executing. @@ -168,7 +170,7 @@ namespace chaiscript File_Position start_position; std::string filename; std::string detail; - std::vector call_stack; + std::vector call_stack; eval_error(const std::string &t_why, const File_Position &t_where, const std::string &t_fname, const std::vector &t_parameters, const std::vector &t_functions, @@ -228,26 +230,26 @@ namespace chaiscript template static AST_Node_Type id(const T& t) { - return t->identifier; + return t.identifier; } template static std::string pretty(const T& t) { - return t->pretty_print(); + return t.pretty_print(); } template static const std::string &fname(const T& t) { - return t->filename(); + return t.filename(); } template static std::string startpos(const T& t) { std::ostringstream oss; - oss << t->start().line << ", " << t->start().column; + oss << t.start().line << ", " << t.start().column; return oss.str(); } @@ -321,7 +323,7 @@ namespace chaiscript } } - retval += "\n Defined at " + format_location(dynfun->get_parse_tree()); + retval += "\n Defined at " + format_location(dynfun->get_parse_tree()); } return retval; @@ -330,20 +332,15 @@ namespace chaiscript template static std::string format_guard(const T &t) { - return t->pretty_print(); + return t.pretty_print(); } template static std::string format_location(const T &t) { - if (t) { - std::ostringstream oss; - oss << "(" << t->filename() << " " << t->start().line << ", " << t->start().column << ")"; - return oss.str(); - } else { - return "(internal)"; - } - + std::ostringstream oss; + oss << "(" << t.filename() << " " << t.start().line << ", " << t.start().column << ")"; + return oss.str(); } static std::string format_detail(const std::vector &t_functions, @@ -492,7 +489,7 @@ namespace chaiscript /// \brief Struct that doubles as both a parser ast_node and an AST node. - struct AST_Node : std::enable_shared_from_this { + struct AST_Node { public: const AST_Node_Type identifier; const std::string text; @@ -516,14 +513,14 @@ namespace chaiscript oss << text; - for (auto & elem : this->get_children()) { - oss << elem->pretty_print() << ' '; + for (auto & elem : get_children()) { + oss << elem.get().pretty_print() << ' '; } return oss.str(); } - virtual std::vector get_children() const = 0; + virtual std::vector> get_children() const = 0; virtual Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const = 0; @@ -534,8 +531,8 @@ namespace chaiscript oss << t_prepend << "(" << ast_node_type_to_string(this->identifier) << ") " << this->text << " : " << this->location.start.line << ", " << this->location.start.column << '\n'; - for (auto & elem : this->get_children()) { - oss << elem->to_string(t_prepend + " "); + for (auto & elem : get_children()) { + oss << elem.get().to_string(t_prepend + " "); } return oss.str(); } @@ -568,12 +565,60 @@ namespace chaiscript }; + struct AST_Node_Trace + { + const AST_Node_Type identifier; + const std::string text; + Parse_Location location; + + const std::string &filename() const { + return *location.filename; + } + + const File_Position &start() const { + return location.start; + } + + const File_Position &end() const { + return location.end; + } + + std::string pretty_print() const + { + std::ostringstream oss; + + oss << text; + + for (const auto & elem : children) { + oss << elem.pretty_print() << ' '; + } + + return oss.str(); + } + + std::vector get_children(const AST_Node &node) + { + const auto node_children = node.get_children(); + return std::vector(node_children.begin(), node_children.end()); + } + + AST_Node_Trace(const AST_Node &node) + : identifier(node.identifier), text(node.text), + location(node.location), children(get_children(node)) + { + } + + + std::vector children; + + }; + namespace parser { class ChaiScript_Parser_Base { public: virtual AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) = 0; - virtual void debug_print(AST_NodePtr t, std::string prepend = "") const = 0; + virtual void debug_print(const AST_Node &t, std::string prepend = "") const = 0; virtual void *get_tracer_ptr() = 0; virtual ~ChaiScript_Parser_Base() = default; ChaiScript_Parser_Base() = default; diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index 37131773..dc0b8536 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -332,9 +332,9 @@ explicit ChaiScript_Basic(std::unique_ptr &&pars AST_NodePtr parse(const std::string &t_input, const bool t_debug_print = false) { - const auto ast = m_parser->parse(t_input, "PARSE"); + auto ast = m_parser->parse(t_input, "PARSE"); if (t_debug_print) { - m_parser->debug_print(ast); + m_parser->debug_print(*ast); } return ast; } diff --git a/include/chaiscript/language/chaiscript_eval.hpp b/include/chaiscript/language/chaiscript_eval.hpp index 95e2218e..4388649d 100644 --- a/include/chaiscript/language/chaiscript_eval.hpp +++ b/include/chaiscript/language/chaiscript_eval.hpp @@ -47,13 +47,13 @@ namespace chaiscript { template struct AST_Node_Impl; - template using AST_Node_Impl_Ptr = typename std::shared_ptr>; + template using AST_Node_Impl_Ptr = typename std::unique_ptr>; namespace detail { /// Helper function that will set up the scope around a function call, including handling the named function parameters template - static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl_Ptr &t_node, const std::vector &t_param_names, const std::vector &t_vals, const std::map *t_locals=nullptr, bool has_this_capture = false) { + static Boxed_Value eval_function(chaiscript::detail::Dispatch_Engine &t_ss, const AST_Node_Impl &t_node, const std::vector &t_param_names, const std::vector &t_vals, const std::map *t_locals=nullptr, bool has_this_capture = false) { chaiscript::detail::Dispatch_State state(t_ss); const Boxed_Value *thisobj = [&]() -> const Boxed_Value *{ @@ -83,7 +83,7 @@ namespace chaiscript } try { - return t_node->eval(state); + return t_node.eval(state); } catch (detail::Return_Value &rv) { return std::move(rv.retval); } @@ -106,8 +106,14 @@ namespace chaiscript } - std::vector get_children() const final { - return {children.begin(), children.end()}; + std::vector> get_children() const final { + std::vector> retval; + retval.reserve(children.size()); + for (auto &&child : children) { + retval.emplace_back(*child); + } + + return retval; } Boxed_Value eval(const chaiscript::detail::Dispatch_State &t_e) const final @@ -116,7 +122,7 @@ namespace chaiscript T::trace(t_e, this); return eval_internal(t_e); } catch (exception::eval_error &ee) { - ee.call_stack.push_back(shared_from_this()); + ee.call_stack.push_back(*this); throw; } } @@ -364,44 +370,44 @@ namespace chaiscript AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Arg_List, std::move(t_loc), std::move(t_children)) { } - static std::string get_arg_name(const AST_Node_Impl_Ptr &t_node) { - if (t_node->children.empty()) + static std::string get_arg_name(const AST_Node_Impl &t_node) { + if (t_node.children.empty()) { - return t_node->text; - } else if (t_node->children.size() == 1) { - return t_node->children[0]->text; + return t_node.text; + } else if (t_node.children.size() == 1) { + return t_node.children[0]->text; } else { - return t_node->children[1]->text; + return t_node.children[1]->text; } } - static std::vector get_arg_names(const AST_Node_Impl_Ptr &t_node) { + static std::vector get_arg_names(const AST_Node_Impl &t_node) { std::vector retval; - for (const auto &node : t_node->children) + for (const auto &node : t_node.children) { - retval.push_back(get_arg_name(node)); + retval.push_back(get_arg_name(*node)); } return retval; } - static std::pair get_arg_type(const AST_Node_Impl_Ptr &t_node, const chaiscript::detail::Dispatch_State &t_ss) + static std::pair get_arg_type(const AST_Node_Impl &t_node, const chaiscript::detail::Dispatch_State &t_ss) { - if (t_node->children.size() < 2) + if (t_node.children.size() < 2) { return {}; } else { - return {t_node->children[0]->text, t_ss->get_type(t_node->children[0]->text, false)}; + return {t_node.children[0]->text, t_ss->get_type(t_node.children[0]->text, false)}; } } - static dispatch::Param_Types get_arg_types(const AST_Node_Impl_Ptr &t_node, const chaiscript::detail::Dispatch_State &t_ss) { + static dispatch::Param_Types get_arg_types(const AST_Node_Impl &t_node, const chaiscript::detail::Dispatch_State &t_ss) { std::vector> retval; - for (const auto &child : t_node->children) + for (const auto &child : t_node.children) { - retval.push_back(get_arg_type(child, t_ss)); + retval.push_back(get_arg_type(*child, t_ss)); } return dispatch::Param_Types(std::move(retval)); @@ -621,9 +627,15 @@ namespace chaiscript template struct Lambda_AST_Node final : AST_Node_Impl { Lambda_AST_Node(std::string t_ast_node_text, Parse_Location t_loc, std::vector> t_children) : - AST_Node_Impl(t_ast_node_text, AST_Node_Type::Lambda, std::move(t_loc), std::move(t_children)), - m_param_names(Arg_List_AST_Node::get_arg_names(this->children[1])), - m_this_capture(has_this_capture(this->children[0]->children)) + AST_Node_Impl(t_ast_node_text, + AST_Node_Type::Lambda, + std::move(t_loc), + std::vector>(std::make_move_iterator(t_children.begin()), + std::make_move_iterator(std::prev(t_children.end()))) + ), + m_param_names(Arg_List_AST_Node::get_arg_names(*this->children[1])), + m_this_capture(has_this_capture(this->children[0]->children)), + m_lambda_node(std::move(t_children.back())) { } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override { @@ -637,18 +649,18 @@ namespace chaiscript }(); const auto numparams = this->children[1]->children.size(); - const auto param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss); + const auto param_types = Arg_List_AST_Node::get_arg_types(*this->children[1], t_ss); - const auto &lambda_node = this->children.back(); std::reference_wrapper engine(*t_ss); return Boxed_Value( dispatch::make_dynamic_proxy_function( - [engine, lambda_node, param_names = this->m_param_names, captures, this_capture = this->m_this_capture](const std::vector &t_params) + [engine, lambda_node = this->m_lambda_node, param_names = this->m_param_names, captures, + this_capture = this->m_this_capture] (const std::vector &t_params) { - return detail::eval_function(engine, lambda_node, param_names, t_params, &captures, this_capture); + return detail::eval_function(engine, *lambda_node, param_names, t_params, &captures, this_capture); }, - static_cast(numparams), lambda_node, param_types + static_cast(numparams), m_lambda_node, param_types ) ); } @@ -664,7 +676,7 @@ namespace chaiscript private: const std::vector m_param_names; const bool m_this_capture = false; - + const std::shared_ptr> m_lambda_node; }; template @@ -699,55 +711,81 @@ namespace chaiscript template struct Def_AST_Node final : AST_Node_Impl { + + std::shared_ptr> m_body_node; + std::shared_ptr> m_guard_node; + Def_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::Def, std::move(t_loc), std::move(t_children)) { } + AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Def, std::move(t_loc), + std::vector>(std::make_move_iterator(t_children.begin()), + std::make_move_iterator(std::prev(t_children.end(), has_guard(t_children)?2:1))) + ), + m_body_node(get_body_node(std::move(t_children))), + m_guard_node(get_guard_node(std::move(t_children), t_children.size()-this->children.size()==2)) + + { } + + static std::shared_ptr> get_guard_node(std::vector> &&vec, bool has_guard) + { + if (has_guard) { + return std::move(*std::prev(vec.end(), 2)); + } else { + return {}; + } + } + + static std::shared_ptr> get_body_node(std::vector> &&vec) + { + return std::move(vec.back()); + } + + static bool has_guard(const std::vector> &t_children) + { + if ((t_children.size() > 2) && (t_children[1]->identifier == AST_Node_Type::Arg_List)) { + if (t_children.size() > 3) { + return true; + } + } + else { + if (t_children.size() > 2) { + return true; + } + } + return false; + } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ std::vector t_param_names; size_t numparams = 0; - AST_Node_Impl_Ptr guardnode; dispatch::Param_Types param_types; - if ((this->children.size() > 2) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { + if ((this->children.size() > 1) && (this->children[1]->identifier == AST_Node_Type::Arg_List)) { numparams = this->children[1]->children.size(); - t_param_names = Arg_List_AST_Node::get_arg_names(this->children[1]); - param_types = Arg_List_AST_Node::get_arg_types(this->children[1], t_ss); - - if (this->children.size() > 3) { - guardnode = this->children[2]; - } - } - else { - //no parameters - numparams = 0; - - if (this->children.size() > 2) { - guardnode = this->children[1]; - } + t_param_names = Arg_List_AST_Node::get_arg_names(*this->children[1]); + param_types = Arg_List_AST_Node::get_arg_types(*this->children[1], t_ss); } std::reference_wrapper engine(*t_ss); std::shared_ptr guard; - if (guardnode) { + if (m_guard_node) { guard = dispatch::make_dynamic_proxy_function( - [engine, guardnode, t_param_names](const std::vector &t_params) + [engine, guardnode = m_guard_node, t_param_names](const std::vector &t_params) { - return detail::eval_function(engine, guardnode, t_param_names, t_params); + return detail::eval_function(engine, *guardnode, t_param_names, t_params); }, - static_cast(numparams), guardnode); + static_cast(numparams), m_guard_node); } try { const std::string & l_function_name = this->children[0]->text; - const auto & func_node = this->children.back(); t_ss->add( dispatch::make_dynamic_proxy_function( - [engine, guardnode, func_node, t_param_names](const std::vector &t_params) + [engine, func_node = m_body_node, t_param_names](const std::vector &t_params) { - return detail::eval_function(engine, func_node, t_param_names, t_params); + return detail::eval_function(engine, *func_node, t_param_names, t_params); }, - static_cast(numparams), this->children.back(), + static_cast(numparams), m_body_node, param_types, guard), l_function_name); } catch (const exception::name_conflict_error &e) { throw exception::eval_error("Function redefined '" + e.name() + "'"); @@ -1230,32 +1268,32 @@ namespace chaiscript } for (size_t i = 1; i < end_point; ++i) { chaiscript::eval::detail::Scope_Push_Pop catch_scope(t_ss); - AST_Node_Impl_Ptr catch_block = this->children[i]; + auto &catch_block = *this->children[i]; - if (catch_block->children.size() == 1) { + if (catch_block.children.size() == 1) { //No variable capture, no guards - retval = catch_block->children[0]->eval(t_ss); + retval = catch_block.children[0]->eval(t_ss); break; - } else if (catch_block->children.size() == 2 || catch_block->children.size() == 3) { - const auto name = Arg_List_AST_Node::get_arg_name(catch_block->children[0]); + } else if (catch_block.children.size() == 2 || catch_block.children.size() == 3) { + const auto name = Arg_List_AST_Node::get_arg_name(*catch_block.children[0]); if (dispatch::Param_Types( - std::vector>{Arg_List_AST_Node::get_arg_type(catch_block->children[0], t_ss)} + std::vector>{Arg_List_AST_Node::get_arg_type(*catch_block.children[0], t_ss)} ).match(std::vector{t_except}, t_ss.conversions()).first) { t_ss.add_object(name, t_except); - if (catch_block->children.size() == 2) { + if (catch_block.children.size() == 2) { //Variable capture, no guards - retval = catch_block->children[1]->eval(t_ss); + retval = catch_block.children[1]->eval(t_ss); break; } - else if (catch_block->children.size() == 3) { + else if (catch_block.children.size() == 3) { //Variable capture, guards bool guard = false; try { - guard = boxed_cast(catch_block->children[1]->eval(t_ss)); + guard = boxed_cast(catch_block.children[1]->eval(t_ss)); } catch (const exception::bad_boxed_cast &) { if (this->children.back()->identifier == AST_Node_Type::Finally) { this->children.back()->children[0]->eval(t_ss); @@ -1263,7 +1301,7 @@ namespace chaiscript throw exception::eval_error("Guard condition not boolean"); } if (guard) { - retval = catch_block->children[2]->eval(t_ss); + retval = catch_block.children[2]->eval(t_ss); break; } } @@ -1335,8 +1373,18 @@ namespace chaiscript template struct Method_AST_Node final : AST_Node_Impl { + std::shared_ptr> m_body_node; + std::shared_ptr> m_guard_node; + Method_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::Method, std::move(t_loc), std::move(t_children)) { } + AST_Node_Impl(std::move(t_ast_node_text), AST_Node_Type::Method, std::move(t_loc), + std::vector>(std::make_move_iterator(t_children.begin()), + std::make_move_iterator(std::prev(t_children.end(), Def_AST_Node::has_guard(t_children)?2:1))) + ), + m_body_node(Def_AST_Node::get_body_node(std::move(t_children))), + m_guard_node(Def_AST_Node::get_guard_node(std::move(t_children), t_children.size()-this->children.size()==2)) + { + } Boxed_Value eval_internal(const chaiscript::detail::Dispatch_State &t_ss) const override{ @@ -1348,39 +1396,27 @@ namespace chaiscript std::vector t_param_names{"this"}; dispatch::Param_Types param_types; - if ((this->children.size() > 3) + if ((this->children.size() > 2) && (this->children[2]->identifier == AST_Node_Type::Arg_List)) { - auto args = Arg_List_AST_Node::get_arg_names(this->children[2]); + auto args = Arg_List_AST_Node::get_arg_names(*this->children[2]); t_param_names.insert(t_param_names.end(), args.begin(), args.end()); - param_types = Arg_List_AST_Node::get_arg_types(this->children[2], t_ss); - - if (this->children.size() > 4) { - guardnode = this->children[3]; - } - } - else { - //no parameters - - if (this->children.size() > 3) { - guardnode = this->children[2]; - } + param_types = Arg_List_AST_Node::get_arg_types(*this->children[2], t_ss); } const size_t numparams = t_param_names.size(); std::shared_ptr guard; std::reference_wrapper engine(*t_ss); - if (guardnode) { + if (m_guard_node) { guard = dispatch::make_dynamic_proxy_function( - [engine, t_param_names, guardnode](const std::vector &t_params) { - return chaiscript::eval::detail::eval_function(engine, guardnode, t_param_names, t_params); + [engine, t_param_names, guardnode = m_guard_node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(engine, *guardnode, t_param_names, t_params); }, - static_cast(numparams), guardnode); + static_cast(numparams), m_guard_node); } try { const std::string & function_name = this->children[1]->text; - auto node = this->children.back(); if (function_name == class_name) { param_types.push_front(class_name, Type_Info()); @@ -1388,10 +1424,10 @@ namespace chaiscript t_ss->add( std::make_shared(class_name, dispatch::make_dynamic_proxy_function( - [engine, t_param_names, node](const std::vector &t_params) { - return chaiscript::eval::detail::eval_function(engine, node, t_param_names, t_params); + [engine, t_param_names, node = m_body_node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params); }, - static_cast(numparams), node, param_types, guard + static_cast(numparams), m_body_node, param_types, guard ) ), function_name); @@ -1402,15 +1438,17 @@ namespace chaiscript auto type = t_ss->get_type(class_name, false); param_types.push_front(class_name, type); - t_ss->add(std::make_shared(class_name, + t_ss->add( + std::make_shared(class_name, dispatch::make_dynamic_proxy_function( - [engine, t_param_names, node](const std::vector &t_params) { - return chaiscript::eval::detail::eval_function(engine, node, t_param_names, t_params); + [engine, t_param_names, node = m_body_node](const std::vector &t_params) { + return chaiscript::eval::detail::eval_function(engine, *node, t_param_names, t_params); }, - static_cast(numparams), node, param_types, guard), type), + static_cast(numparams), m_body_node, param_types, guard), type), function_name); } } catch (const exception::name_conflict_error &e) { + std::cout << "Method!!" << std::endl; throw exception::eval_error("Method redefined '" + e.name() + "'"); } return void_var(); diff --git a/include/chaiscript/language/chaiscript_optimizer.hpp b/include/chaiscript/language/chaiscript_optimizer.hpp index 996b6971..675d092c 100644 --- a/include/chaiscript/language/chaiscript_optimizer.hpp +++ b/include/chaiscript/language/chaiscript_optimizer.hpp @@ -24,17 +24,26 @@ namespace chaiscript { template auto optimize(eval::AST_Node_Impl_Ptr p) { - (void)std::initializer_list{ (p = static_cast(*this).optimize(p), 0)... }; + (void)std::initializer_list{ (p = static_cast(*this).optimize(std::move(p)), 0)... }; return p; } }; template - auto child_at(const eval::AST_Node_Impl_Ptr &node, const size_t offset) { - if (node->children[offset]->identifier == AST_Node_Type::Compiled) { - return dynamic_cast&>(*node->children[offset]).m_original_node; + eval::AST_Node_Impl &child_at(eval::AST_Node_Impl &node, const size_t offset) { + if (node.children[offset]->identifier == AST_Node_Type::Compiled) { + return *(dynamic_cast &>(*node.children[offset]).m_original_node); } else { - return node->children[offset]; + return *node.children[offset]; + } + } + + template + const eval::AST_Node_Impl &child_at(const eval::AST_Node_Impl &node, const size_t offset) { + if (node.children[offset]->identifier == AST_Node_Type::Compiled) { + return *(dynamic_cast &>(*node.children[offset]).m_original_node); + } else { + return *node.children[offset]; } @@ -48,24 +57,24 @@ namespace chaiscript { } template - auto child_count(const eval::AST_Node_Impl_Ptr &node) { - if (node->identifier == AST_Node_Type::Compiled) { - return dynamic_cast&>(*node).m_original_node->children.size(); + auto child_count(const eval::AST_Node_Impl &node) { + if (node.identifier == AST_Node_Type::Compiled) { + return dynamic_cast&>(node).m_original_node->children.size(); } else { - return node->children.size(); + return node.children.size(); } } template - auto make_compiled_node(const eval::AST_Node_Impl_Ptr &original_node, std::vector> children, Callable callable) + auto make_compiled_node(eval::AST_Node_Impl_Ptr original_node, std::vector> children, Callable callable) { - return chaiscript::make_shared, eval::Compiled_AST_Node>(original_node, std::move(children), std::move(callable)); + return chaiscript::make_unique, eval::Compiled_AST_Node>(std::move(original_node), std::move(children), std::move(callable)); } struct Return { template - auto optimize(const eval::AST_Node_Impl_Ptr &p) + auto optimize(eval::AST_Node_Impl_Ptr p) { if ( (p->identifier == AST_Node_Type::Def || p->identifier == AST_Node_Type::Lambda) && !p->children.empty()) @@ -75,7 +84,7 @@ namespace chaiscript { auto &block_last_child = last_child->children.back(); if (block_last_child->identifier == AST_Node_Type::Return) { if (block_last_child->children.size() == 1) { - last_child->children.back() = block_last_child->children[0]; + last_child->children.back() = std::move(block_last_child->children[0]); } } } @@ -86,9 +95,9 @@ namespace chaiscript { }; template - bool contains_var_decl_in_scope(const T &node) + bool contains_var_decl_in_scope(const eval::AST_Node_Impl &node) { - if (node->identifier == AST_Node_Type::Var_Decl) { + if (node.identifier == AST_Node_Type::Var_Decl) { return true; } @@ -96,8 +105,8 @@ namespace chaiscript { for (size_t i = 0; i < num; ++i) { const auto &child = child_at(node, i); - if (child->identifier != AST_Node_Type::Block - && child->identifier != AST_Node_Type::For + if (child.identifier != AST_Node_Type::Block + && child.identifier != AST_Node_Type::For && contains_var_decl_in_scope(child)) { return true; } @@ -108,15 +117,16 @@ namespace chaiscript { struct Block { template - auto optimize(const eval::AST_Node_Impl_Ptr &node) { + auto optimize(eval::AST_Node_Impl_Ptr node) { if (node->identifier == AST_Node_Type::Block) { - if (!contains_var_decl_in_scope(node)) + if (!contains_var_decl_in_scope(*node)) { if (node->children.size() == 1) { - return node->children[0]; + return std::move(node->children[0]); } else { - return chaiscript::make_shared, eval::Scopeless_Block_AST_Node>(node->text, node->location, node->children); + return chaiscript::make_unique, eval::Scopeless_Block_AST_Node>(node->text, node->location, + std::move(node->children)); } } } @@ -127,7 +137,7 @@ namespace chaiscript { struct Dead_Code { template - auto optimize(const eval::AST_Node_Impl_Ptr &node) { + auto optimize(eval::AST_Node_Impl_Ptr node) { if (node->identifier == AST_Node_Type::Block) { std::vector keepers; @@ -135,10 +145,10 @@ namespace chaiscript { 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 - && child->identifier != AST_Node_Type::Noop) + const auto &child = *node->children[i]; + if ( (child.identifier != AST_Node_Type::Id + && child.identifier != AST_Node_Type::Constant + && child.identifier != AST_Node_Type::Noop) || i == num_children - 1) { keepers.push_back(i); } @@ -147,12 +157,16 @@ namespace chaiscript { 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); + const auto new_children = [&](){ + std::vector> retval; + for (const auto x : keepers) + { + retval.push_back(std::move(node->children[x])); + } + return retval; + }; + + return chaiscript::make_unique, eval::Block_AST_Node>(node->text, node->location, new_children()); } } else { return node; @@ -162,29 +176,30 @@ namespace chaiscript { struct Unused_Return { template - auto optimize(const eval::AST_Node_Impl_Ptr &node) { + auto optimize(eval::AST_Node_Impl_Ptr node) { if ((node->identifier == AST_Node_Type::Block || node->identifier == AST_Node_Type::Scopeless_Block) && !node->children.empty()) { for (size_t i = 0; i < node->children.size()-1; ++i) { - auto child = node->children[i]; + auto child = node->children[i].get(); if (child->identifier == AST_Node_Type::Fun_Call) { - node->children[i] = chaiscript::make_shared, eval::Unused_Return_Fun_Call_AST_Node>(child->text, child->location, std::move(child->children)); + node->children[i] = chaiscript::make_unique, eval::Unused_Return_Fun_Call_AST_Node>(child->text, child->location, + std::move(child->children)); } } } else if ((node->identifier == AST_Node_Type::For || node->identifier == AST_Node_Type::While) - && child_count(node) > 0) { - auto child = child_at(node, child_count(node) - 1); - if (child->identifier == AST_Node_Type::Block - || child->identifier == AST_Node_Type::Scopeless_Block) + && child_count(*node) > 0) { + auto &child = child_at(*node, child_count(*node) - 1); + if (child.identifier == AST_Node_Type::Block + || child.identifier == AST_Node_Type::Scopeless_Block) { auto num_sub_children = child_count(child); for (size_t i = 0; i < num_sub_children; ++i) { - auto sub_child = child_at(child, i); - if (sub_child->identifier == AST_Node_Type::Fun_Call) { - child->children[i] = chaiscript::make_shared, eval::Unused_Return_Fun_Call_AST_Node>(sub_child->text, sub_child->location, std::move(sub_child->children)); + auto &sub_child = child_at(child, i); + if (sub_child.identifier == AST_Node_Type::Fun_Call) { + child.children[i] = chaiscript::make_unique, eval::Unused_Return_Fun_Call_AST_Node>(sub_child.text, sub_child.location, std::move(sub_child.children)); } } } @@ -195,17 +210,17 @@ namespace chaiscript { struct If { template - auto optimize(const eval::AST_Node_Impl_Ptr &node) { + auto optimize(eval::AST_Node_Impl_Ptr node) { if ((node->identifier == AST_Node_Type::If) && node->children.size() >= 2 && node->children[0]->identifier == AST_Node_Type::Constant) { - const auto condition = std::dynamic_pointer_cast>(node->children[0])->m_value; + const auto condition = dynamic_cast *>(node->children[0].get())->m_value; if (condition.get_type_info().bare_equal_type_info(typeid(bool))) { if (boxed_cast(condition)) { - return node->children[1]; + return std::move(node->children[1]); } else if (node->children.size() == 3) { - return node->children[2]; + return std::move(node->children[2]); } } } @@ -216,7 +231,7 @@ namespace chaiscript { struct Partial_Fold { template - auto optimize(const eval::AST_Node_Impl_Ptr &node) { + auto optimize(eval::AST_Node_Impl_Ptr node) { // Fold right side if (node->identifier == AST_Node_Type::Binary @@ -228,9 +243,10 @@ namespace chaiscript { const auto &oper = node->text; const auto parsed = Operators::to_operator(oper); if (parsed != Operators::Opers::invalid) { - const auto rhs = std::dynamic_pointer_cast>(node->children[1])->m_value; + const auto rhs = dynamic_cast *>(node->children[1].get())->m_value; if (rhs.get_type_info().is_arithmetic()) { - return chaiscript::make_shared, eval::Fold_Right_Binary_Operator_AST_Node>(node->text, node->location, node->children, rhs); + return chaiscript::make_unique, eval::Fold_Right_Binary_Operator_AST_Node>(node->text, node->location, + std::move(node->children), rhs); } } } catch (const std::exception &) { @@ -244,7 +260,7 @@ namespace chaiscript { struct Constant_Fold { template - auto optimize(const eval::AST_Node_Impl_Ptr &node) { + auto optimize(eval::AST_Node_Impl_Ptr node) { if (node->identifier == AST_Node_Type::Prefix && node->children.size() == 1 @@ -253,14 +269,14 @@ namespace chaiscript { 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 lhs = dynamic_cast *>(node->children[0].get())->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)); + return chaiscript::make_unique, 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))); + return chaiscript::make_unique, eval::Constant_AST_Node>(std::move(match), node->location, Boxed_Value(!boxed_cast(lhs))); } } catch (const std::exception &) { //failure to fold, that's OK @@ -271,8 +287,8 @@ namespace chaiscript { && 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; + const auto lhs = dynamic_cast &>(*node->children[0]).m_value; + const auto rhs = dynamic_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] { @@ -280,7 +296,7 @@ namespace chaiscript { else { return Boxed_Value(lhs_val || rhs_val); } }(); - return chaiscript::make_shared, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val)); + return chaiscript::make_unique, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val)); } } catch (const std::exception &) { //failure to fold, that's OK @@ -294,12 +310,12 @@ namespace chaiscript { const auto &oper = node->text; const auto parsed = Operators::to_operator(oper); if (parsed != Operators::Opers::invalid) { - const auto lhs = std::dynamic_pointer_cast>(node->children[0])->m_value; - const auto rhs = std::dynamic_pointer_cast>(node->children[1])->m_value; + const auto lhs = dynamic_cast &>(*node->children[0]).m_value; + const auto rhs = dynamic_cast &>(*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, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val)); + return chaiscript::make_unique, eval::Constant_AST_Node>(std::move(match), node->location, std::move(val)); } } } catch (const std::exception &) { @@ -312,13 +328,13 @@ namespace chaiscript { && node->children[1]->children.size() == 1 && node->children[1]->children[0]->identifier == AST_Node_Type::Constant) { - const auto arg = std::dynamic_pointer_cast>(node->children[1]->children[0])->m_value; + const auto arg = dynamic_cast &>(*node->children[1]->children[0]).m_value; if (arg.get_type_info().is_arithmetic()) { const auto &fun_name = node->children[0]->text; const auto make_constant = [&node, &fun_name](auto val){ const auto match = fun_name + "(" + node->children[1]->children[0]->text + ")"; - return chaiscript::make_shared, eval::Constant_AST_Node>(std::move(match), node->location, Boxed_Value(val)); + return chaiscript::make_unique, eval::Constant_AST_Node>(std::move(match), node->location, Boxed_Value(val)); }; if (fun_name == "double") { @@ -344,35 +360,36 @@ namespace chaiscript { struct For_Loop { template - auto optimize(const eval::AST_Node_Impl_Ptr &for_node) { + auto optimize(eval::AST_Node_Impl_Ptr for_node) { if (for_node->identifier != AST_Node_Type::For) { return for_node; } - const auto eq_node = child_at(for_node, 0); - const auto binary_node = child_at(for_node, 1); - const auto prefix_node = child_at(for_node, 2); + const auto &eq_node = child_at(*for_node, 0); + const auto &binary_node = child_at(*for_node, 1); + const auto &prefix_node = child_at(*for_node, 2); - if (eq_node->identifier == AST_Node_Type::Equation + if (child_count(*for_node) == 4 + && eq_node.identifier == AST_Node_Type::Equation && child_count(eq_node) == 2 - && child_at(eq_node, 0)->identifier == AST_Node_Type::Var_Decl - && child_at(eq_node, 1)->identifier == AST_Node_Type::Constant - && binary_node->identifier == AST_Node_Type::Binary - && binary_node->text == "<" + && child_at(eq_node, 0).identifier == AST_Node_Type::Var_Decl + && child_at(eq_node, 1).identifier == AST_Node_Type::Constant + && binary_node.identifier == AST_Node_Type::Binary + && binary_node.text == "<" && child_count(binary_node) == 2 - && child_at(binary_node, 0)->identifier == AST_Node_Type::Id - && child_at(binary_node, 0)->text == child_at(child_at(eq_node,0), 0)->text - && child_at(binary_node, 1)->identifier == AST_Node_Type::Constant - && prefix_node->identifier == AST_Node_Type::Prefix - && prefix_node->text == "++" + && child_at(binary_node, 0).identifier == AST_Node_Type::Id + && child_at(binary_node, 0).text == child_at(child_at(eq_node,0), 0).text + && child_at(binary_node, 1).identifier == AST_Node_Type::Constant + && prefix_node.identifier == AST_Node_Type::Prefix + && prefix_node.text == "++" && child_count(prefix_node) == 1 - && child_at(prefix_node, 0)->identifier == AST_Node_Type::Id - && child_at(prefix_node, 0)->text == child_at(child_at(eq_node,0), 0)->text) + && child_at(prefix_node, 0).identifier == AST_Node_Type::Id + && child_at(prefix_node, 0).text == child_at(child_at(eq_node,0), 0).text) { - const Boxed_Value &begin = std::dynamic_pointer_cast>(child_at(eq_node, 1))->m_value; - const Boxed_Value &end = std::dynamic_pointer_cast>(child_at(binary_node, 1))->m_value; - const std::string &id = child_at(prefix_node, 0)->text; + const Boxed_Value &begin = dynamic_cast &>(child_at(eq_node, 1)).m_value; + const Boxed_Value &end = dynamic_cast &>(child_at(binary_node, 1)).m_value; + const std::string &id = child_at(prefix_node, 0).text; if (begin.get_type_info().bare_equal(user_type()) && end.get_type_info().bare_equal(user_type())) { @@ -380,9 +397,14 @@ namespace chaiscript { const auto start_int = boxed_cast(begin); const auto end_int = boxed_cast(end); - const auto body = child_at(for_node, 3); - - return make_compiled_node(for_node, {body}, + // note that we are moving the last element out, then popping the empty shared_ptr + // from the vector + std::vector> body_vector; + auto body_child = std::move(for_node->children[3]); + for_node->children.pop_back(); + body_vector.emplace_back(std::move(body_child)); + + return make_compiled_node(std::move(for_node), std::move(body_vector), [id, start_int, end_int](const std::vector> &children, const chaiscript::detail::Dispatch_State &t_ss) { assert(children.size() == 1); chaiscript::eval::detail::Scope_Push_Pop spp(t_ss); diff --git a/include/chaiscript/language/chaiscript_parser.hpp b/include/chaiscript/language/chaiscript_parser.hpp index 93e69343..73575ef5 100644 --- a/include/chaiscript/language/chaiscript_parser.hpp +++ b/include/chaiscript/language/chaiscript_parser.hpp @@ -397,7 +397,7 @@ namespace chaiscript return m_optimizer; } - ChaiScript_Parser(const ChaiScript_Parser &) = default; + ChaiScript_Parser(const ChaiScript_Parser &) = delete; ChaiScript_Parser &operator=(const ChaiScript_Parser &) = delete; ChaiScript_Parser(ChaiScript_Parser &&) = default; ChaiScript_Parser &operator=(ChaiScript_Parser &&) = delete; @@ -406,10 +406,10 @@ namespace chaiscript bool char_in_alphabet(char c, detail::Alphabet a) const { return m_alphabet[a][static_cast(c)]; } /// Prints the parsed ast_nodes as a tree - void debug_print(AST_NodePtr t, std::string prepend = "") const override { - std::cout << prepend << "(" << ast_node_type_to_string(t->identifier) << ") " << t->text << " : " << t->start().line << ", " << t->start().column << '\n'; - for (const auto &node : t->get_children()) { - debug_print(node, prepend + " "); + void debug_print(const AST_Node &t, std::string prepend = "") const override { + std::cout << prepend << "(" << ast_node_type_to_string(t.identifier) << ") " << t.text << " : " << t.start().line << ", " << t.start().column << '\n'; + for (const auto &node : t.get_children()) { + debug_print(node.get(), prepend + " "); } } @@ -452,7 +452,7 @@ namespace chaiscript /// \todo fix the fact that a successful match that captured no ast_nodes doesn't have any real start position m_match_stack.push_back( m_optimizer.optimize( - chaiscript::make_shared, NodeType>( + chaiscript::make_unique, NodeType>( std::move(t_text), std::move(filepos), std::move(new_children))) @@ -779,9 +779,9 @@ namespace chaiscript } template - std::shared_ptr> make_node(std::string t_match, const int t_prev_line, const int t_prev_col, Param && ...param) + std::unique_ptr> make_node(std::string t_match, const int t_prev_line, const int t_prev_col, Param && ...param) { - return chaiscript::make_shared, T>(std::move(t_match), Parse_Location(m_filename, t_prev_line, t_prev_col, m_position.line, m_position.col), std::forward(param)...); + return chaiscript::make_unique, T>(std::move(t_match), Parse_Location(m_filename, t_prev_line, t_prev_col, m_position.line, m_position.col), std::forward(param)...); } /// Reads a number from the input, detecting if it's an integer or floating point @@ -1759,7 +1759,7 @@ namespace chaiscript 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>()); + m_match_stack.push_back(chaiscript::make_unique, eval::Noop_AST_Node>()); } if (!is_if_init) { @@ -1849,7 +1849,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_unique, eval::Noop_AST_Node>()); } } @@ -1859,13 +1859,13 @@ namespace chaiscript { return false; } else { - m_match_stack.push_back(chaiscript::make_shared, eval::Constant_AST_Node>(Boxed_Value(true))); + m_match_stack.push_back(chaiscript::make_unique, eval::Constant_AST_Node>(Boxed_Value(true))); } } if (!Equation()) { - m_match_stack.push_back(chaiscript::make_shared, eval::Noop_AST_Node>()); + m_match_stack.push_back(chaiscript::make_unique, eval::Noop_AST_Node>()); } return true; @@ -2005,7 +2005,7 @@ namespace chaiscript } if (m_match_stack.size() == prev_stack_top) { - m_match_stack.push_back(chaiscript::make_shared, eval::Noop_AST_Node>()); + m_match_stack.push_back(chaiscript::make_unique, eval::Noop_AST_Node>()); } build_match>(prev_stack_top); @@ -2029,7 +2029,7 @@ namespace chaiscript } if (m_match_stack.size() == prev_stack_top) { - m_match_stack.push_back(chaiscript::make_shared, eval::Noop_AST_Node>()); + m_match_stack.push_back(chaiscript::make_unique, eval::Noop_AST_Node>()); } build_match>(prev_stack_top); @@ -2105,13 +2105,13 @@ namespace chaiscript } if (m_match_stack.back()->children.empty()) { throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); } - auto dot_access = m_match_stack.back()->children[0]; - auto func_call = m_match_stack.back(); + auto dot_access = std::move(m_match_stack.back()->children[0]); + auto func_call = std::move(m_match_stack.back()); m_match_stack.pop_back(); func_call->children.erase(func_call->children.begin()); if (dot_access->children.empty()) { throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); } - func_call->children.insert(func_call->children.begin(), dot_access->children.back()); + func_call->children.insert(func_call->children.begin(), std::move(dot_access->children.back())); dot_access->children.pop_back(); dot_access->children.push_back(std::move(func_call)); if (dot_access->children.size() != 2) { throw exception::eval_error("Incomplete dot access fun call", File_Position(m_position.line, m_position.col), *m_filename); @@ -2517,24 +2517,23 @@ namespace chaiscript AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) override { - ChaiScript_Parser parser(*this); - parser.m_match_stack.clear(); + ChaiScript_Parser parser(m_tracer, m_optimizer); return parser.parse_internal(t_input, t_fname); } eval::AST_Node_Impl_Ptr parse_instr_eval(const std::string &t_input) { - const auto last_position = m_position; - const auto last_filename = m_filename; - const auto last_match_stack = std::exchange(m_match_stack, decltype(m_match_stack){}); + auto last_position = m_position; + auto last_filename = m_filename; + auto last_match_stack = std::exchange(m_match_stack, decltype(m_match_stack){}); - const auto retval = parse_internal(t_input, "instr eval"); + auto retval = parse_internal(t_input, "instr eval"); m_position = std::move(last_position); m_filename = std::move(last_filename); m_match_stack = std::move(last_match_stack); - return std::dynamic_pointer_cast>(retval); + return eval::AST_Node_Impl_Ptr(dynamic_cast*>(retval.release())); } /// Parses the given input string, tagging parsed ast_nodes with the given m_filename. @@ -2546,7 +2545,6 @@ namespace chaiscript while (m_position.has_more() && (!Eol())) { ++m_position; } - /// \todo respect // -*- coding: utf-8 -*- on line 1 or 2 see: http://evanjones.ca/python-utf8.html) } if (Statements(true)) { @@ -2556,10 +2554,12 @@ namespace chaiscript build_match>(0); } } else { - m_match_stack.push_back(chaiscript::make_shared, eval::Noop_AST_Node>()); + m_match_stack.push_back(chaiscript::make_unique, eval::Noop_AST_Node>()); } - return m_match_stack.front(); + AST_NodePtr retval(std::move(m_match_stack.front())); + m_match_stack.clear(); + return retval; } }; } diff --git a/src/main.cpp b/src/main.cpp index 78044e06..e826def0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -247,7 +247,7 @@ void interactive(chaiscript::ChaiScript_Basic& chai) catch (const chaiscript::exception::eval_error &ee) { std::cout << ee.what(); if ( !ee.call_stack.empty() ) { - std::cout << "during evaluation at (" << ee.call_stack[0]->start().line << ", " << ee.call_stack[0]->start().column << ")"; + std::cout << "during evaluation at (" << ee.call_stack[0].start().line << ", " << ee.call_stack[0].start().column << ")"; } std::cout << '\n'; }