use CsStackedValue appropriately

master
Daniel Kolesa 2016-08-31 18:49:24 +01:00
parent 57620a7bd2
commit 2a71bd3409
4 changed files with 83 additions and 155 deletions

View File

@ -50,7 +50,7 @@ ostd::ConstCharRange cs_debug_line(
ostd::format(r, "%d: %s", num, fmt); ostd::format(r, "%d: %s", num, fmt);
} }
r.put('\0'); r.put('\0');
return buf; return buf.data(); /* trigger strlen */
} }
if (end.empty()) { if (end.empty()) {
break; break;

View File

@ -293,7 +293,7 @@ void CsState::clear_override(CsIdent &id) {
CsAlias &a = static_cast<CsAlias &>(id); CsAlias &a = static_cast<CsAlias &>(id);
a.cleanup_value(); a.cleanup_value();
a.clean_code(); a.clean_code();
a.set_value_str(""); a.val_v.set_str("");
break; break;
} }
case CsIdentType::ivar: { case CsIdentType::ivar: {
@ -559,7 +559,7 @@ void CsValue::set_macro(ostd::ConstCharRange val) {
void CsValue::set(CsValue &tv) { void CsValue::set(CsValue &tv) {
*this = tv; *this = tv;
tv.p_type = CsValueType::null; tv.set_null();
} }
@ -1261,43 +1261,36 @@ void cs_init_lib_io(CsState &cs) {
}); });
} }
static inline void cs_set_iter(CsAlias &a, CsInt i, CsIdentStack &stack) {
CsValue v;
v.set_int(i);
a.push_arg(v, stack);
}
static inline void cs_do_loop( static inline void cs_do_loop(
CsState &cs, CsIdent &id, CsInt offset, CsInt n, CsInt step, CsState &cs, CsIdent &id, CsInt offset, CsInt n, CsInt step,
CsBytecode *cond, CsBytecode *body CsBytecode *cond, CsBytecode *body
) { ) {
if (n <= 0 || !id.is_alias()) { CsStackedValue idv{&id};
if (n <= 0 || !idv.has_alias()) {
return; return;
} }
CsAlias &a = static_cast<CsAlias &>(id);
CsIdentStack stack;
for (CsInt i = 0; i < n; ++i) { for (CsInt i = 0; i < n; ++i) {
cs_set_iter(a, offset + i * step, stack); idv.set_int(offset + i * step);
idv.push();
if (cond && !cs.run_bool(cond)) { if (cond && !cs.run_bool(cond)) {
break; break;
} }
cs.run_int(body); cs.run_int(body);
} }
a.pop_arg();
} }
static inline void cs_loop_conc( static inline void cs_loop_conc(
CsState &cs, CsValue &res, CsIdent &id, CsInt offset, CsInt n, CsState &cs, CsValue &res, CsIdent &id, CsInt offset, CsInt n,
CsInt step, CsBytecode *body, bool space CsInt step, CsBytecode *body, bool space
) { ) {
if (n <= 0 || !id.is_alias()) { CsStackedValue idv{&id};
if (n <= 0 || !idv.has_alias()) {
return; return;
} }
CsAlias &a = static_cast<CsAlias &>(id);
CsIdentStack stack;
CsVector<char> s; CsVector<char> s;
for (CsInt i = 0; i < n; ++i) { for (CsInt i = 0; i < n; ++i) {
cs_set_iter(a, offset + i * step, stack); idv.set_int(offset + i * step);
idv.push();
CsValue v; CsValue v;
cs.run_ret(body, v); cs.run_ret(body, v);
CsString vstr = ostd::move(v.get_str()); CsString vstr = ostd::move(v.get_str());
@ -1307,9 +1300,6 @@ static inline void cs_loop_conc(
s.push_n(vstr.data(), vstr.size()); s.push_n(vstr.data(), vstr.size());
v.cleanup(); v.cleanup();
} }
if (n > 0) {
a.pop_arg();
}
s.push('\0'); s.push('\0');
ostd::Size len = s.size() - 1; ostd::Size len = s.size() - 1;
res.set_mstr(ostd::CharRange(s.disown(), len)); res.set_mstr(ostd::CharRange(s.disown(), len));
@ -1442,19 +1432,14 @@ void cs_init_lib_base(CsState &cs) {
}); });
cs_add_command(cs, "pushif", "rTe", [&cs](CsValueRange args, CsValue &res) { cs_add_command(cs, "pushif", "rTe", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
CsValue &v = args[1]; if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
CsBytecode *code = args[2].get_code();
if (!id->is_alias() || (id->get_index() < MaxArguments)) {
return; return;
} }
CsAlias *a = static_cast<CsAlias *>(id); if (args[1].get_bool()) {
if (v.get_bool()) { idv.set(args[1]);
CsIdentStack stack; idv.push();
a->push_arg(v, stack); cs.run_ret(args[2].get_code(), res);
v.set_null();
cs.run_ret(code, res);
a->pop_arg();
} }
}); });
@ -1584,17 +1569,13 @@ void cs_init_lib_base(CsState &cs) {
}); });
cs_add_command(cs, "push", "rTe", [&cs](CsValueRange args, CsValue &res) { cs_add_command(cs, "push", "rTe", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
if (!id->is_alias() || (id->get_index() < MaxArguments)) { if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return; return;
} }
CsAlias *a = static_cast<CsAlias *>(id); idv.set(args[1]);
CsIdentStack stack; idv.push();
CsValue &v = args[1];
a->push_arg(v, stack);
v.set_null();
cs.run_ret(args[2].get_code(), res); cs.run_ret(args[2].get_code(), res);
a->pop_arg();
}); });
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL); cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);

