move more code around

master
Daniel Kolesa 2016-08-17 23:06:39 +01:00
parent ae00cf2ebb
commit e7ce1d2b1e
5 changed files with 166 additions and 144 deletions

View File

@ -14,6 +14,18 @@ static inline bool cs_has_cmd_cb(Ident *id) {
return !!cb->cb_cftv; return !!cb->cb_cftv;
} }
static inline void cs_push_alias(Ident *id, IdentStack &st) {
if ((id->type == ID_ALIAS) && (id->index >= MaxArguments)) {
static_cast<Alias *>(id)->push_arg(null_value, st);
}
}
static inline void cs_pop_alias(Ident *id) {
if ((id->type == ID_ALIAS) && (id->index >= MaxArguments)) {
static_cast<Alias *>(id)->pop_arg();
}
}
ostd::ConstCharRange cs_debug_line( ostd::ConstCharRange cs_debug_line(
CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt, CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt,
ostd::CharRange buf ostd::CharRange buf
@ -434,37 +446,39 @@ static ostd::Uint32 const *runcode(
); );
static inline void cs_call_alias( static inline void cs_call_alias(
CsState &cs, Ident *id, TaggedValue *args, TaggedValue &result, CsState &cs, Alias *a, TaggedValue *args, TaggedValue &result,
int callargs, int &nargs, int offset, int skip, ostd::Uint32 op int callargs, int &nargs, int offset, int skip, ostd::Uint32 op
) { ) {
IdentStack argstack[MaxArguments]; IdentStack argstack[MaxArguments];
for(int i = 0; i < callargs; i++) { for(int i = 0; i < callargs; i++) {
cs.identmap[i]->push_arg(args[offset + i], argstack[i], false); static_cast<Alias *>(cs.identmap[i])->push_arg(
args[offset + i], argstack[i], false
);
} }
int oldargs = cs.numargs; int oldargs = cs.numargs;
cs.numargs = callargs; cs.numargs = callargs;
int oldflags = cs.identflags; int oldflags = cs.identflags;
cs.identflags |= id->flags&IDF_OVERRIDDEN; cs.identflags |= a->flags&IDF_OVERRIDDEN;
IdentLink aliaslink = { IdentLink aliaslink = {
id, cs.stack, (1<<callargs)-1, argstack a, cs.stack, (1<<callargs)-1, argstack
}; };
cs.stack = &aliaslink; cs.stack = &aliaslink;
if (!id->code) { if (!a->code) {
id->code = reinterpret_cast<Bytecode *>(compilecode(cs, id->get_str())); a->code = reinterpret_cast<Bytecode *>(compilecode(cs, a->get_str()));
} }
ostd::Uint32 *codep = reinterpret_cast<ostd::Uint32 *>(id->code); ostd::Uint32 *codep = reinterpret_cast<ostd::Uint32 *>(a->code);
bcode_incr(codep); bcode_incr(codep);
runcode(cs, codep+1, (result)); runcode(cs, codep+1, (result));
bcode_decr(codep); bcode_decr(codep);
cs.stack = aliaslink.next; cs.stack = aliaslink.next;
cs.identflags = oldflags; cs.identflags = oldflags;
for (int i = 0; i < callargs; i++) { for (int i = 0; i < callargs; i++) {
cs.identmap[i]->pop_arg(); static_cast<Alias *>(cs.identmap[i])->pop_arg();
} }
int argmask = aliaslink.usedargs & (~0 << callargs); int argmask = aliaslink.usedargs & (~0 << callargs);
for (; argmask; ++callargs) { for (; argmask; ++callargs) {
if (argmask & (1 << callargs)) { if (argmask & (1 << callargs)) {
cs.identmap[callargs]->pop_arg(); static_cast<Alias *>(cs.identmap[callargs])->pop_arg();
argmask &= ~(1 << callargs); argmask &= ~(1 << callargs);
} }
} }
@ -662,11 +676,11 @@ static ostd::Uint32 const *runcode(
int numlocals = op >> 8, offset = numargs - numlocals; int numlocals = op >> 8, offset = numargs - numlocals;
IdentStack locals[MaxArguments]; IdentStack locals[MaxArguments];
for (int i = 0; i < numlocals; ++i) { for (int i = 0; i < numlocals; ++i) {
args[offset + i].id->push_alias(locals[i]); cs_push_alias(args[offset + i].id, locals[i]);
} }
code = runcode(cs, code, result); code = runcode(cs, code, result);
for (int i = offset; i < numargs; i++) { for (int i = offset; i < numargs; i++) {
args[i].id->pop_alias(); cs_pop_alias(args[i].id);
} }
goto exit; goto exit;
} }
@ -923,12 +937,12 @@ static ostd::Uint32 const *runcode(
args[numargs++].set_ident(cs.identmap[op >> 8]); args[numargs++].set_ident(cs.identmap[op >> 8]);
continue; continue;
case CODE_IDENTARG: { case CODE_IDENTARG: {
Ident *id = cs.identmap[op >> 8]; Alias *a = static_cast<Alias *>(cs.identmap[op >> 8]);
if (!(cs.stack->usedargs & (1 << id->index))) { if (!(cs.stack->usedargs & (1 << a->index))) {
id->push_arg(null_value, cs.stack->argstack[id->index], false); a->push_arg(null_value, cs.stack->argstack[a->index], false);
cs.stack->usedargs |= 1 << id->index; cs.stack->usedargs |= 1 << a->index;
} }
args[numargs++].set_ident(id); args[numargs++].set_ident(a);
continue; continue;
} }
case CODE_IDENTU: { case CODE_IDENTU: {
@ -942,7 +956,9 @@ static ostd::Uint32 const *runcode(
id = cs.new_ident(ostd::ConstCharRange(arg.cstr, arg.len)); id = cs.new_ident(ostd::ConstCharRange(arg.cstr, arg.len));
} }
if (id->index < MaxArguments && !(cs.stack->usedargs & (1 << id->index))) { if (id->index < MaxArguments && !(cs.stack->usedargs & (1 << id->index))) {
id->push_arg(null_value, cs.stack->argstack[id->index], false); static_cast<Alias *>(id)->push_arg(
null_value, cs.stack->argstack[id->index], false
);
cs.stack->usedargs |= 1 << id->index; cs.stack->usedargs |= 1 << id->index;
} }
arg.cleanup(); arg.cleanup();
@ -1329,10 +1345,14 @@ static ostd::Uint32 const *runcode(
} }
case CODE_ALIAS: case CODE_ALIAS:
cs.identmap[op >> 8]->set_alias(cs, args[--numargs]); static_cast<Alias *>(cs.identmap[op >> 8])->set_alias(
cs, args[--numargs]
);
continue; continue;
case CODE_ALIASARG: case CODE_ALIASARG:
cs.identmap[op >> 8]->set_arg(cs, args[--numargs]); static_cast<Alias *>(cs.identmap[op >> 8])->set_arg(
cs, args[--numargs]
);
continue; continue;
case CODE_ALIASU: case CODE_ALIASU:
numargs -= 2; numargs -= 2;
@ -1354,7 +1374,8 @@ static ostd::Uint32 const *runcode(
continue; continue;
} }
cs_call_alias( cs_call_alias(
cs, id, args, result, callargs, numargs, offset, 0, op cs, static_cast<Alias *>(id), args, result, callargs,
numargs, offset, 0, op
); );
continue; continue;
} }
@ -1371,7 +1392,8 @@ static ostd::Uint32 const *runcode(
continue; continue;
} }
cs_call_alias( cs_call_alias(
cs, id, args, result, callargs, numargs, offset, 0, op cs, static_cast<Alias *>(id), args, result, callargs,
numargs, offset, 0, op
); );
continue; continue;
} }
@ -1430,13 +1452,13 @@ noid:
IdentStack locals[MaxArguments]; IdentStack locals[MaxArguments];
idarg.cleanup(); idarg.cleanup();
for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) { for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) {
cs.force_ident( cs_push_alias(cs.force_ident(
args[offset + j] args[offset + j]
)->push_alias(locals[j]); ), locals[j]);
} }
code = runcode(cs, code, result); code = runcode(cs, code, result);
for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) { for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) {
args[offset + j].id->pop_alias(); cs_pop_alias(args[offset + j].id);
} }
goto exit; goto exit;
} }
@ -1476,24 +1498,26 @@ noid:
free_args(args, numargs, offset - 1); free_args(args, numargs, offset - 1);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
continue; continue;
case ID_ALIAS: case ID_ALIAS: {
Alias *a = static_cast<Alias *>(id);
if ( if (
id->index < MaxArguments && a->index < MaxArguments &&
!(cs.stack->usedargs & (1 << id->index)) !(cs.stack->usedargs & (1 << a->index))
) { ) {
free_args(args, numargs, offset - 1); free_args(args, numargs, offset - 1);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
continue; continue;
} }
if (id->get_valtype() == VAL_NULL) { if (a->get_valtype() == VAL_NULL) {
goto noid; goto noid;
} }
idarg.cleanup(); idarg.cleanup();
cs_call_alias( cs_call_alias(
cs, id, args, result, callargs, numargs, cs, a, args, result, callargs, numargs,
offset, 1, op offset, 1, op
); );
continue; continue;
}
} }
} }
} }
@ -1573,19 +1597,21 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
); );
} }
break; break;
case ID_ALIAS: case ID_ALIAS: {
if (id->index < MaxArguments) { Alias *a = static_cast<Alias *>(id);
if (!(stack->usedargs & (1 << id->index))) { if (a->index < MaxArguments) {
if (!(stack->usedargs & (1 << a->index))) {
break; break;
} }
} }
if (id->get_valtype() == VAL_NULL) { if (a->get_valtype() == VAL_NULL) {
break; break;
} }
cs_call_alias( cs_call_alias(
*this, id, args.data(), ret, nargs, nargs, 0, 0, RET_NULL *this, a, args.data(), ret, nargs, nargs, 0, 0, RET_NULL
); );
break; break;
}
} }
} }
free_args(args.data(), nargs, 0); free_args(args.data(), nargs, 0);

