From 89e5f5f00420c22db5abe0b88dcf5225444283f7 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Tue, 30 Mar 2021 20:55:50 +0200 Subject: [PATCH] move everything to alias_stack and remove stacked_value --- include/cubescript/cubescript.hh | 26 --- src/cs_val.cc | 62 ------- src/lib_list.cc | 266 +++++++++++++++---------------- 3 files changed, 125 insertions(+), 229 deletions(-) diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 56afcf0..2afe633 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -837,32 +837,6 @@ private: alias *p_alias; }; -struct LIBCUBESCRIPT_EXPORT stacked_value: any_value { - stacked_value(state &cs, ident *id = nullptr); - ~stacked_value(); - - stacked_value(stacked_value const &) = delete; - stacked_value(stacked_value &&) = delete; - - stacked_value &operator=(stacked_value const &) = delete; - stacked_value &operator=(stacked_value &&v) = delete; - - stacked_value &operator=(any_value const &v); - stacked_value &operator=(any_value &&v); - - bool set_alias(ident *id); - alias *get_alias() const; - bool has_alias() const; - - bool push(); - bool pop(); - -private: - state &p_state; - alias *p_a; - bool p_pushed; -}; - struct LIBCUBESCRIPT_EXPORT list_parser { list_parser(state &cs, std::string_view s = std::string_view{}): p_state{&cs}, p_input_beg{s.data()}, p_input_end{s.data() + s.size()} diff --git a/src/cs_val.cc b/src/cs_val.cc index b7aab40..9b31fe9 100644 --- a/src/cs_val.cc +++ b/src/cs_val.cc @@ -408,68 +408,6 @@ bool any_value::get_bool() const { } } -/* stacked value for easy stack management */ - -stacked_value::stacked_value(state &cs, ident *id): - any_value{cs}, p_state{cs}, p_a{nullptr}, p_pushed{false} -{ - set_alias(id); -} - -stacked_value::~stacked_value() { - pop(); - static_cast(this)->~any_value(); -} - -stacked_value &stacked_value::operator=(any_value const &v) { - *static_cast(this) = v; - return *this; -} - -stacked_value &stacked_value::operator=(any_value &&v) { - *static_cast(this) = std::move(v); - return *this; -} - -bool stacked_value::set_alias(ident *id) { - if (!id || !id->is_alias()) { - return false; - } - p_a = static_cast(id); - return true; -} - -alias *stacked_value::get_alias() const { - return p_a; -} - -bool stacked_value::has_alias() const { - return p_a != nullptr; -} - -bool stacked_value::push() { - if (!p_a) { - return false; - } - auto &ts = *p_state.thread_pointer(); - auto &ap = *static_cast(p_a); - if (!p_pushed) { - ap.push_arg(ts.idstack.emplace_back(p_state)); - p_pushed = true; - } - ap.p_val = std::move(*static_cast(this)); - return true; -} - -bool stacked_value::pop() { - if (!p_pushed || !p_a) { - return false; - } - static_cast(p_a)->pop_arg(); - p_pushed = false; - return true; -} - /* public utilities */ LIBCUBESCRIPT_EXPORT string_ref concat_values( diff --git a/src/lib_list.cc b/src/lib_list.cc index f20234f..947eacb 100644 --- a/src/lib_list.cc +++ b/src/lib_list.cc @@ -76,31 +76,30 @@ static void loop_list_conc( state &cs, any_value &res, ident *id, std::string_view list, bcode *body, bool space ) { - stacked_value idv{cs, id}; - if (!idv.has_alias()) { - return; - } - charbuf r{cs}; - int n = 0; - for (list_parser p{cs, list}; p.parse(); ++n) { - idv.set_str(p.get_item()); - idv.push(); - if (n && space) { - r.push_back(' '); + if (alias_stack st{cs, id}; st) { + any_value idv{cs}; + charbuf r{cs}; + int n = 0; + for (list_parser p{cs, list}; p.parse(); ++n) { + idv.set_str(p.get_item()); + st.set(std::move(idv)); + if (n && space) { + r.push_back(' '); + } + any_value v{cs}; + switch (cs.run_loop(body, v)) { + case loop_state::BREAK: + goto end; + case loop_state::CONTINUE: + continue; + default: + break; + } + r.append(v.get_str()); } - any_value v{cs}; - switch (cs.run_loop(body, v)) { - case loop_state::BREAK: - goto end; - case loop_state::CONTINUE: - continue; - default: - break; - } - r.append(v.get_str()); - } end: - res.set_str(r.str()); + res.set_str(r.str()); + } } int list_includes( @@ -205,44 +204,41 @@ void init_lib_list(state &gcs) { }); gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) { - stacked_value idv{cs, args[0].get_ident()}; - if (!idv.has_alias()) { - res.set_int(-1); - return; - } - auto body = args[2].get_code(); - int n = -1; - for (list_parser p{cs, args[1].get_str()}; p.parse();) { - ++n; - idv.set_str(p.get_raw_item()); - idv.push(); - if (cs.run(body).get_bool()) { - res.set_int(integer_type(n)); - return; + if (alias_stack st{cs, args[0].get_ident()}; st) { + any_value idv{cs}; + auto body = args[2].get_code(); + int n = -1; + for (list_parser p{cs, args[1].get_str()}; p.parse();) { + ++n; + idv.set_str(p.get_raw_item()); + st.set(std::move(idv)); + if (cs.run(body).get_bool()) { + res.set_int(integer_type(n)); + return; + } } } res.set_int(-1); }); gcs.new_command("listassoc", "rse", [](auto &cs, auto args, auto &res) { - stacked_value idv{cs, args[0].get_ident()}; - if (!idv.has_alias()) { - return; - } - auto body = args[2].get_code(); - int n = -1; - for (list_parser p{cs, args[1].get_str()}; p.parse();) { - ++n; - idv.set_str(p.get_raw_item()); - idv.push(); - if (cs.run(body).get_bool()) { - if (p.parse()) { - res.set_str(p.get_item()); + if (alias_stack st{cs, args[0].get_ident()}; st) { + any_value idv{cs}; + auto body = args[2].get_code(); + int n = -1; + for (list_parser p{cs, args[1].get_str()}; p.parse();) { + ++n; + idv.set_str(p.get_raw_item()); + st.set(std::move(idv)); + if (cs.run(body).get_bool()) { + if (p.parse()) { + res.set_str(p.get_item()); + } + break; + } + if (!p.parse()) { + break; } - break; - } - if (!p.parse()) { - break; } } }); @@ -292,87 +288,82 @@ void init_lib_list(state &gcs) { }); gcs.new_command("looplist", "rse", [](auto &cs, auto args, auto &) { - stacked_value idv{cs, args[0].get_ident()}; - if (!idv.has_alias()) { - return; - } - auto body = args[2].get_code(); - int n = 0; - for (list_parser p{cs, args[1].get_str()}; p.parse(); ++n) { - idv.set_str(p.get_item()); - idv.push(); - switch (cs.run_loop(body)) { - case loop_state::BREAK: - goto end; - default: /* continue and normal */ - break; + if (alias_stack st{cs, args[0].get_ident()}; st) { + any_value idv{cs}; + auto body = args[2].get_code(); + int n = 0; + for (list_parser p{cs, args[1].get_str()}; p.parse(); ++n) { + idv.set_str(p.get_item()); + st.set(std::move(idv)); + switch (cs.run_loop(body)) { + case loop_state::BREAK: + return; + default: /* continue and normal */ + break; + } } } -end: - return; }); gcs.new_command("looplist2", "rrse", [](auto &cs, auto args, auto &) { - stacked_value idv1{cs, args[0].get_ident()}; - stacked_value idv2{cs, args[1].get_ident()}; - if (!idv1.has_alias() || !idv2.has_alias()) { + alias_stack st1{cs, args[0].get_ident()}; + alias_stack st2{cs, args[1].get_ident()}; + if (!st1 || !st2) { return; } + any_value idv{cs}; auto body = args[3].get_code(); int n = 0; for (list_parser p{cs, args[2].get_str()}; p.parse(); n += 2) { - idv1.set_str(p.get_item()); + idv.set_str(p.get_item()); + st1.set(std::move(idv)); if (p.parse()) { - idv2.set_str(p.get_item()); + idv.set_str(p.get_item()); } else { - idv2.set_str(""); + idv.set_str(""); } - idv1.push(); - idv2.push(); + st2.set(std::move(idv)); switch (cs.run_loop(body)) { case loop_state::BREAK: - goto end; + return; default: /* continue and normal */ break; } } -end: - return; }); gcs.new_command("looplist3", "rrrse", [](auto &cs, auto args, auto &) { - stacked_value idv1{cs, args[0].get_ident()}; - stacked_value idv2{cs, args[1].get_ident()}; - stacked_value idv3{cs, args[2].get_ident()}; - if (!idv1.has_alias() || !idv2.has_alias() || !idv3.has_alias()) { + alias_stack st1{cs, args[0].get_ident()}; + alias_stack st2{cs, args[1].get_ident()}; + alias_stack st3{cs, args[2].get_ident()}; + if (!st1 || !st2 || !st3) { return; } + any_value idv{cs}; auto body = args[4].get_code(); int n = 0; for (list_parser p{cs, args[3].get_str()}; p.parse(); n += 3) { - idv1.set_str(p.get_item()); + idv.set_str(p.get_item()); + st1.set(std::move(idv)); if (p.parse()) { - idv2.set_str(p.get_item()); + idv.set_str(p.get_item()); } else { - idv2.set_str(""); + idv.set_str(""); } + st2.set(std::move(idv)); if (p.parse()) { - idv3.set_str(p.get_item()); + idv.set_str(p.get_item()); } else { - idv3.set_str(""); + idv.set_str(""); } - idv1.push(); - idv2.push(); - idv3.push(); + st3.set(std::move(idv)); switch (cs.run_loop(body)) { case loop_state::BREAK: - goto end; + return; default: /* continue and normal */ break; } } -end: - return; }); gcs.new_command("looplistconcat", "rse", [](auto &cs, auto args, auto &res) { @@ -392,41 +383,39 @@ end: }); gcs.new_command("listfilter", "rse", [](auto &cs, auto args, auto &res) { - stacked_value idv{cs, args[0].get_ident()}; - if (!idv.has_alias()) { - return; - } - auto body = args[2].get_code(); - charbuf r{cs}; - int n = 0; - for (list_parser p{cs, args[1].get_str()}; p.parse(); ++n) { - idv.set_str(p.get_raw_item()); - idv.push(); - if (cs.run(body).get_bool()) { - if (r.size()) { - r.push_back(' '); + if (alias_stack st{cs, args[0].get_ident()}; st) { + any_value idv{cs}; + auto body = args[2].get_code(); + charbuf r{cs}; + int n = 0; + for (list_parser p{cs, args[1].get_str()}; p.parse(); ++n) { + idv.set_str(p.get_raw_item()); + st.set(std::move(idv)); + if (cs.run(body).get_bool()) { + if (r.size()) { + r.push_back(' '); + } + r.append(p.get_quoted_item()); } - r.append(p.get_quoted_item()); } + res.set_str(r.str()); } - res.set_str(r.str()); }); gcs.new_command("listcount", "rse", [](auto &cs, auto args, auto &res) { - stacked_value idv{cs, args[0].get_ident()}; - if (!idv.has_alias()) { - return; - } - auto body = args[2].get_code(); - int n = 0, r = 0; - for (list_parser p{cs, args[1].get_str()}; p.parse(); ++n) { - idv.set_str(p.get_raw_item()); - idv.push(); - if (cs.run(body).get_bool()) { - r++; + if (alias_stack st{cs, args[0].get_ident()}; st) { + any_value idv{cs}; + auto body = args[2].get_code(); + int n = 0, r = 0; + for (list_parser p{cs, args[1].get_str()}; p.parse(); ++n) { + idv.set_str(p.get_raw_item()); + st.set(std::move(idv)); + if (cs.run(body).get_bool()) { + r++; + } } + res.set_int(r); } - res.set_int(r); }); gcs.new_command("prettylist", "ss", [](auto &cs, auto args, auto &res) { @@ -529,14 +518,15 @@ struct ListSortItem { struct ListSortFun { state &cs; - stacked_value &xv, &yv; + alias_stack &xst, &yst; bcode *body; bool operator()(ListSortItem const &xval, ListSortItem const &yval) { - xv.set_str(xval.str); - yv.set_str(yval.str); - xv.push(); - yv.push(); + any_value v{cs}; + v.set_str(xval.str); + xst.set(std::move(v)); + v.set_str(yval.str); + yst.set(std::move(v)); return cs.run(body).get_bool(); } }; @@ -545,11 +535,14 @@ static void list_sort( state &cs, any_value &res, std::string_view list, ident *x, ident *y, bcode *body, bcode *unique ) { - if (x == y || !x->is_alias() || !y->is_alias()) { + if (x == y) { return; } - alias *xa = static_cast(x), *ya = static_cast(y); + alias_stack xst{cs, x}, yst{cs, y}; + if (!xst || !yst) { + return; + } valbuf items{cs.thread_pointer()->istate}; size_t total = 0; @@ -565,16 +558,10 @@ static void list_sort( return; } - stacked_value xval{cs, xa}, yval{cs, ya}; - xval.set_none(); - yval.set_none(); - xval.push(); - yval.push(); - size_t totaluniq = total; size_t nuniq = items.size(); if (body) { - ListSortFun f = { cs, xval, yval, body }; + ListSortFun f = { cs, xst, yst, body }; std::sort(items.buf.begin(), items.buf.end(), f); if (!code_is_empty(unique)) { f.body = unique; @@ -591,7 +578,7 @@ static void list_sort( } } } else { - ListSortFun f = { cs, xval, yval, unique }; + ListSortFun f = { cs, xst, yst, unique }; totaluniq = items[0].quote.size(); nuniq = 1; for (size_t i = 1; i < items.size(); i++) { @@ -610,9 +597,6 @@ static void list_sort( } } - xval.pop(); - yval.pop(); - charbuf sorted{cs}; sorted.reserve(totaluniq + std::max(nuniq - 1, size_t(0))); for (size_t i = 0; i < items.size(); ++i) {