forked from OctaForge/libcubescript
more progress
parent
a2091bdbbd
commit
27c0f1922b
208
command.cc
208
command.cc
|
@ -215,84 +215,90 @@ void debug_alias(CsState &cs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ident::push_arg(const TaggedValue &v, IdentStack &st) {
|
||||||
|
st.val = val;
|
||||||
|
st.valtype = valtype;
|
||||||
|
st.next = stack;
|
||||||
|
stack = &st;
|
||||||
|
setval(v);
|
||||||
|
clean_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ident::pop_arg() {
|
||||||
|
if (!stack) return;
|
||||||
|
IdentStack *st = stack;
|
||||||
|
if (valtype == VAL_STR) delete[] val.s;
|
||||||
|
setval(*stack);
|
||||||
|
clean_code();
|
||||||
|
stack = st->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ident::undo_arg(IdentStack &st) {
|
||||||
|
IdentStack *prev = stack;
|
||||||
|
st.val = val;
|
||||||
|
st.valtype = valtype;
|
||||||
|
st.next = prev;
|
||||||
|
stack = prev->next;
|
||||||
|
setval(*prev);
|
||||||
|
clean_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Ident::redo_arg(const IdentStack &st) {
|
||||||
|
IdentStack *prev = st.next;
|
||||||
|
prev->val = val;
|
||||||
|
prev->valtype = valtype;
|
||||||
|
stack = prev;
|
||||||
|
setval(st);
|
||||||
|
clean_code();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
static void cs_do_args(CsState &cs, F body) {
|
||||||
|
IdentStack argstack[MAX_ARGUMENTS];
|
||||||
|
int argmask1 = cs.stack->usedargs;
|
||||||
|
for (int i = 0; argmask1; argmask1 >>= 1, ++i) if(argmask1 & 1)
|
||||||
|
cs.identmap[i]->undo_arg(argstack[i]);
|
||||||
|
IdentLink *prevstack = cs.stack->next;
|
||||||
|
IdentLink aliaslink = {
|
||||||
|
cs.stack->id, cs.stack, prevstack->usedargs, prevstack->argstack
|
||||||
|
};
|
||||||
|
cs.stack = &aliaslink;
|
||||||
|
body();
|
||||||
|
prevstack->usedargs = aliaslink.usedargs;
|
||||||
|
cs.stack = aliaslink.next;
|
||||||
|
int argmask2 = cs.stack->usedargs;
|
||||||
|
for(int i = 0; argmask2; argmask2 >>= 1, ++i) if(argmask2 & 1)
|
||||||
|
cs.identmap[i]->redo_arg(argstack[i]);
|
||||||
|
}
|
||||||
|
|
||||||
void init_lib_base(CsState &cs) {
|
void init_lib_base(CsState &cs) {
|
||||||
cs.add_command("nodebug", "e", [](CsState &cs, ostd::uint *body) {
|
cs.add_command("nodebug", "e", [](CsState &cs, ostd::uint *body) {
|
||||||
++cs.nodebug;
|
++cs.nodebug;
|
||||||
executeret(body, *cs.result);
|
executeret(body, *cs.result);
|
||||||
--cs.nodebug;
|
--cs.nodebug;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cs.add_command("push", "rTe", [](CsState &cs, Ident *id,
|
||||||
|
TaggedValue *v, ostd::uint *code) {
|
||||||
|
if (id->type != ID_ALIAS || id->index < MAX_ARGUMENTS) return;
|
||||||
|
IdentStack stack;
|
||||||
|
id->push_arg(*v, stack);
|
||||||
|
v->type = VAL_NULL;
|
||||||
|
id->flags &= ~IDF_UNKNOWN;
|
||||||
|
executeret(code, *cs.result);
|
||||||
|
id->pop_arg();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void pusharg(Ident &id, const TaggedValue &v, IdentStack &stack) {
|
|
||||||
stack.val = id.val;
|
|
||||||
stack.valtype = id.valtype;
|
|
||||||
stack.next = id.stack;
|
|
||||||
id.stack = &stack;
|
|
||||||
id.setval(v);
|
|
||||||
id.clean_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
void poparg(Ident &id) {
|
|
||||||
if (!id.stack) return;
|
|
||||||
IdentStack *stack = id.stack;
|
|
||||||
if (id.valtype == VAL_STR) delete[] id.val.s;
|
|
||||||
id.setval(*stack);
|
|
||||||
id.clean_code();
|
|
||||||
id.stack = stack->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void undoarg(Ident &id, IdentStack &stack) {
|
|
||||||
IdentStack *prev = id.stack;
|
|
||||||
stack.val = id.val;
|
|
||||||
stack.valtype = id.valtype;
|
|
||||||
stack.next = prev;
|
|
||||||
id.stack = prev->next;
|
|
||||||
id.setval(*prev);
|
|
||||||
id.clean_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UNDOARGS \
|
|
||||||
IdentStack argstack[MAX_ARGUMENTS]; \
|
|
||||||
for(int argmask = cstate.stack->usedargs, i = 0; argmask; argmask >>= 1, i++) if(argmask&1) \
|
|
||||||
undoarg(*cstate.identmap[i], argstack[i]); \
|
|
||||||
IdentLink *prevstack = cstate.stack->next; \
|
|
||||||
IdentLink aliaslink = { cstate.stack->id, cstate.stack, prevstack->usedargs, prevstack->argstack }; \
|
|
||||||
cstate.stack = &aliaslink;
|
|
||||||
|
|
||||||
static inline void redoarg(Ident &id, const IdentStack &stack) {
|
|
||||||
IdentStack *prev = stack.next;
|
|
||||||
prev->val = id.val;
|
|
||||||
prev->valtype = id.valtype;
|
|
||||||
id.stack = prev;
|
|
||||||
id.setval(stack);
|
|
||||||
id.clean_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define REDOARGS \
|
|
||||||
prevstack->usedargs = aliaslink.usedargs; \
|
|
||||||
cstate.stack = aliaslink.next; \
|
|
||||||
for(int argmask = cstate.stack->usedargs, i = 0; argmask; argmask >>= 1, i++) if(argmask&1) \
|
|
||||||
redoarg(*cstate.identmap[i], argstack[i]);
|
|
||||||
|
|
||||||
ICOMMAND(push, "rTe", (CsState &cs, Ident *id, TaggedValue *v, ostd::uint *code), {
|
|
||||||
if (id->type != ID_ALIAS || id->index < MAX_ARGUMENTS) return;
|
|
||||||
IdentStack stack;
|
|
||||||
pusharg(*id, *v, stack);
|
|
||||||
v->type = VAL_NULL;
|
|
||||||
id->flags &= ~IDF_UNKNOWN;
|
|
||||||
executeret(code, *cs.result);
|
|
||||||
poparg(*id);
|
|
||||||
});
|
|
||||||
|
|
||||||
static inline void pushalias(Ident &id, IdentStack &stack) {
|
static inline void pushalias(Ident &id, IdentStack &stack) {
|
||||||
if (id.type == ID_ALIAS && id.index >= MAX_ARGUMENTS) {
|
if (id.type == ID_ALIAS && id.index >= MAX_ARGUMENTS) {
|
||||||
pusharg(id, null_value, stack);
|
id.push_arg(null_value, stack);
|
||||||
id.flags &= ~IDF_UNKNOWN;
|
id.flags &= ~IDF_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void popalias(Ident &id) {
|
static inline void popalias(Ident &id) {
|
||||||
if (id.type == ID_ALIAS && id.index >= MAX_ARGUMENTS) poparg(id);
|
if (id.type == ID_ALIAS && id.index >= MAX_ARGUMENTS) id.pop_arg();
|
||||||
}
|
}
|
||||||
|
|
||||||
KEYWORD(local, ID_LOCAL);
|
KEYWORD(local, ID_LOCAL);
|
||||||
|
@ -374,7 +380,7 @@ static inline void setarg(Ident &id, TaggedValue &v) {
|
||||||
id.setval(v);
|
id.setval(v);
|
||||||
id.clean_code();
|
id.clean_code();
|
||||||
} else {
|
} else {
|
||||||
pusharg(id, v, cstate.stack->argstack[id.index]);
|
id.push_arg(v, cstate.stack->argstack[id.index]);
|
||||||
cstate.stack->usedargs |= 1 << id.index;
|
cstate.stack->usedargs |= 1 << id.index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2341,12 +2347,12 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
|
||||||
case CODE_DOARGS|RET_INT:
|
case CODE_DOARGS|RET_INT:
|
||||||
case CODE_DOARGS|RET_FLOAT:
|
case CODE_DOARGS|RET_FLOAT:
|
||||||
if (cstate.stack != &cstate.noalias) {
|
if (cstate.stack != &cstate.noalias) {
|
||||||
UNDOARGS
|
cs_do_args(cstate, [&]() {
|
||||||
result.cleanup();
|
result.cleanup();
|
||||||
runcode(args[--numargs].code, result);
|
runcode(args[--numargs].code, result);
|
||||||
args[numargs].cleanup();
|
args[numargs].cleanup();
|
||||||
result.force(op & CODE_RET_MASK);
|
result.force(op & CODE_RET_MASK);
|
||||||
REDOARGS
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
|
@ -2552,7 +2558,7 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
|
||||||
case CODE_IDENTARG: {
|
case CODE_IDENTARG: {
|
||||||
Ident *id = cstate.identmap[op >> 8];
|
Ident *id = cstate.identmap[op >> 8];
|
||||||
if (!(cstate.stack->usedargs & (1 << id->index))) {
|
if (!(cstate.stack->usedargs & (1 << id->index))) {
|
||||||
pusharg(*id, null_value, cstate.stack->argstack[id->index]);
|
id->push_arg(null_value, cstate.stack->argstack[id->index]);
|
||||||
cstate.stack->usedargs |= 1 << id->index;
|
cstate.stack->usedargs |= 1 << id->index;
|
||||||
}
|
}
|
||||||
args[numargs++].set_ident(id);
|
args[numargs++].set_ident(id);
|
||||||
|
@ -2562,7 +2568,7 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
|
||||||
TaggedValue &arg = args[numargs - 1];
|
TaggedValue &arg = args[numargs - 1];
|
||||||
Ident *id = arg.type == VAL_STR || arg.type == VAL_MACRO || arg.type == VAL_CSTR ? cstate.new_ident(arg.cstr, IDF_UNKNOWN) : cstate.dummy;
|
Ident *id = arg.type == VAL_STR || arg.type == VAL_MACRO || arg.type == VAL_CSTR ? cstate.new_ident(arg.cstr, IDF_UNKNOWN) : cstate.dummy;
|
||||||
if (id->index < MAX_ARGUMENTS && !(cstate.stack->usedargs & (1 << id->index))) {
|
if (id->index < MAX_ARGUMENTS && !(cstate.stack->usedargs & (1 << id->index))) {
|
||||||
pusharg(*id, null_value, cstate.stack->argstack[id->index]);
|
id->push_arg(null_value, cstate.stack->argstack[id->index]);
|
||||||
cstate.stack->usedargs |= 1 << id->index;
|
cstate.stack->usedargs |= 1 << id->index;
|
||||||
}
|
}
|
||||||
arg.cleanup();
|
arg.cleanup();
|
||||||
|
@ -2829,7 +2835,7 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
|
||||||
#define CALLALIAS { \
|
#define CALLALIAS { \
|
||||||
IdentStack argstack[MAX_ARGUMENTS]; \
|
IdentStack argstack[MAX_ARGUMENTS]; \
|
||||||
for(int i = 0; i < callargs; i++) \
|
for(int i = 0; i < callargs; i++) \
|
||||||
pusharg(*cstate.identmap[i], args[offset + i], argstack[i]); \
|
cstate.identmap[i]->push_arg(args[offset + i], argstack[i]); \
|
||||||
int oldargs = _numargs; \
|
int oldargs = _numargs; \
|
||||||
_numargs = callargs; \
|
_numargs = callargs; \
|
||||||
int oldflags = cstate.identflags; \
|
int oldflags = cstate.identflags; \
|
||||||
|
@ -2845,9 +2851,9 @@ static const ostd::uint *runcode(const ostd::uint *code, TaggedValue &result) {
|
||||||
cstate.stack = aliaslink.next; \
|
cstate.stack = aliaslink.next; \
|
||||||
cstate.identflags = oldflags; \
|
cstate.identflags = oldflags; \
|
||||||
for(int i = 0; i < callargs; i++) \
|
for(int i = 0; i < callargs; i++) \
|
||||||
poparg(*cstate.identmap[i]); \
|
cstate.identmap[i]->pop_arg(); \
|
||||||
for(int argmask = aliaslink.usedargs&(~0<<callargs), i = callargs; argmask; i++) \
|
for(int argmask = aliaslink.usedargs&(~0<<callargs), i = callargs; argmask; i++) \
|
||||||
if(argmask&(1<<i)) { poparg(*cstate.identmap[i]); argmask &= ~(1<<i); } \
|
if(argmask&(1<<i)) { cstate.identmap[i]->pop_arg(); argmask &= ~(1<<i); } \
|
||||||
result.force(op&CODE_RET_MASK); \
|
result.force(op&CODE_RET_MASK); \
|
||||||
_numargs = oldargs; \
|
_numargs = oldargs; \
|
||||||
numargs = SKIPARGS(offset); \
|
numargs = SKIPARGS(offset); \
|
||||||
|
@ -3253,9 +3259,7 @@ ICOMMANDK(do, ID_DO, "e", (CsState &cs, ostd::uint *body), executeret(body, *cs.
|
||||||
|
|
||||||
static void doargs(CsState &cs, ostd::uint *body) {
|
static void doargs(CsState &cs, ostd::uint *body) {
|
||||||
if (cstate.stack != &cstate.noalias) {
|
if (cstate.stack != &cstate.noalias) {
|
||||||
UNDOARGS
|
cs_do_args(cs, [&]() { executeret(body, *cs.result); });
|
||||||
executeret(body, *cs.result);
|
|
||||||
REDOARGS
|
|
||||||
} else executeret(body, *cs.result);
|
} else executeret(body, *cs.result);
|
||||||
}
|
}
|
||||||
COMMANDK(doargs, ID_DOARGS, "e");
|
COMMANDK(doargs, ID_DOARGS, "e");
|
||||||
|
@ -3267,17 +3271,17 @@ ICOMMAND(pushif, "rTe", (CsState &cs, Ident *id, TaggedValue *v, ostd::uint *cod
|
||||||
if (id->type != ID_ALIAS || id->index < MAX_ARGUMENTS) return;
|
if (id->type != ID_ALIAS || id->index < MAX_ARGUMENTS) return;
|
||||||
if (getbool(*v)) {
|
if (getbool(*v)) {
|
||||||
IdentStack stack;
|
IdentStack stack;
|
||||||
pusharg(*id, *v, stack);
|
id->push_arg(*v, stack);
|
||||||
v->type = VAL_NULL;
|
v->type = VAL_NULL;
|
||||||
id->flags &= ~IDF_UNKNOWN;
|
id->flags &= ~IDF_UNKNOWN;
|
||||||
executeret(code, *cs.result);
|
executeret(code, *cs.result);
|
||||||
poparg(*id);
|
id->pop_arg();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
void loopiter(Ident *id, IdentStack &stack, const TaggedValue &v) {
|
void loopiter(Ident *id, IdentStack &stack, const TaggedValue &v) {
|
||||||
if (id->stack != &stack) {
|
if (id->stack != &stack) {
|
||||||
pusharg(*id, v, stack);
|
id->push_arg(v, stack);
|
||||||
id->flags &= ~IDF_UNKNOWN;
|
id->flags &= ~IDF_UNKNOWN;
|
||||||
} else {
|
} else {
|
||||||
if (id->valtype == VAL_STR) delete[] id->val.s;
|
if (id->valtype == VAL_STR) delete[] id->val.s;
|
||||||
|
@ -3287,7 +3291,7 @@ void loopiter(Ident *id, IdentStack &stack, const TaggedValue &v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void loopend(Ident *id, IdentStack &stack) {
|
void loopend(Ident *id, IdentStack &stack) {
|
||||||
if (id->stack == &stack) poparg(*id);
|
if (id->stack == &stack) id->pop_arg();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void setiter(Ident &id, int i, IdentStack &stack) {
|
static inline void setiter(Ident &id, int i, IdentStack &stack) {
|
||||||
|
@ -3301,7 +3305,7 @@ static inline void setiter(Ident &id, int i, IdentStack &stack) {
|
||||||
} else {
|
} else {
|
||||||
TaggedValue t;
|
TaggedValue t;
|
||||||
t.set_int(i);
|
t.set_int(i);
|
||||||
pusharg(id, t, stack);
|
id.push_arg(t, stack);
|
||||||
id.flags &= ~IDF_UNKNOWN;
|
id.flags &= ~IDF_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3313,7 +3317,7 @@ static inline void doloop(CsState &cs, Ident &id, int offset, int n, int step, o
|
||||||
setiter(id, offset + i * step, stack);
|
setiter(id, offset + i * step, stack);
|
||||||
cs.run_int(body);
|
cs.run_int(body);
|
||||||
}
|
}
|
||||||
poparg(id);
|
id.pop_arg();
|
||||||
}
|
}
|
||||||
ICOMMAND(loop, "rie", (CsState &cs, Ident *id, int *n, ostd::uint *body), doloop(cs, *id, 0, *n, 1, body));
|
ICOMMAND(loop, "rie", (CsState &cs, Ident *id, int *n, ostd::uint *body), doloop(cs, *id, 0, *n, 1, body));
|
||||||
ICOMMAND(loop+, "riie", (CsState &cs, Ident *id, int *offset, int *n, ostd::uint *body), doloop(cs, *id, *offset, *n, 1, body));
|
ICOMMAND(loop+, "riie", (CsState &cs, Ident *id, int *offset, int *n, ostd::uint *body), doloop(cs, *id, *offset, *n, 1, body));
|
||||||
|
@ -3328,7 +3332,7 @@ static inline void loopwhile(CsState &cs, Ident &id, int offset, int n, int step
|
||||||
if (!cs.run_bool(cond)) break;
|
if (!cs.run_bool(cond)) break;
|
||||||
cs.run_int(body);
|
cs.run_int(body);
|
||||||
}
|
}
|
||||||
poparg(id);
|
id.pop_arg();
|
||||||
}
|
}
|
||||||
ICOMMAND(loopwhile, "riee", (CsState &cs, Ident *id, int *n, ostd::uint *cond, ostd::uint *body), loopwhile(cs, *id, 0, *n, 1, cond, body));
|
ICOMMAND(loopwhile, "riee", (CsState &cs, Ident *id, int *n, ostd::uint *cond, ostd::uint *body), loopwhile(cs, *id, 0, *n, 1, cond, body));
|
||||||
ICOMMAND(loopwhile+, "riiee", (CsState &cs, Ident *id, int *offset, int *n, ostd::uint *cond, ostd::uint *body), loopwhile(cs, *id, *offset, *n, 1, cond, body));
|
ICOMMAND(loopwhile+, "riiee", (CsState &cs, Ident *id, int *offset, int *n, ostd::uint *cond, ostd::uint *body), loopwhile(cs, *id, *offset, *n, 1, cond, body));
|
||||||
|
@ -3351,7 +3355,7 @@ static inline void loopconc(Ident &id, int offset, int n, int step, ostd::uint *
|
||||||
s.push_n(vstr, len);
|
s.push_n(vstr, len);
|
||||||
v.cleanup();
|
v.cleanup();
|
||||||
}
|
}
|
||||||
if (n > 0) poparg(id);
|
if (n > 0) id.pop_arg();
|
||||||
s.push('\0');
|
s.push('\0');
|
||||||
cstate.result->set_str(s.disown());
|
cstate.result->set_str(s.disown());
|
||||||
}
|
}
|
||||||
|
@ -3557,7 +3561,7 @@ static inline void setiter(Ident &id, char *val, IdentStack &stack) {
|
||||||
} else {
|
} else {
|
||||||
TaggedValue t;
|
TaggedValue t;
|
||||||
t.set_str(val);
|
t.set_str(val);
|
||||||
pusharg(id, t, stack);
|
id.push_arg(t, stack);
|
||||||
id.flags &= ~IDF_UNKNOWN;
|
id.flags &= ~IDF_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3579,7 +3583,7 @@ void listfind(CsState &cs, Ident *id, const char *list, const ostd::uint *body)
|
||||||
}
|
}
|
||||||
cs.result->set_int(-1);
|
cs.result->set_int(-1);
|
||||||
found:
|
found:
|
||||||
if (n >= 0) poparg(*id);
|
if (n >= 0) id->pop_arg();
|
||||||
}
|
}
|
||||||
COMMAND(listfind, "rse");
|
COMMAND(listfind, "rse");
|
||||||
|
|
||||||
|
@ -3596,7 +3600,7 @@ void listassoc(CsState &cs, Ident *id, const char *list, const ostd::uint *body)
|
||||||
}
|
}
|
||||||
if (!parselist(s)) break;
|
if (!parselist(s)) break;
|
||||||
}
|
}
|
||||||
if (n >= 0) poparg(*id);
|
if (n >= 0) id->pop_arg();
|
||||||
}
|
}
|
||||||
COMMAND(listassoc, "rse");
|
COMMAND(listassoc, "rse");
|
||||||
|
|
||||||
|
@ -3639,7 +3643,7 @@ void looplist(CsState &cs, Ident *id, const char *list, const ostd::uint *body)
|
||||||
setiter(*id, listelem(start, end, qstart), stack);
|
setiter(*id, listelem(start, end, qstart), stack);
|
||||||
cs.run_int(body);
|
cs.run_int(body);
|
||||||
}
|
}
|
||||||
if (n) poparg(*id);
|
if (n) id->pop_arg();
|
||||||
}
|
}
|
||||||
COMMAND(looplist, "rse");
|
COMMAND(looplist, "rse");
|
||||||
|
|
||||||
|
@ -3653,8 +3657,8 @@ void looplist2(CsState &cs, Ident *id, Ident *id2, const char *list, const ostd:
|
||||||
cs.run_int(body);
|
cs.run_int(body);
|
||||||
}
|
}
|
||||||
if (n) {
|
if (n) {
|
||||||
poparg(*id);
|
id->pop_arg();
|
||||||
poparg(*id2);
|
id2->pop_arg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
COMMAND(looplist2, "rrse");
|
COMMAND(looplist2, "rrse");
|
||||||
|
@ -3670,9 +3674,9 @@ void looplist3(CsState &cs, Ident *id, Ident *id2, Ident *id3, const char *list,
|
||||||
cs.run_int(body);
|
cs.run_int(body);
|
||||||
}
|
}
|
||||||
if (n) {
|
if (n) {
|
||||||
poparg(*id);
|
id->pop_arg();
|
||||||
poparg(*id2);
|
id2->pop_arg();
|
||||||
poparg(*id3);
|
id3->pop_arg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
COMMAND(looplist3, "rrrse");
|
COMMAND(looplist3, "rrrse");
|
||||||
|
@ -3695,7 +3699,7 @@ void looplistconc(CsState &cs, Ident *id, const char *list, const ostd::uint *bo
|
||||||
r.push_n(vstr, len);
|
r.push_n(vstr, len);
|
||||||
v.cleanup();
|
v.cleanup();
|
||||||
}
|
}
|
||||||
if (n) poparg(*id);
|
if (n) id->pop_arg();
|
||||||
r.push('\0');
|
r.push('\0');
|
||||||
cs.result->set_str(r.disown());
|
cs.result->set_str(r.disown());
|
||||||
}
|
}
|
||||||
|
@ -3716,7 +3720,7 @@ void listfilter(CsState &cs, Ident *id, const char *list, const ostd::uint *body
|
||||||
r.push_n(qstart, qend - qstart);
|
r.push_n(qstart, qend - qstart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n) poparg(*id);
|
if (n) id->pop_arg();
|
||||||
r.push('\0');
|
r.push('\0');
|
||||||
cs.result->set_str(r.disown());
|
cs.result->set_str(r.disown());
|
||||||
}
|
}
|
||||||
|
@ -3731,7 +3735,7 @@ void listcount(CsState &cs, Ident *id, const char *list, const ostd::uint *body)
|
||||||
setiter(*id, val, stack);
|
setiter(*id, val, stack);
|
||||||
if (cs.run_bool(body)) r++;
|
if (cs.run_bool(body)) r++;
|
||||||
}
|
}
|
||||||
if (n) poparg(*id);
|
if (n) id->pop_arg();
|
||||||
cs.result->set_int(r);
|
cs.result->set_int(r);
|
||||||
}
|
}
|
||||||
COMMAND(listcount, "rse");
|
COMMAND(listcount, "rse");
|
||||||
|
@ -3862,9 +3866,9 @@ void sortlist(CsState &cs, char *list, Ident *x, Ident *y, ostd::uint *body, ost
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentStack xstack, ystack;
|
IdentStack xstack, ystack;
|
||||||
pusharg(*x, null_value, xstack);
|
x->push_arg(null_value, xstack);
|
||||||
x->flags &= ~IDF_UNKNOWN;
|
x->flags &= ~IDF_UNKNOWN;
|
||||||
pusharg(*y, null_value, ystack);
|
y->push_arg(null_value, ystack);
|
||||||
y->flags &= ~IDF_UNKNOWN;
|
y->flags &= ~IDF_UNKNOWN;
|
||||||
|
|
||||||
int totalunique = total, numunique = items.size();
|
int totalunique = total, numunique = items.size();
|
||||||
|
@ -3904,8 +3908,8 @@ void sortlist(CsState &cs, char *list, Ident *x, Ident *y, ostd::uint *body, ost
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
poparg(*x);
|
x->pop_arg();
|
||||||
poparg(*y);
|
y->pop_arg();
|
||||||
|
|
||||||
char *sorted = cstr;
|
char *sorted = cstr;
|
||||||
int sortedlen = totalunique + ostd::max(numunique - 1, 0);
|
int sortedlen = totalunique + ostd::max(numunique - 1, 0);
|
||||||
|
|
|
@ -277,6 +277,11 @@ struct Ident {
|
||||||
}
|
}
|
||||||
|
|
||||||
void clean_code();
|
void clean_code();
|
||||||
|
|
||||||
|
void push_arg(const TaggedValue &v, IdentStack &st);
|
||||||
|
void pop_arg();
|
||||||
|
void undo_arg(IdentStack &st);
|
||||||
|
void redo_arg(const IdentStack &st);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IdentLink {
|
struct IdentLink {
|
||||||
|
@ -576,9 +581,6 @@ static inline void loopiter(Ident *id, IdentStack &stack, const char *s) {
|
||||||
loopiter(id, stack, v);
|
loopiter(id, stack, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pusharg(Ident &id, const TaggedValue &v, IdentStack &stack);
|
|
||||||
void poparg(Ident &id);
|
|
||||||
|
|
||||||
#define KEYWORD(name, type) static bool __dummy_##type = addcommand(#name, (IdentFunc)nullptr, nullptr, type)
|
#define KEYWORD(name, type) static bool __dummy_##type = addcommand(#name, (IdentFunc)nullptr, nullptr, type)
|
||||||
#define COMMANDKN(name, type, fun, nargs) static bool __dummy_##fun = addcommand(#name, (IdentFunc)fun, nargs, type)
|
#define COMMANDKN(name, type, fun, nargs) static bool __dummy_##fun = addcommand(#name, (IdentFunc)fun, nargs, type)
|
||||||
#define COMMANDK(name, type, nargs) COMMANDKN(name, type, name, nargs)
|
#define COMMANDK(name, type, nargs) COMMANDKN(name, type, name, nargs)
|
||||||
|
|
Loading…
Reference in New Issue