View File

@ -70,7 +70,7 @@ static void cs_do_args(CsState &cs, F body) {
int argmask1 = cs.stack->usedargs; int argmask1 = cs.stack->usedargs;
for (int i = 0; argmask1; argmask1 >>= 1, ++i) { for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
if (argmask1 & 1) { if (argmask1 & 1) {
cs.identmap[i]->undo_arg(argstack[i]); static_cast<Alias *>(cs.identmap[i])->undo_arg(argstack[i]);
} }
} }
IdentLink *prevstack = cs.stack->next; IdentLink *prevstack = cs.stack->next;
@ -84,7 +84,7 @@ static void cs_do_args(CsState &cs, F body) {
int argmask2 = cs.stack->usedargs; int argmask2 = cs.stack->usedargs;
for (int i = 0; argmask2; argmask2 >>= 1, ++i) { for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
if (argmask2 & 1) { if (argmask2 & 1) {
cs.identmap[i]->redo_arg(argstack[i]); static_cast<Alias *>(cs.identmap[i])->redo_arg(argstack[i]);
} }
} }
} }

View File

@ -159,8 +159,9 @@ CsState::~CsState() {
for (auto &p: idents.iter()) { for (auto &p: idents.iter()) {
Ident *i = p.second; Ident *i = p.second;
if (i->type == ID_ALIAS) { if (i->type == ID_ALIAS) {
static_cast<Alias *>(i)->force_null(); Alias *a = static_cast<Alias *>(i);
delete[] reinterpret_cast<ostd::Uint32 *>(i->code); a->force_null();
delete[] reinterpret_cast<ostd::Uint32 *>(a->code);
} else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) { } else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) {
delete[] static_cast<Command *>(i)->cargs; delete[] static_cast<Command *>(i)->cargs;
} }
@ -660,7 +661,7 @@ void Ident::get_cval(TaggedValue &v) const {
} }
} }
void Ident::clean_code() { void Alias::clean_code() {
ostd::Uint32 *bcode = reinterpret_cast<ostd::Uint32 *>(code); ostd::Uint32 *bcode = reinterpret_cast<ostd::Uint32 *>(code);
if (bcode) { if (bcode) {
bcode_decr(bcode); bcode_decr(bcode);
@ -668,7 +669,7 @@ void Ident::clean_code() {
} }
} }
void Ident::push_arg(TaggedValue const &v, IdentStack &st, bool um) { void Alias::push_arg(TaggedValue const &v, IdentStack &st, bool um) {
st.val = val; st.val = val;
st.valtype = valtype; st.valtype = valtype;
st.next = stack; st.next = stack;
@ -680,7 +681,7 @@ void Ident::push_arg(TaggedValue const &v, IdentStack &st, bool um) {
} }
} }
void Ident::pop_arg() { void Alias::pop_arg() {
if (!stack) { if (!stack) {
return; return;
} }
@ -693,7 +694,7 @@ void Ident::pop_arg() {
stack = st->next; stack = st->next;
} }
void Ident::undo_arg(IdentStack &st) { void Alias::undo_arg(IdentStack &st) {
IdentStack *prev = stack; IdentStack *prev = stack;
st.val = val; st.val = val;
st.valtype = valtype; st.valtype = valtype;
@ -703,7 +704,7 @@ void Ident::undo_arg(IdentStack &st) {
clean_code(); clean_code();
} }
void Ident::redo_arg(IdentStack const &st) { void Alias::redo_arg(IdentStack const &st) {
IdentStack *prev = st.next; IdentStack *prev = st.next;
prev->val = val; prev->val = val;
prev->valtype = valtype; prev->valtype = valtype;
@ -712,19 +713,7 @@ void Ident::redo_arg(IdentStack const &st) {
clean_code(); clean_code();
} }
void Ident::push_alias(IdentStack &stack) { void Alias::set_arg(CsState &cs, TaggedValue &v) {
if (type == ID_ALIAS && index >= MaxArguments) {
push_arg(null_value, stack);
}
}
void Ident::pop_alias() {
if (type == ID_ALIAS && index >= MaxArguments) {
pop_arg();
}
}
void Ident::set_arg(CsState &cs, TaggedValue &v) {
if (cs.stack->usedargs & (1 << index)) { if (cs.stack->usedargs & (1 << index)) {
if (get_valtype() == VAL_STR) { if (get_valtype() == VAL_STR) {
delete[] val.s; delete[] val.s;
@ -737,7 +726,7 @@ void Ident::set_arg(CsState &cs, TaggedValue &v) {
} }
} }
void Ident::set_alias(CsState &cs, TaggedValue &v) { void Alias::set_alias(CsState &cs, TaggedValue &v) {
if (get_valtype() == VAL_STR) { if (get_valtype() == VAL_STR) {
delete[] val.s; delete[] val.s;
} }
@ -1106,23 +1095,23 @@ void cs_init_lib_io(CsState &cs) {
}); });
} }
static inline void cs_set_iter(Ident &id, CsInt i, IdentStack &stack) { static inline void cs_set_iter(Alias &a, CsInt i, IdentStack &stack) {
if (id.stack == &stack) { if (a.stack == &stack) {
if (id.get_valtype() != VAL_INT) { if (a.get_valtype() != VAL_INT) {
if (id.get_valtype() == VAL_STR) { if (a.get_valtype() == VAL_STR) {
delete[] id.val.s; delete[] a.val.s;
id.val.s = nullptr; a.val.s = nullptr;
id.val.len = 0; a.val.len = 0;
} }
id.clean_code(); a.clean_code();
id.valtype = VAL_INT; a.valtype = VAL_INT;
} }
id.val.i = i; a.val.i = i;
return; return;
} }
TaggedValue v; TaggedValue v;
v.set_int(i); v.set_int(i);
id.push_arg(v, stack); a.push_arg(v, stack);
} }
static inline void cs_do_loop( static inline void cs_do_loop(
@ -1132,15 +1121,16 @@ static inline void cs_do_loop(
if (n <= 0 || !id.is_alias()) { if (n <= 0 || !id.is_alias()) {
return; return;
} }
Alias &a = static_cast<Alias &>(id);
IdentStack stack; IdentStack stack;
for (CsInt i = 0; i < n; ++i) { for (CsInt i = 0; i < n; ++i) {
cs_set_iter(id, offset + i * step, stack); cs_set_iter(a, offset + i * step, stack);
if (cond && !cs.run_bool(cond)) { if (cond && !cs.run_bool(cond)) {
break; break;
} }
cs.run_int(body); cs.run_int(body);
} }
id.pop_arg(); a.pop_arg();
} }
static inline void cs_loop_conc( static inline void cs_loop_conc(
@ -1150,10 +1140,11 @@ static inline void cs_loop_conc(
if (n <= 0 || !id.is_alias()) { if (n <= 0 || !id.is_alias()) {
return; return;
} }
Alias &a = static_cast<Alias &>(id);
IdentStack stack; IdentStack stack;
ostd::Vector<char> s; ostd::Vector<char> s;
for (CsInt i = 0; i < n; ++i) { for (CsInt i = 0; i < n; ++i) {
cs_set_iter(id, offset + i * step, stack); cs_set_iter(a, offset + i * step, stack);
TaggedValue v; TaggedValue v;
cs.run_ret(body, v); cs.run_ret(body, v);
ostd::String vstr = ostd::move(v.get_str()); ostd::String vstr = ostd::move(v.get_str());
@ -1164,7 +1155,7 @@ static inline void cs_loop_conc(
v.cleanup(); v.cleanup();
} }
if (n > 0) { if (n > 0) {
id.pop_arg(); a.pop_arg();
} }
s.push('\0'); s.push('\0');
ostd::Size len = s.size() - 1; ostd::Size len = s.size() - 1;
@ -1293,12 +1284,13 @@ void cs_init_lib_base(CsState &cs) {
if (!id->is_alias() || (id->index < MaxArguments)) { if (!id->is_alias() || (id->index < MaxArguments)) {
return; return;
} }
Alias *a = static_cast<Alias *>(id);
if (v.get_bool()) { if (v.get_bool()) {
IdentStack stack; IdentStack stack;
id->push_arg(v, stack); a->push_arg(v, stack);
v.set_null(); v.set_null();
cs.run_ret(code, res); cs.run_ret(code, res);
id->pop_arg(); a->pop_arg();
} }
}); });
@ -1432,12 +1424,13 @@ void cs_init_lib_base(CsState &cs) {
if (!id->is_alias() || (id->index < MaxArguments)) { if (!id->is_alias() || (id->index < MaxArguments)) {
return; return;
} }
Alias *a = static_cast<Alias *>(id);
IdentStack stack; IdentStack stack;
TaggedValue &v = args[1]; TaggedValue &v = args[1];
id->push_arg(v, stack); a->push_arg(v, stack);
v.set_null(); v.set_null();
cs.run_ret(args[2].get_code(), res); cs.run_ret(args[2].get_code(), res);
id->pop_arg(); a->pop_arg();
}); });
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL); cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);

