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);
}
r.put('\0');
return buf;
return buf.data(); /* trigger strlen */
}
if (end.empty()) {
break;

View File

@ -293,7 +293,7 @@ void CsState::clear_override(CsIdent &id) {
CsAlias &a = static_cast<CsAlias &>(id);
a.cleanup_value();
a.clean_code();
a.set_value_str("");
a.val_v.set_str("");
break;
}
case CsIdentType::ivar: {
@ -559,7 +559,7 @@ void CsValue::set_macro(ostd::ConstCharRange val) {
void CsValue::set(CsValue &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(
CsState &cs, CsIdent &id, CsInt offset, CsInt n, CsInt step,
CsBytecode *cond, CsBytecode *body
) {
if (n <= 0 || !id.is_alias()) {
CsStackedValue idv{&id};
if (n <= 0 || !idv.has_alias()) {
return;
}
CsAlias &a = static_cast<CsAlias &>(id);
CsIdentStack stack;
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)) {
break;
}
cs.run_int(body);
}
a.pop_arg();
}
static inline void cs_loop_conc(
CsState &cs, CsValue &res, CsIdent &id, CsInt offset, CsInt n,
CsInt step, CsBytecode *body, bool space
) {
if (n <= 0 || !id.is_alias()) {
CsStackedValue idv{&id};
if (n <= 0 || !idv.has_alias()) {
return;
}
CsAlias &a = static_cast<CsAlias &>(id);
CsIdentStack stack;
CsVector<char> s;
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;
cs.run_ret(body, v);
CsString vstr = ostd::move(v.get_str());
@ -1307,9 +1300,6 @@ static inline void cs_loop_conc(
s.push_n(vstr.data(), vstr.size());
v.cleanup();
}
if (n > 0) {
a.pop_arg();
}
s.push('\0');
ostd::Size len = s.size() - 1;
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) {
CsIdent *id = args[0].get_ident();
CsValue &v = args[1];
CsBytecode *code = args[2].get_code();
if (!id->is_alias() || (id->get_index() < MaxArguments)) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return;
}
CsAlias *a = static_cast<CsAlias *>(id);
if (v.get_bool()) {
CsIdentStack stack;
a->push_arg(v, stack);
v.set_null();
cs.run_ret(code, res);
a->pop_arg();
if (args[1].get_bool()) {
idv.set(args[1]);
idv.push();
cs.run_ret(args[2].get_code(), res);
}
});
@ -1584,17 +1569,13 @@ void cs_init_lib_base(CsState &cs) {
});
cs_add_command(cs, "push", "rTe", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident();
if (!id->is_alias() || (id->get_index() < MaxArguments)) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
return;
}
CsAlias *a = static_cast<CsAlias *>(id);
CsIdentStack stack;
CsValue &v = args[1];
a->push_arg(v, stack);
v.set_null();
idv.set(args[1]);
idv.push();
cs.run_ret(args[2].get_code(), res);
a->pop_arg();
});
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;
}
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() {
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(
CsState &cs, CsValue &res, CsIdent *id, ostd::ConstCharRange list,
CsBytecode *body, bool space
) {
if (!id->is_alias()) {
CsStackedValue idv{id};
if (!idv.has_alias()) {
return;
}
CsIdentStack stack;
CsVector<char> r;
int n = 0;
for (util::ListParser p(list); p.parse(); ++n) {
char *val = p.element().disown();
cs_set_iter(*static_cast<CsAlias *>(id), val, stack);
idv.set_mstr(val);
idv.push();
if (n && space) {
r.push(' ');
}
@ -96,9 +91,6 @@ static void cs_loop_list_conc(
r.push_n(vstr.data(), vstr.size());
v.cleanup();
}
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
r.push('\0');
ostd::Size len = r.size();
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) {
CsIdent *id = args[0].get_ident();
auto body = args[2].get_code();
if (!id->is_alias()) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias()) {
res.set_int(-1);
return;
}
CsIdentStack stack;
auto body = args[2].get_code();
int n = -1;
for (util::ListParser p(args[1].get_strr()); p.parse();) {
++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)) {
res.set_int(CsInt(n));
goto found;
return;
}
}
res.set_int(-1);
found:
if (n >= 0) {
static_cast<CsAlias *>(id)->pop_arg();
}
});
cs.add_command("listassoc", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident();
auto body = args[2].get_code();
if (!id->is_alias()) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias()) {
return;
}
CsIdentStack stack;
auto body = args[2].get_code();
int n = -1;
for (util::ListParser p(args[1].get_strr()); p.parse();) {
++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 (p.parse()) {
auto elem = p.element();
@ -248,9 +236,6 @@ found:
break;
}
}
if (n >= 0) {
static_cast<CsAlias *>(id)->pop_arg();
}
});
cs.add_command("listfind=", "i", [](CsValueRange args, CsValue &res) {
@ -298,71 +283,53 @@ found:
});
cs.add_command("looplist", "rse", [&cs](CsValueRange args, CsValue &) {
CsIdent *id = args[0].get_ident();
auto body = args[2].get_code();
if (!id->is_alias()) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias()) {
return;
}
CsIdentStack stack;
auto body = args[2].get_code();
int n = 0;
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);
}
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
});
cs.add_command("looplist2", "rrse", [&cs](CsValueRange args, CsValue &) {
CsIdent *id = args[0].get_ident(), *id2 = args[1].get_ident();
auto body = args[3].get_code();
if (!id->is_alias() || !id2->is_alias()) {
CsStackedValue idv1{args[0].get_ident()}, idv2{args[1].get_ident()};
if (!idv1.has_alias() || !idv2.has_alias()) {
return;
}
CsIdentStack stack, stack2;
auto body = args[3].get_code();
int n = 0;
for (util::ListParser p(args[2].get_strr()); p.parse(); n += 2) {
cs_set_iter(*static_cast<CsAlias *>(id), p.element().disown(), stack);
cs_set_iter(
*static_cast<CsAlias *>(id2),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2
);
idv1.set_mstr(p.element().disown());
idv2.set_mstr(p.parse() ? p.element().disown() : cs_dup_ostr(""));
idv1.push();
idv2.push();
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 &) {
CsIdent *id = args[0].get_ident();
CsIdent *id2 = args[1].get_ident();
CsIdent *id3 = args[2].get_ident();
auto body = args[4].get_code();
if (!id->is_alias() || !id2->is_alias() || !id3->is_alias()) {
CsStackedValue idv1{args[0].get_ident()};
CsStackedValue idv2{args[1].get_ident()};
CsStackedValue idv3{args[2].get_ident()};
if (!idv1.has_alias() || !idv2.has_alias() || !idv3.has_alias()) {
return;
}
CsIdentStack stack, stack2, stack3;
auto body = args[4].get_code();
int n = 0;
for (util::ListParser p(args[3].get_strr()); p.parse(); n += 3) {
cs_set_iter(*static_cast<CsAlias *>(id), p.element().disown(), stack);
cs_set_iter(
*static_cast<CsAlias *>(id2),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2
);
cs_set_iter(
*static_cast<CsAlias *>(id3),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack3
);
idv1.set_mstr(p.element().disown());
idv2.set_mstr(p.parse() ? p.element().disown() : cs_dup_ostr(""));
idv3.set_mstr(p.parse() ? p.element().disown() : cs_dup_ostr(""));
idv1.push();
idv2.push();
idv3.push();
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](
@ -384,17 +351,17 @@ found:
});
cs.add_command("listfilter", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident();
auto body = args[2].get_code();
if (!id->is_alias()) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias()) {
return;
}
CsIdentStack stack;
auto body = args[2].get_code();
CsVector<char> r;
int n = 0;
for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) {
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 (r.size()) {
r.push(' ');
@ -402,32 +369,26 @@ found:
r.push_n(p.quote.data(), p.quote.size());
}
}
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
r.push('\0');
ostd::Size len = r.size() - 1;
res.set_mstr(ostd::CharRange(r.disown(), len));
});
cs.add_command("listcount", "rse", [&cs](CsValueRange args, CsValue &res) {
CsIdent *id = args[0].get_ident();
auto body = args[2].get_code();
if (!id->is_alias()) {
CsStackedValue idv{args[0].get_ident()};
if (!idv.has_alias()) {
return;
}
CsIdentStack stack;
auto body = args[2].get_code();
int n = 0, r = 0;
for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) {
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)) {
r++;
}
}
if (n) {
static_cast<CsAlias *>(id)->pop_arg();
}
res.set_int(r);
});
@ -538,14 +499,14 @@ struct ListSortItem {
struct ListSortFun {
CsState &cs;
CsAlias *x, *y;
CsStackedValue &xv, &yv;
CsBytecode *body;
bool operator()(ListSortItem const &xval, ListSortItem const &yval) {
x->clean_code();
x->set_value_cstr(xval.str);
y->clean_code();
y->set_value_cstr(yval.str);
xv.set_cstr(xval.str);
yv.set_cstr(yval.str);
xv.push();
yv.push();
return cs.run_bool(body);
}
};
@ -577,18 +538,16 @@ static void cs_list_sort(
return;
}
/* default null value, set later from callback */
CsValue nv;
nv.set_null();
CsIdentStack xstack, ystack;
xa->push_arg(nv, xstack);
ya->push_arg(nv, ystack);
CsStackedValue xval{xa}, yval{ya};
xval.set_null();
yval.set_null();
xval.push();
yval.push();
ostd::Size totaluniq = total;
ostd::Size nuniq = items.size();
if (body) {
ListSortFun f = { cs, xa, ya, body };
ListSortFun f = { cs, xval, yval, body };
ostd::sort_cmp(items.iter(), f);
if (!cs_code_is_empty(unique)) {
f.body = unique;
@ -605,7 +564,7 @@ static void cs_list_sort(
}
}
} else {
ListSortFun f = { cs, xa, ya, unique };
ListSortFun f = { cs, xval, yval, unique };
totaluniq = items[0].quote.size();
nuniq = 1;
for (ostd::Size i = 1; i < items.size(); i++) {
@ -624,8 +583,8 @@ static void cs_list_sort(
}
}
xa->pop_arg();
ya->pop_arg();
xval.pop();
yval.pop();
char *sorted = cstr;
ostd::Size sortedlen = totaluniq + ostd::max(nuniq - 1, ostd::Size(0));