move more code around
parent
ae00cf2ebb
commit
e7ce1d2b1e
94
cs_vm.cc
94
cs_vm.cc
|
@ -14,6 +14,18 @@ static inline bool cs_has_cmd_cb(Ident *id) {
|
|||
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(
|
||||
CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt,
|
||||
ostd::CharRange buf
|
||||
|
@ -434,37 +446,39 @@ static ostd::Uint32 const *runcode(
|
|||
);
|
||||
|
||||
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
|
||||
) {
|
||||
IdentStack argstack[MaxArguments];
|
||||
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;
|
||||
cs.numargs = callargs;
|
||||
int oldflags = cs.identflags;
|
||||
cs.identflags |= id->flags&IDF_OVERRIDDEN;
|
||||
cs.identflags |= a->flags&IDF_OVERRIDDEN;
|
||||
IdentLink aliaslink = {
|
||||
id, cs.stack, (1<<callargs)-1, argstack
|
||||
a, cs.stack, (1<<callargs)-1, argstack
|
||||
};
|
||||
cs.stack = &aliaslink;
|
||||
if (!id->code) {
|
||||
id->code = reinterpret_cast<Bytecode *>(compilecode(cs, id->get_str()));
|
||||
if (!a->code) {
|
||||
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);
|
||||
runcode(cs, codep+1, (result));
|
||||
bcode_decr(codep);
|
||||
cs.stack = aliaslink.next;
|
||||
cs.identflags = oldflags;
|
||||
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);
|
||||
for (; argmask; ++callargs) {
|
||||
if (argmask & (1 << callargs)) {
|
||||
cs.identmap[callargs]->pop_arg();
|
||||
static_cast<Alias *>(cs.identmap[callargs])->pop_arg();
|
||||
argmask &= ~(1 << callargs);
|
||||
}
|
||||
}
|
||||
|
@ -662,11 +676,11 @@ static ostd::Uint32 const *runcode(
|
|||
int numlocals = op >> 8, offset = numargs - numlocals;
|
||||
IdentStack locals[MaxArguments];
|
||||
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);
|
||||
for (int i = offset; i < numargs; i++) {
|
||||
args[i].id->pop_alias();
|
||||
cs_pop_alias(args[i].id);
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
@ -923,12 +937,12 @@ static ostd::Uint32 const *runcode(
|
|||
args[numargs++].set_ident(cs.identmap[op >> 8]);
|
||||
continue;
|
||||
case CODE_IDENTARG: {
|
||||
Ident *id = cs.identmap[op >> 8];
|
||||
if (!(cs.stack->usedargs & (1 << id->index))) {
|
||||
id->push_arg(null_value, cs.stack->argstack[id->index], false);
|
||||
cs.stack->usedargs |= 1 << id->index;
|
||||
Alias *a = static_cast<Alias *>(cs.identmap[op >> 8]);
|
||||
if (!(cs.stack->usedargs & (1 << a->index))) {
|
||||
a->push_arg(null_value, cs.stack->argstack[a->index], false);
|
||||
cs.stack->usedargs |= 1 << a->index;
|
||||
}
|
||||
args[numargs++].set_ident(id);
|
||||
args[numargs++].set_ident(a);
|
||||
continue;
|
||||
}
|
||||
case CODE_IDENTU: {
|
||||
|
@ -942,7 +956,9 @@ static ostd::Uint32 const *runcode(
|
|||
id = cs.new_ident(ostd::ConstCharRange(arg.cstr, arg.len));
|
||||
}
|
||||
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;
|
||||
}
|
||||
arg.cleanup();
|
||||
|
@ -1329,10 +1345,14 @@ static ostd::Uint32 const *runcode(
|
|||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
case CODE_ALIASU:
|
||||
numargs -= 2;
|
||||
|
@ -1354,7 +1374,8 @@ static ostd::Uint32 const *runcode(
|
|||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -1371,7 +1392,8 @@ static ostd::Uint32 const *runcode(
|
|||
continue;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
@ -1430,13 +1452,13 @@ noid:
|
|||
IdentStack locals[MaxArguments];
|
||||
idarg.cleanup();
|
||||
for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) {
|
||||
cs.force_ident(
|
||||
cs_push_alias(cs.force_ident(
|
||||
args[offset + j]
|
||||
)->push_alias(locals[j]);
|
||||
), locals[j]);
|
||||
}
|
||||
code = runcode(cs, code, result);
|
||||
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;
|
||||
}
|
||||
|
@ -1476,21 +1498,22 @@ noid:
|
|||
free_args(args, numargs, offset - 1);
|
||||
force_arg(result, op & CODE_RET_MASK);
|
||||
continue;
|
||||
case ID_ALIAS:
|
||||
case ID_ALIAS: {
|
||||
Alias *a = static_cast<Alias *>(id);
|
||||
if (
|
||||
id->index < MaxArguments &&
|
||||
!(cs.stack->usedargs & (1 << id->index))
|
||||
a->index < MaxArguments &&
|
||||
!(cs.stack->usedargs & (1 << a->index))
|
||||
) {
|
||||
free_args(args, numargs, offset - 1);
|
||||
force_arg(result, op & CODE_RET_MASK);
|
||||
continue;
|
||||
}
|
||||
if (id->get_valtype() == VAL_NULL) {
|
||||
if (a->get_valtype() == VAL_NULL) {
|
||||
goto noid;
|
||||
}
|
||||
idarg.cleanup();
|
||||
cs_call_alias(
|
||||
cs, id, args, result, callargs, numargs,
|
||||
cs, a, args, result, callargs, numargs,
|
||||
offset, 1, op
|
||||
);
|
||||
continue;
|
||||
|
@ -1498,6 +1521,7 @@ noid:
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exit:
|
||||
--rundepth;
|
||||
return code;
|
||||
|
@ -1573,21 +1597,23 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
|||
);
|
||||
}
|
||||
break;
|
||||
case ID_ALIAS:
|
||||
if (id->index < MaxArguments) {
|
||||
if (!(stack->usedargs & (1 << id->index))) {
|
||||
case ID_ALIAS: {
|
||||
Alias *a = static_cast<Alias *>(id);
|
||||
if (a->index < MaxArguments) {
|
||||
if (!(stack->usedargs & (1 << a->index))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (id->get_valtype() == VAL_NULL) {
|
||||
if (a->get_valtype() == VAL_NULL) {
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
free_args(args.data(), nargs, 0);
|
||||
--rundepth;
|
||||
}
|
||||
|
|
4
cs_vm.hh
4
cs_vm.hh
|
@ -70,7 +70,7 @@ static void cs_do_args(CsState &cs, F body) {
|
|||
int argmask1 = cs.stack->usedargs;
|
||||
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
|
||||
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;
|
||||
|
@ -84,7 +84,7 @@ static void cs_do_args(CsState &cs, F body) {
|
|||
int argmask2 = cs.stack->usedargs;
|
||||
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
|
||||
if (argmask2 & 1) {
|
||||
cs.identmap[i]->redo_arg(argstack[i]);
|
||||
static_cast<Alias *>(cs.identmap[i])->redo_arg(argstack[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,8 +159,9 @@ CsState::~CsState() {
|
|||
for (auto &p: idents.iter()) {
|
||||
Ident *i = p.second;
|
||||
if (i->type == ID_ALIAS) {
|
||||
static_cast<Alias *>(i)->force_null();
|
||||
delete[] reinterpret_cast<ostd::Uint32 *>(i->code);
|
||||
Alias *a = static_cast<Alias *>(i);
|
||||
a->force_null();
|
||||
delete[] reinterpret_cast<ostd::Uint32 *>(a->code);
|
||||
} else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) {
|
||||
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);
|
||||
if (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.valtype = valtype;
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -693,7 +694,7 @@ void Ident::pop_arg() {
|
|||
stack = st->next;
|
||||
}
|
||||
|
||||
void Ident::undo_arg(IdentStack &st) {
|
||||
void Alias::undo_arg(IdentStack &st) {
|
||||
IdentStack *prev = stack;
|
||||
st.val = val;
|
||||
st.valtype = valtype;
|
||||
|
@ -703,7 +704,7 @@ void Ident::undo_arg(IdentStack &st) {
|
|||
clean_code();
|
||||
}
|
||||
|
||||
void Ident::redo_arg(IdentStack const &st) {
|
||||
void Alias::redo_arg(IdentStack const &st) {
|
||||
IdentStack *prev = st.next;
|
||||
prev->val = val;
|
||||
prev->valtype = valtype;
|
||||
|
@ -712,19 +713,7 @@ void Ident::redo_arg(IdentStack const &st) {
|
|||
clean_code();
|
||||
}
|
||||
|
||||
void Ident::push_alias(IdentStack &stack) {
|
||||
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) {
|
||||
void Alias::set_arg(CsState &cs, TaggedValue &v) {
|
||||
if (cs.stack->usedargs & (1 << index)) {
|
||||
if (get_valtype() == VAL_STR) {
|
||||
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) {
|
||||
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) {
|
||||
if (id.stack == &stack) {
|
||||
if (id.get_valtype() != VAL_INT) {
|
||||
if (id.get_valtype() == VAL_STR) {
|
||||
delete[] id.val.s;
|
||||
id.val.s = nullptr;
|
||||
id.val.len = 0;
|
||||
static inline void cs_set_iter(Alias &a, CsInt i, IdentStack &stack) {
|
||||
if (a.stack == &stack) {
|
||||
if (a.get_valtype() != VAL_INT) {
|
||||
if (a.get_valtype() == VAL_STR) {
|
||||
delete[] a.val.s;
|
||||
a.val.s = nullptr;
|
||||
a.val.len = 0;
|
||||
}
|
||||
id.clean_code();
|
||||
id.valtype = VAL_INT;
|
||||
a.clean_code();
|
||||
a.valtype = VAL_INT;
|
||||
}
|
||||
id.val.i = i;
|
||||
a.val.i = i;
|
||||
return;
|
||||
}
|
||||
TaggedValue v;
|
||||
v.set_int(i);
|
||||
id.push_arg(v, stack);
|
||||
a.push_arg(v, stack);
|
||||
}
|
||||
|
||||
static inline void cs_do_loop(
|
||||
|
@ -1132,15 +1121,16 @@ static inline void cs_do_loop(
|
|||
if (n <= 0 || !id.is_alias()) {
|
||||
return;
|
||||
}
|
||||
Alias &a = static_cast<Alias &>(id);
|
||||
IdentStack stack;
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
cs.run_int(body);
|
||||
}
|
||||
id.pop_arg();
|
||||
a.pop_arg();
|
||||
}
|
||||
|
||||
static inline void cs_loop_conc(
|
||||
|
@ -1150,10 +1140,11 @@ static inline void cs_loop_conc(
|
|||
if (n <= 0 || !id.is_alias()) {
|
||||
return;
|
||||
}
|
||||
Alias &a = static_cast<Alias &>(id);
|
||||
IdentStack stack;
|
||||
ostd::Vector<char> s;
|
||||
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;
|
||||
cs.run_ret(body, v);
|
||||
ostd::String vstr = ostd::move(v.get_str());
|
||||
|
@ -1164,7 +1155,7 @@ static inline void cs_loop_conc(
|
|||
v.cleanup();
|
||||
}
|
||||
if (n > 0) {
|
||||
id.pop_arg();
|
||||
a.pop_arg();
|
||||
}
|
||||
s.push('\0');
|
||||
ostd::Size len = s.size() - 1;
|
||||
|
@ -1293,12 +1284,13 @@ void cs_init_lib_base(CsState &cs) {
|
|||
if (!id->is_alias() || (id->index < MaxArguments)) {
|
||||
return;
|
||||
}
|
||||
Alias *a = static_cast<Alias *>(id);
|
||||
if (v.get_bool()) {
|
||||
IdentStack stack;
|
||||
id->push_arg(v, stack);
|
||||
a->push_arg(v, stack);
|
||||
v.set_null();
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
Alias *a = static_cast<Alias *>(id);
|
||||
IdentStack stack;
|
||||
TaggedValue &v = args[1];
|
||||
id->push_arg(v, stack);
|
||||
a->push_arg(v, stack);
|
||||
v.set_null();
|
||||
cs.run_ret(args[2].get_code(), res);
|
||||
id->pop_arg();
|
||||
a->pop_arg();
|
||||
});
|
||||
|
||||
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);
|
||||
|
|
|
@ -172,8 +172,6 @@ union IdentValuePtr {
|
|||
|
||||
struct CsState;
|
||||
|
||||
using VarCb = ostd::Function<void(Ident &)>;
|
||||
|
||||
enum class IdentType {
|
||||
unknown = -1,
|
||||
ivar, fvar, svar, command, alias
|
||||
|
@ -199,7 +197,6 @@ struct OSTD_EXPORT Ident {
|
|||
IdentValue overrideval;
|
||||
};
|
||||
struct { /* ID_ALIAS */
|
||||
Bytecode *code;
|
||||
IdentValue val;
|
||||
IdentStack *stack;
|
||||
};
|
||||
|
@ -223,19 +220,6 @@ struct OSTD_EXPORT Ident {
|
|||
void get_cstr(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 {
|
||||
return valtype;
|
||||
}
|
||||
|
@ -271,6 +255,8 @@ protected:
|
|||
Ident();
|
||||
};
|
||||
|
||||
using VarCb = ostd::Function<void(Ident &)>;
|
||||
|
||||
struct OSTD_EXPORT Var: Ident {
|
||||
VarCb cb_var;
|
||||
|
||||
|
@ -306,12 +292,24 @@ struct OSTD_EXPORT Svar: Var {
|
|||
};
|
||||
|
||||
struct OSTD_EXPORT Alias: Ident {
|
||||
Bytecode *code;
|
||||
|
||||
Alias(ostd::ConstCharRange n, char *a, int flags);
|
||||
Alias(ostd::ConstCharRange n, CsInt a, int flags);
|
||||
Alias(ostd::ConstCharRange n, CsFloat a, int flags);
|
||||
Alias(ostd::ConstCharRange n, 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() {
|
||||
if (valtype == VAL_STR) {
|
||||
delete[] val.s;
|
||||
|
@ -475,52 +473,52 @@ enum {
|
|||
OSTD_EXPORT void init_libs(CsState &cs, int libs = CS_LIB_ALL);
|
||||
|
||||
struct OSTD_EXPORT StackedValue: TaggedValue {
|
||||
StackedValue(Ident *id = nullptr):
|
||||
TaggedValue(), p_id(nullptr), p_stack(), p_pushed(false)
|
||||
StackedValue(Alias *a = nullptr):
|
||||
TaggedValue(), p_a(nullptr), p_stack(), p_pushed(false)
|
||||
{
|
||||
set_id(id);
|
||||
set_alias(a);
|
||||
}
|
||||
|
||||
~StackedValue() {
|
||||
pop();
|
||||
}
|
||||
|
||||
bool set_id(Ident *id) {
|
||||
bool set_alias(Ident *id) {
|
||||
if (!id || !id->is_alias()) {
|
||||
return false;
|
||||
}
|
||||
p_id = id;
|
||||
p_a = static_cast<Alias *>(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
Ident *get_id() const {
|
||||
return p_id;
|
||||
Alias *get_alias() const {
|
||||
return p_a;
|
||||
}
|
||||
|
||||
bool has_id() const {
|
||||
return p_id != nullptr;
|
||||
bool has_alias() const {
|
||||
return p_a != nullptr;
|
||||
}
|
||||
|
||||
bool push() {
|
||||
if (p_pushed || !p_id) {
|
||||
if (p_pushed || !p_a) {
|
||||
return false;
|
||||
}
|
||||
p_id->push_arg(*this, p_stack);
|
||||
p_a->push_arg(*this, p_stack);
|
||||
p_pushed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pop() {
|
||||
if (!p_pushed || !p_id) {
|
||||
if (!p_pushed || !p_a) {
|
||||
return false;
|
||||
}
|
||||
p_id->pop_arg();
|
||||
p_a->pop_arg();
|
||||
p_pushed = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Ident *p_id;
|
||||
Alias *p_a;
|
||||
IdentStack p_stack;
|
||||
bool p_pushed;
|
||||
};
|
||||
|
|
81
lib_list.cc
81
lib_list.cc
|
@ -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) {
|
||||
if (id.stack == &stack) {
|
||||
if (id.get_valtype() == VAL_STR) {
|
||||
delete[] id.val.s;
|
||||
static inline void cs_set_iter(Alias &a, char *val, IdentStack &stack) {
|
||||
if (a.stack == &stack) {
|
||||
if (a.get_valtype() == VAL_STR) {
|
||||
delete[] a.val.s;
|
||||
} else {
|
||||
id.valtype = VAL_STR;
|
||||
a.valtype = VAL_STR;
|
||||
}
|
||||
id.clean_code();
|
||||
id.val.s = val;
|
||||
id.val.len = strlen(val);
|
||||
a.clean_code();
|
||||
a.val.s = val;
|
||||
a.val.len = strlen(val);
|
||||
return;
|
||||
}
|
||||
TaggedValue v;
|
||||
v.set_mstr(val);
|
||||
id.push_arg(v, stack);
|
||||
a.push_arg(v, stack);
|
||||
}
|
||||
|
||||
static void cs_loop_list_conc(
|
||||
|
@ -97,7 +97,7 @@ static void cs_loop_list_conc(
|
|||
int n = 0;
|
||||
for (util::ListParser p(list); p.parse(); ++n) {
|
||||
char *val = p.element().disown();
|
||||
cs_set_iter(*id, val, stack);
|
||||
cs_set_iter(*static_cast<Alias *>(id), val, stack);
|
||||
if (n && space) {
|
||||
r.push(' ');
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ static void cs_loop_list_conc(
|
|||
v.cleanup();
|
||||
}
|
||||
if (n) {
|
||||
id->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
}
|
||||
r.push('\0');
|
||||
ostd::Size len = r.size();
|
||||
|
@ -222,7 +222,7 @@ void cs_init_lib_list(CsState &cs) {
|
|||
int n = -1;
|
||||
for (util::ListParser p(args[1].get_strr()); p.parse();) {
|
||||
++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)) {
|
||||
res.set_int(CsInt(n));
|
||||
goto found;
|
||||
|
@ -231,7 +231,7 @@ void cs_init_lib_list(CsState &cs) {
|
|||
res.set_int(-1);
|
||||
found:
|
||||
if (n >= 0) {
|
||||
id->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -245,7 +245,7 @@ found:
|
|||
int n = -1;
|
||||
for (util::ListParser p(args[1].get_strr()); p.parse();) {
|
||||
++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 (p.parse()) {
|
||||
auto elem = p.element();
|
||||
|
@ -260,7 +260,7 @@ found:
|
|||
}
|
||||
}
|
||||
if (n >= 0) {
|
||||
id->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -317,11 +317,11 @@ found:
|
|||
IdentStack stack;
|
||||
int n = 0;
|
||||
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);
|
||||
}
|
||||
if (n) {
|
||||
id->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -334,15 +334,16 @@ found:
|
|||
IdentStack stack, stack2;
|
||||
int n = 0;
|
||||
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(
|
||||
*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);
|
||||
}
|
||||
if (n) {
|
||||
id->pop_arg();
|
||||
id2->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
static_cast<Alias *>(id2)->pop_arg();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -357,19 +358,21 @@ found:
|
|||
IdentStack stack, stack2, stack3;
|
||||
int n = 0;
|
||||
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(
|
||||
*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(
|
||||
*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);
|
||||
}
|
||||
if (n) {
|
||||
id->pop_arg();
|
||||
id2->pop_arg();
|
||||
id3->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
static_cast<Alias *>(id2)->pop_arg();
|
||||
static_cast<Alias *>(id3)->pop_arg();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -402,7 +405,7 @@ found:
|
|||
int n = 0;
|
||||
for (util::ListParser p(args[1].get_strr()); p.parse(); ++n) {
|
||||
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 (r.size()) {
|
||||
r.push(' ');
|
||||
|
@ -411,7 +414,7 @@ found:
|
|||
}
|
||||
}
|
||||
if (n) {
|
||||
id->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
}
|
||||
r.push('\0');
|
||||
ostd::Size len = r.size() - 1;
|
||||
|
@ -428,13 +431,13 @@ found:
|
|||
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(*id, val, stack);
|
||||
cs_set_iter(*static_cast<Alias *>(id), val, stack);
|
||||
if (cs.run_bool(body)) {
|
||||
r++;
|
||||
}
|
||||
}
|
||||
if (n) {
|
||||
id->pop_arg();
|
||||
static_cast<Alias *>(id)->pop_arg();
|
||||
}
|
||||
res.set_int(r);
|
||||
});
|
||||
|
@ -546,7 +549,7 @@ struct ListSortItem {
|
|||
|
||||
struct ListSortFun {
|
||||
CsState &cs;
|
||||
Ident *x, *y;
|
||||
Alias *x, *y;
|
||||
Bytecode *body;
|
||||
|
||||
bool operator()(ListSortItem const &xval, ListSortItem const &yval) {
|
||||
|
@ -574,6 +577,8 @@ static void cs_list_sort(
|
|||
return;
|
||||
}
|
||||
|
||||
Alias *xa = static_cast<Alias *>(x), *ya = static_cast<Alias *>(y);
|
||||
|
||||
ostd::Vector<ListSortItem> items;
|
||||
ostd::Size clen = list.size();
|
||||
ostd::Size total = 0;
|
||||
|
@ -596,13 +601,13 @@ static void cs_list_sort(
|
|||
nv.set_null();
|
||||
|
||||
IdentStack xstack, ystack;
|
||||
x->push_arg(nv, xstack);
|
||||
y->push_arg(nv, ystack);
|
||||
xa->push_arg(nv, xstack);
|
||||
ya->push_arg(nv, ystack);
|
||||
|
||||
ostd::Size totaluniq = total;
|
||||
ostd::Size nuniq = items.size();
|
||||
if (body) {
|
||||
ListSortFun f = { cs, x, y, body };
|
||||
ListSortFun f = { cs, xa, ya, body };
|
||||
ostd::sort_cmp(items.iter(), f);
|
||||
if (!code_is_empty(unique)) {
|
||||
f.body = unique;
|
||||
|
@ -619,7 +624,7 @@ static void cs_list_sort(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
ListSortFun f = { cs, x, y, unique };
|
||||
ListSortFun f = { cs, xa, ya, unique };
|
||||
totaluniq = items[0].quote.size();
|
||||
nuniq = 1;
|
||||
for (ostd::Size i = 1; i < items.size(); i++) {
|
||||
|
@ -638,8 +643,8 @@ static void cs_list_sort(
|
|||
}
|
||||
}
|
||||
|
||||
x->pop_arg();
|
||||
y->pop_arg();
|
||||
xa->pop_arg();
|
||||
ya->pop_arg();
|
||||
|
||||
char *sorted = cstr;
|
||||
ostd::Size sortedlen = totaluniq + ostd::max(nuniq - 1, ostd::Size(0));
|
||||
|
|
Loading…
Reference in New Issue