View File

@ -172,8 +172,6 @@ union IdentValuePtr {
struct CsState; struct CsState;
using VarCb = ostd::Function<void(Ident &)>;
enum class IdentType { enum class IdentType {
unknown = -1, unknown = -1,
ivar, fvar, svar, command, alias ivar, fvar, svar, command, alias
@ -199,7 +197,6 @@ struct OSTD_EXPORT Ident {
IdentValue overrideval; IdentValue overrideval;
}; };
struct { /* ID_ALIAS */ struct { /* ID_ALIAS */
Bytecode *code;
IdentValue val; IdentValue val;
IdentStack *stack; IdentStack *stack;
}; };
@ -223,19 +220,6 @@ struct OSTD_EXPORT Ident {
void get_cstr(TaggedValue &v) const; void get_cstr(TaggedValue &v) const;
void get_cval(TaggedValue &v) const; void get_cval(TaggedValue &v) const;
void clean_code();
void push_arg(TaggedValue const &v, IdentStack &st, bool um = true);
void pop_arg();
void undo_arg(IdentStack &st);
void redo_arg(IdentStack const &st);
void push_alias(IdentStack &st);
void pop_alias();
void set_arg(CsState &cs, TaggedValue &v);
void set_alias(CsState &cs, TaggedValue &v);
int get_valtype() const { int get_valtype() const {
return valtype; return valtype;
} }
@ -271,6 +255,8 @@ protected:
Ident(); Ident();
}; };
using VarCb = ostd::Function<void(Ident &)>;
struct OSTD_EXPORT Var: Ident { struct OSTD_EXPORT Var: Ident {
VarCb cb_var; VarCb cb_var;
@ -306,12 +292,24 @@ struct OSTD_EXPORT Svar: Var {
}; };
struct OSTD_EXPORT Alias: Ident { struct OSTD_EXPORT Alias: Ident {
Bytecode *code;
Alias(ostd::ConstCharRange n, char *a, int flags); Alias(ostd::ConstCharRange n, char *a, int flags);
Alias(ostd::ConstCharRange n, CsInt a, int flags); Alias(ostd::ConstCharRange n, CsInt a, int flags);
Alias(ostd::ConstCharRange n, CsFloat a, int flags); Alias(ostd::ConstCharRange n, CsFloat a, int flags);
Alias(ostd::ConstCharRange n, int flags); Alias(ostd::ConstCharRange n, int flags);
Alias(ostd::ConstCharRange n, TaggedValue const &v, int flags); Alias(ostd::ConstCharRange n, TaggedValue const &v, int flags);
void push_arg(TaggedValue const &v, IdentStack &st, bool um = true);
void pop_arg();
void undo_arg(IdentStack &st);
void redo_arg(IdentStack const &st);
void set_arg(CsState &cs, TaggedValue &v);
void set_alias(CsState &cs, TaggedValue &v);
void clean_code();
void force_null() { void force_null() {
if (valtype == VAL_STR) { if (valtype == VAL_STR) {
delete[] val.s; delete[] val.s;
@ -475,52 +473,52 @@ enum {
OSTD_EXPORT void init_libs(CsState &cs, int libs = CS_LIB_ALL); OSTD_EXPORT void init_libs(CsState &cs, int libs = CS_LIB_ALL);
struct OSTD_EXPORT StackedValue: TaggedValue { struct OSTD_EXPORT StackedValue: TaggedValue {
StackedValue(Ident *id = nullptr): StackedValue(Alias *a = nullptr):
TaggedValue(), p_id(nullptr), p_stack(), p_pushed(false) TaggedValue(), p_a(nullptr), p_stack(), p_pushed(false)
{ {
set_id(id); set_alias(a);
} }
~StackedValue() { ~StackedValue() {
pop(); pop();
} }
bool set_id(Ident *id) { bool set_alias(Ident *id) {
if (!id || !id->is_alias()) { if (!id || !id->is_alias()) {
return false; return false;
} }
p_id = id; p_a = static_cast<Alias *>(id);
return true; return true;
} }
Ident *get_id() const { Alias *get_alias() const {
return p_id; return p_a;
} }
bool has_id() const { bool has_alias() const {
return p_id != nullptr; return p_a != nullptr;
} }
bool push() { bool push() {
if (p_pushed || !p_id) { if (p_pushed || !p_a) {
return false; return false;
} }
p_id->push_arg(*this, p_stack); p_a->push_arg(*this, p_stack);
p_pushed = true; p_pushed = true;
return true; return true;
} }
bool pop() { bool pop() {
if (!p_pushed || !p_id) { if (!p_pushed || !p_a) {
return false; return false;
} }
p_id->pop_arg(); p_a->pop_arg();
p_pushed = false; p_pushed = false;
return true; return true;
} }
private: private:
Ident *p_id; Alias *p_a;
IdentStack p_stack; IdentStack p_stack;
bool p_pushed; bool p_pushed;
}; };

View File

@ -68,21 +68,21 @@ static inline void cs_list_assoc(TvalRange args, TaggedValue &res, F cmp) {
} }
} }
static inline void cs_set_iter(Ident &id, char *val, IdentStack &stack) { static inline void cs_set_iter(Alias &a, char *val, IdentStack &stack) {
if (id.stack == &stack) { if (a.stack == &stack) {
if (id.get_valtype() == VAL_STR) { if (a.get_valtype() == VAL_STR) {
delete[] id.val.s; delete[] a.val.s;
} else { } else {
id.valtype = VAL_STR; a.valtype = VAL_STR;
} }
id.clean_code(); a.clean_code();
id.val.s = val; a.val.s = val;
id.val.len = strlen(val); a.val.len = strlen(val);
return; return;
} }
TaggedValue v; TaggedValue v;
v.set_mstr(val); v.set_mstr(val);
id.push_arg(v, stack); a.push_arg(v, stack);
} }
static void cs_loop_list_conc( static void cs_loop_list_conc(
@ -97,7 +97,7 @@ static void cs_loop_list_conc(
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(*id, val, stack); cs_set_iter(*static_cast<Alias *>(id), val, stack);
if (n && space) { if (n && space) {
r.push(' '); r.push(' ');
} }
@ -108,7 +108,7 @@ static void cs_loop_list_conc(
v.cleanup(); v.cleanup();
} }
if (n) { if (n) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
} }
r.push('\0'); r.push('\0');
ostd::Size len = r.size(); ostd::Size len = r.size();
@ -222,7 +222,7 @@ void cs_init_lib_list(CsState &cs) {
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(*id, cs_dup_ostr(p.item), stack); cs_set_iter(*static_cast<Alias *>(id), cs_dup_ostr(p.item), stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
res.set_int(CsInt(n)); res.set_int(CsInt(n));
goto found; goto found;
@ -231,7 +231,7 @@ void cs_init_lib_list(CsState &cs) {
res.set_int(-1); res.set_int(-1);
found: found:
if (n >= 0) { if (n >= 0) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
} }
}); });
@ -245,7 +245,7 @@ found:
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(*id, cs_dup_ostr(p.item), stack); cs_set_iter(*static_cast<Alias *>(id), cs_dup_ostr(p.item), stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
if (p.parse()) { if (p.parse()) {
auto elem = p.element(); auto elem = p.element();
@ -260,7 +260,7 @@ found:
} }
} }
if (n >= 0) { if (n >= 0) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
} }
}); });
@ -317,11 +317,11 @@ found:
IdentStack stack; IdentStack stack;
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(*id, p.element().disown(), stack); cs_set_iter(*static_cast<Alias *>(id), p.element().disown(), stack);
cs.run_int(body); cs.run_int(body);
} }
if (n) { if (n) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
} }
}); });
@ -334,15 +334,16 @@ found:
IdentStack stack, stack2; IdentStack stack, stack2;
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(*id, p.element().disown(), stack); cs_set_iter(*static_cast<Alias *>(id), p.element().disown(), stack);
cs_set_iter( cs_set_iter(
*id2, p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2 *static_cast<Alias *>(id2),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2
); );
cs.run_int(body); cs.run_int(body);
} }
if (n) { if (n) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
id2->pop_arg(); static_cast<Alias *>(id2)->pop_arg();
} }
}); });
@ -357,19 +358,21 @@ found:
IdentStack stack, stack2, stack3; IdentStack stack, stack2, stack3;
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(*id, p.element().disown(), stack); cs_set_iter(*static_cast<Alias *>(id), p.element().disown(), stack);
cs_set_iter( cs_set_iter(
*id2, p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2 *static_cast<Alias *>(id2),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack2
); );
cs_set_iter( cs_set_iter(
*id3, p.parse() ? p.element().disown() : cs_dup_ostr(""), stack3 *static_cast<Alias *>(id3),
p.parse() ? p.element().disown() : cs_dup_ostr(""), stack3
); );
cs.run_int(body); cs.run_int(body);
} }
if (n) { if (n) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
id2->pop_arg(); static_cast<Alias *>(id2)->pop_arg();
id3->pop_arg(); static_cast<Alias *>(id3)->pop_arg();
} }
}); });
@ -402,7 +405,7 @@ found:
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(*id, val, stack); cs_set_iter(*static_cast<Alias *>(id), val, stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
if (r.size()) { if (r.size()) {
r.push(' '); r.push(' ');
@ -411,7 +414,7 @@ found:
} }
} }
if (n) { if (n) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
} }
r.push('\0'); r.push('\0');
ostd::Size len = r.size() - 1; ostd::Size len = r.size() - 1;
@ -428,13 +431,13 @@ found:
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(*id, val, stack); cs_set_iter(*static_cast<Alias *>(id), val, stack);
if (cs.run_bool(body)) { if (cs.run_bool(body)) {
r++; r++;
} }
} }
if (n) { if (n) {
id->pop_arg(); static_cast<Alias *>(id)->pop_arg();
} }
res.set_int(r); res.set_int(r);
}); });
@ -546,7 +549,7 @@ struct ListSortItem {
struct ListSortFun { struct ListSortFun {
CsState &cs; CsState &cs;
Ident *x, *y; Alias *x, *y;
Bytecode *body; Bytecode *body;
bool operator()(ListSortItem const &xval, ListSortItem const &yval) { bool operator()(ListSortItem const &xval, ListSortItem const &yval) {
@ -574,6 +577,8 @@ static void cs_list_sort(
return; return;
} }
Alias *xa = static_cast<Alias *>(x), *ya = static_cast<Alias *>(y);
ostd::Vector<ListSortItem> items; ostd::Vector<ListSortItem> items;
ostd::Size clen = list.size(); ostd::Size clen = list.size();
ostd::Size total = 0; ostd::Size total = 0;
@ -596,13 +601,13 @@ static void cs_list_sort(
nv.set_null(); nv.set_null();
IdentStack xstack, ystack; IdentStack xstack, ystack;
x->push_arg(nv, xstack); xa->push_arg(nv, xstack);
y->push_arg(nv, ystack); 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, x, y, body }; ListSortFun f = { cs, xa, ya, body };
ostd::sort_cmp(items.iter(), f); ostd::sort_cmp(items.iter(), f);
if (!code_is_empty(unique)) { if (!code_is_empty(unique)) {
f.body = unique; f.body = unique;
@ -619,7 +624,7 @@ static void cs_list_sort(
} }
} }
} else { } else {
ListSortFun f = { cs, x, y, unique }; ListSortFun f = { cs, xa, ya, 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++) {
@ -638,8 +643,8 @@ static void cs_list_sort(
} }
} }
x->pop_arg(); xa->pop_arg();
y->pop_arg(); ya->pop_arg();
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));