View File

@ -273,18 +273,6 @@ struct OSTD_EXPORT CsAlias: CsIdent {
val_v = v.val_s; val_v = v.val_s;
} }
void set_value_cstr(ostd::ConstCharRange val) {
val_v.set_cstr(val);
}
void set_value_mstr(ostd::CharRange val) {
val_v.set_mstr(val);
}
void set_value_str(CsString val) {
val_v.set_str(ostd::move(val));
}
void cleanup_value() { void cleanup_value() {
val_v.cleanup(); val_v.cleanup();
} }

View File

@ -68,25 +68,20 @@ static inline void cs_list_assoc(CsValueRange args, CsValue &res, F cmp) {
} }
} }
static inline void cs_set_iter(CsAlias &a, char *val, CsIdentStack &stack) {
CsValue v;
v.set_mstr(val);
a.push_arg(v, stack);
}
static void cs_loop_list_conc( static void cs_loop_list_conc(
CsState &cs, CsValue &res, CsIdent *id, ostd::ConstCharRange list, CsState &cs, CsValue &res, CsIdent *id, ostd::ConstCharRange list,
CsBytecode *body, bool space CsBytecode *body, bool space
) { ) {
if (!id->is_alias()) { CsStackedValue idv{id};
if (!idv.has_alias()) {
return; return;
} }
CsIdentStack stack;
CsVector<char> r; CsVector<char> r;
int n = 0; int n = 0;
for (util::ListParser p(list); p.parse(); ++n) { for (util::ListParser p(list); p.parse(); ++n) {
char *val = p.element().disown(); char *val = p.element().disown();
cs_set_iter(*static_cast<CsAlias *>(id), val, stack); idv.set_mstr(val);
idv.push();
if (n && space) { if (n && space) {
r.push(' '); r.push(' ');
} }
@ -96,9 +91,6 @@ static void cs_loop_list_conc(
r.push_n(vstr.data(), vstr.size()); r.push_n(vstr.data(), vstr.size());
v.cleanup(); v.cleanup();
} }
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
r.push('\0'); r.push('\0');
ostd::Size len = r.size(); ostd::Size len = r.size();
res.set_mstr(ostd::CharRange(r.disown(), len - 1)); res.set_mstr(ostd::CharRange(r.disown(), len - 1));
@ -201,40 +193,36 @@ void cs_init_lib_list(CsState &cs) {
}); });
cs.add_command("listfind", "rse", [&cs](CsValueRange args, CsValue &res) { cs.add_command("listfind", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
auto body = args[2].get_code(); if (!idv.has_alias()) {
if (!id->is_alias()) {
res.set_int(-1); res.set_int(-1);
return; return;
} }
CsIdentStack stack; auto body = args[2].get_code();
int n = -1; int n = -1;
for (util::ListParser p(args[1].get_strr()); p.parse();) { for (util::ListParser p(args[1].get_strr()); p.parse();) {
++n; ++n;
cs_set_iter(*static_cast<CsAlias *>(id), cs_dup_ostr(p.item), stack); idv.set_mstr(cs_dup_ostr(p.item));
idv.push();
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
res.set_int(CsInt(n)); res.set_int(CsInt(n));
goto found; return;
} }
} }
res.set_int(-1); res.set_int(-1);
found:
if (n >= 0) {
static_cast<CsAlias *>(id)->pop_arg();
}
}); });
cs.add_command("listassoc", "rse", [&cs](CsValueRange args, CsValue &res) { cs.add_command("listassoc", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
auto body = args[2].get_code(); if (!idv.has_alias()) {
if (!id->is_alias()) {
return; return;
} }
CsIdentStack stack; auto body = args[2].get_code();
int n = -1; int n = -1;
for (util::ListParser p(args[1].get_strr()); p.parse();) { for (util::ListParser p(args[1].get_strr()); p.parse();) {
++n; ++n;
cs_set_iter(*static_cast<CsAlias *>(id), cs_dup_ostr(p.item), stack); idv.set_mstr(cs_dup_ostr(p.item));
idv.push();
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
if (p.parse()) { if (p.parse()) {
auto elem = p.element(); auto elem = p.element();
@ -248,9 +236,6 @@ found:
break; break;
} }
} }
if (n >= 0) {
static_cast<CsAlias *>(id)->pop_arg();
}
}); });
cs.add_command("listfind=", "i", [](CsValueRange args, CsValue &res) { cs.add_command("listfind=", "i", [](CsValueRange args, CsValue &res) {
@ -298,71 +283,53 @@ found:
}); });
cs.add_command("looplist", "rse", [&cs](CsValueRange args, CsValue &) { cs.add_command("looplist", "rse", [&cs](CsValueRange args, CsValue &) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
auto body = args[2].get_code(); if (!idv.has_alias()) {
if (!id->is_alias()) {
return; return;
} }
CsIdentStack stack; auto body = args[2].get_code();
int n = 0; int n = 0;
for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) { for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) {
cs_set_iter(*static_cast<CsAlias *>(id), p.element().disown(), stack); idv.set_mstr(p.element().disown());
idv.push();
cs.run_int(body); cs.run_int(body);
} }
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
}); });
cs.add_command("looplist2", "rrse", [&cs](CsValueRange args, CsValue &) { cs.add_command("looplist2", "rrse", [&cs](CsValueRange args, CsValue &) {
CsIdent *id = args[0].get_ident(), *id2 = args[1].get_ident(); CsStackedValue idv1{args[0].get_ident()}, idv2{args[1].get_ident()};
auto body = args[3].get_code(); if (!idv1.has_alias() || !idv2.has_alias()) {
if (!id->is_alias() || !id2->is_alias()) {
return; return;
} }
CsIdentStack stack, stack2; auto body = args[3].get_code();
int n = 0; int n = 0;
for (util::ListParser p(args[2].get_strr()); p.parse(); n += 2) { for (util::ListParser p(args[2].get_strr()); p.parse(); n += 2) {
cs_set_iter(*static_cast<CsAlias *>(id), p.element().disown(), stack); idv1.set_mstr(p.element().disown());
cs_set_iter( idv2.set_mstr(p.parse() ? p.element().disown() : cs_dup_ostr(""));
*static_cast<CsAlias *>(id2), idv1.push();
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2 idv2.push();
);
cs.run_int(body); cs.run_int(body);
} }
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
static_cast<CsAlias *>(id2)->pop_arg();
}
}); });
cs.add_command("looplist3", "rrrse", [&cs](CsValueRange args, CsValue &) { cs.add_command("looplist3", "rrrse", [&cs](CsValueRange args, CsValue &) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv1{args[0].get_ident()};
CsIdent *id2 = args[1].get_ident(); CsStackedValue idv2{args[1].get_ident()};
CsIdent *id3 = args[2].get_ident(); CsStackedValue idv3{args[2].get_ident()};
auto body = args[4].get_code(); if (!idv1.has_alias() || !idv2.has_alias() || !idv3.has_alias()) {
if (!id->is_alias() || !id2->is_alias() || !id3->is_alias()) {
return; return;
} }
CsIdentStack stack, stack2, stack3; auto body = args[4].get_code();
int n = 0; int n = 0;
for (util::ListParser p(args[3].get_strr()); p.parse(); n += 3) { for (util::ListParser p(args[3].get_strr()); p.parse(); n += 3) {
cs_set_iter(*static_cast<CsAlias *>(id), p.element().disown(), stack); idv1.set_mstr(p.element().disown());
cs_set_iter( idv2.set_mstr(p.parse() ? p.element().disown() : cs_dup_ostr(""));
*static_cast<CsAlias *>(id2), idv3.set_mstr(p.parse() ? p.element().disown() : cs_dup_ostr(""));
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2 idv1.push();
); idv2.push();
cs_set_iter( idv3.push();
*static_cast<CsAlias *>(id3),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack3
);
cs.run_int(body); cs.run_int(body);
} }
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
static_cast<CsAlias *>(id2)->pop_arg();
static_cast<CsAlias *>(id3)->pop_arg();
}
}); });
cs.add_command("looplistconcat", "rse", [&cs]( cs.add_command("looplistconcat", "rse", [&cs](
@ -384,17 +351,17 @@ found:
}); });
cs.add_command("listfilter", "rse", [&cs](CsValueRange args, CsValue &res) { cs.add_command("listfilter", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
auto body = args[2].get_code(); if (!idv.has_alias()) {
if (!id->is_alias()) {
return; return;
} }
CsIdentStack stack; auto body = args[2].get_code();
CsVector<char> r; CsVector<char> r;
int n = 0; int n = 0;
for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) { for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) {
char *val = cs_dup_ostr(p.item); char *val = cs_dup_ostr(p.item);
cs_set_iter(*static_cast<CsAlias *>(id), val, stack); idv.set_mstr(val);
idv.push();
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
if (r.size()) { if (r.size()) {
r.push(' '); r.push(' ');
@ -402,32 +369,26 @@ found:
r.push_n(p.quote.data(), p.quote.size()); r.push_n(p.quote.data(), p.quote.size());
} }
} }
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
r.push('\0'); r.push('\0');
ostd::Size len = r.size() - 1; ostd::Size len = r.size() - 1;
res.set_mstr(ostd::CharRange(r.disown(), len)); res.set_mstr(ostd::CharRange(r.disown(), len));
}); });
cs.add_command("listcount", "rse", [&cs](CsValueRange args, CsValue &res) { cs.add_command("listcount", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident(); CsStackedValue idv{args[0].get_ident()};
auto body = args[2].get_code(); if (!idv.has_alias()) {
if (!id->is_alias()) {
return; return;
} }
CsIdentStack stack; auto body = args[2].get_code();
int n = 0, r = 0; int n = 0, r = 0;
for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) { for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) {
char *val = cs_dup_ostr(p.item); char *val = cs_dup_ostr(p.item);
cs_set_iter(*static_cast<CsAlias *>(id), val, stack); idv.set_mstr(val);
idv.push();
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
r++; r++;
} }
} }
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
res.set_int(r); res.set_int(r);
}); });
@ -538,14 +499,14 @@ struct ListSortItem {
struct ListSortFun { struct ListSortFun {
CsState &cs; CsState &cs;
CsAlias *x, *y; CsStackedValue &xv, &yv;
CsBytecode *body; CsBytecode *body;
bool operator()(ListSortItem const &xval, ListSortItem const &yval) { bool operator()(ListSortItem const &xval, ListSortItem const &yval) {
x->clean_code(); xv.set_cstr(xval.str);
x->set_value_cstr(xval.str); yv.set_cstr(yval.str);
y->clean_code(); xv.push();
y->set_value_cstr(yval.str); yv.push();
return cs.run_bool(body); return cs.run_bool(body);
} }
}; };
@ -577,18 +538,16 @@ static void cs_list_sort(
return; return;
} }
/* default null value, set later from callback */ CsStackedValue xval{xa}, yval{ya};
CsValue nv; xval.set_null();
nv.set_null(); yval.set_null();
xval.push();
CsIdentStack xstack, ystack; yval.push();
xa->push_arg(nv, xstack);
ya->push_arg(nv, ystack);
ostd::Size totaluniq = total; ostd::Size totaluniq = total;
ostd::Size nuniq = items.size(); ostd::Size nuniq = items.size();
if (body) { if (body) {
ListSortFun f = { cs, xa, ya, body }; ListSortFun f = { cs, xval, yval, body };
ostd::sort_cmp(items.iter(), f); ostd::sort_cmp(items.iter(), f);
if (!cs_code_is_empty(unique)) { if (!cs_code_is_empty(unique)) {
f.body = unique; f.body = unique;
@ -605,7 +564,7 @@ static void cs_list_sort(
} }
} }
} else { } else {
ListSortFun f = { cs, xa, ya, unique }; ListSortFun f = { cs, xval, yval, unique };
totaluniq = items[0].quote.size(); totaluniq = items[0].quote.size();
nuniq = 1; nuniq = 1;
for (ostd::Size i = 1; i < items.size(); i++) { for (ostd::Size i = 1; i < items.size(); i++) {
@ -624,8 +583,8 @@ static void cs_list_sort(
} }
} }
xa->pop_arg(); xval.pop();
ya->pop_arg(); yval.pop();
char *sorted = cstr; char *sorted = cstr;
ostd::Size sortedlen = totaluniq + ostd::max(nuniq - 1, ostd::Size(0)); ostd::Size sortedlen = totaluniq + ostd::max(nuniq - 1, ostd::Size(0));