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;
|
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);
|
||||||
|
|
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;
|
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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
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) {
|
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));
|
||||||
|
|
Loading…
Reference in New Issue