2016-09-07 20:57:28 +00:00
|
|
|
#include "cubescript/cubescript.hh"
|
2016-08-12 16:38:43 +00:00
|
|
|
#include "cs_vm.hh"
|
2016-08-15 01:19:59 +00:00
|
|
|
#include "cs_util.hh"
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-08-12 23:26:16 +00:00
|
|
|
#include <ostd/memory.hh>
|
2016-11-15 21:50:11 +00:00
|
|
|
#include <ostd/limits.hh>
|
2016-08-12 23:26:16 +00:00
|
|
|
|
2016-08-12 16:38:43 +00:00
|
|
|
namespace cscript {
|
|
|
|
|
2016-09-02 20:49:05 +00:00
|
|
|
struct CsCommandInternal {
|
2016-09-11 21:13:39 +00:00
|
|
|
static void call(
|
|
|
|
CsState &cs, CsCommand *c, CsValueRange args, CsValue &ret
|
|
|
|
) {
|
|
|
|
c->p_cb_cftv(cs, args, ret);
|
2016-08-17 21:04:43 +00:00
|
|
|
}
|
2016-09-02 20:49:05 +00:00
|
|
|
|
|
|
|
static bool has_cb(CsIdent *id) {
|
|
|
|
if (!id->is_command() && !id->is_special()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
CsCommand *cb = static_cast<CsCommand *>(id);
|
|
|
|
return !!cb->p_cb_cftv;
|
|
|
|
}
|
|
|
|
};
|
2016-08-17 21:04:43 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
static inline void cs_push_alias(CsIdent *id, CsIdentStack &st) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (id->is_alias() && (id->get_index() >= MaxArguments)) {
|
2016-09-06 20:57:10 +00:00
|
|
|
CsValue nv;
|
|
|
|
CsAliasInternal::push_arg(static_cast<CsAlias *>(id), nv, st);
|
2016-08-17 22:06:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
static inline void cs_pop_alias(CsIdent *id) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (id->is_alias() && (id->get_index() >= MaxArguments)) {
|
2016-09-02 20:42:10 +00:00
|
|
|
CsAliasInternal::pop_arg(static_cast<CsAlias *>(id));
|
2016-08-17 22:06:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-14 19:46:47 +00:00
|
|
|
CsStackState::CsStackState(CsState &cs, CsStackStateNode *nd, bool gap):
|
|
|
|
p_state(cs), p_node(nd), p_gap(gap)
|
2016-09-09 17:19:50 +00:00
|
|
|
{}
|
|
|
|
CsStackState::CsStackState(CsStackState &&st):
|
2016-09-14 19:46:47 +00:00
|
|
|
p_state(st.p_state), p_node(st.p_node), p_gap(st.p_gap)
|
2016-09-09 17:19:50 +00:00
|
|
|
{
|
|
|
|
st.p_node = nullptr;
|
|
|
|
st.p_gap = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsStackState::~CsStackState() {
|
2016-09-14 19:46:47 +00:00
|
|
|
ostd::Size len = 0;
|
|
|
|
for (CsStackStateNode const *nd = p_node; nd; nd = nd->next) {
|
|
|
|
++len;
|
|
|
|
}
|
2016-10-03 17:23:15 +00:00
|
|
|
p_state.p_state->destroy_array(p_node, len);
|
2016-09-09 17:19:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CsStackState &CsStackState::operator=(CsStackState &&st) {
|
|
|
|
p_node = st.p_node;
|
|
|
|
p_gap = st.p_gap;
|
|
|
|
st.p_node = nullptr;
|
|
|
|
st.p_gap = false;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsStackStateNode const *CsStackState::get() const {
|
|
|
|
return p_node;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CsStackState::gap() const {
|
|
|
|
return p_gap;
|
|
|
|
}
|
|
|
|
|
2016-09-15 19:15:54 +00:00
|
|
|
CsStackState CsErrorException::save_stack(CsState &cs) {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIvar *dalias = static_cast<CsIvar *>(cs.p_state->identmap[DbgaliasIdx]);
|
2016-09-09 17:19:50 +00:00
|
|
|
if (!dalias->get_value()) {
|
2016-09-14 19:46:47 +00:00
|
|
|
return CsStackState(cs, nullptr, !!cs.p_callstack);
|
2016-09-09 17:19:50 +00:00
|
|
|
}
|
|
|
|
int total = 0, depth = 0;
|
2016-09-10 17:54:55 +00:00
|
|
|
for (CsIdentLink *l = cs.p_callstack; l; l = l->next) {
|
2016-09-09 17:19:50 +00:00
|
|
|
total++;
|
|
|
|
}
|
2016-09-10 13:01:49 +00:00
|
|
|
if (!total) {
|
2016-09-14 19:46:47 +00:00
|
|
|
return CsStackState(cs, nullptr, false);
|
2016-09-10 13:01:49 +00:00
|
|
|
}
|
2016-10-03 17:23:15 +00:00
|
|
|
CsStackStateNode *st = cs.p_state->create_array<CsStackStateNode>(
|
2016-09-14 19:46:47 +00:00
|
|
|
ostd::min(total, dalias->get_value())
|
|
|
|
);
|
2016-09-09 17:19:50 +00:00
|
|
|
CsStackStateNode *ret = st, *nd = st;
|
|
|
|
++st;
|
2016-09-10 17:54:55 +00:00
|
|
|
for (CsIdentLink *l = cs.p_callstack; l; l = l->next) {
|
2016-09-09 17:19:50 +00:00
|
|
|
++depth;
|
|
|
|
if (depth < dalias->get_value()) {
|
|
|
|
nd->id = l->id;
|
|
|
|
nd->index = total - depth + 1;
|
2016-09-10 17:54:55 +00:00
|
|
|
if (!l->next) {
|
2016-09-09 17:19:50 +00:00
|
|
|
nd->next = nullptr;
|
|
|
|
} else {
|
|
|
|
nd->next = st;
|
|
|
|
}
|
|
|
|
nd = st++;
|
2016-09-10 17:54:55 +00:00
|
|
|
} else if (!l->next) {
|
2016-09-09 17:19:50 +00:00
|
|
|
nd->id = l->id;
|
|
|
|
nd->index = 1;
|
2016-09-10 17:54:55 +00:00
|
|
|
nd->next = nullptr;
|
2016-09-09 17:19:50 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-14 19:46:47 +00:00
|
|
|
return CsStackState(cs, ret, total > dalias->get_value());
|
2016-09-09 17:19:50 +00:00
|
|
|
}
|
|
|
|
|
2016-09-13 22:14:21 +00:00
|
|
|
ostd::ConstCharRange CsErrorException::save_msg(
|
|
|
|
CsState &cs, ostd::ConstCharRange msg
|
|
|
|
) {
|
|
|
|
if (msg.size() > sizeof(cs.p_errbuf)) {
|
|
|
|
msg = msg.slice(0, sizeof(cs.p_errbuf));
|
|
|
|
}
|
2016-09-29 19:21:21 +00:00
|
|
|
GenState *gs = cs.p_pstate;
|
|
|
|
if (gs) {
|
|
|
|
/* we can attach line number */
|
|
|
|
ostd::CharRange r(cs.p_errbuf, sizeof(cs.p_errbuf));
|
|
|
|
ostd::Ptrdiff sz = -1;
|
|
|
|
if (!gs->src_name.empty()) {
|
|
|
|
sz = ostd::format(r, "%s:%d: %s", gs->src_name, gs->current_line, msg);
|
|
|
|
} else {
|
|
|
|
sz = ostd::format(r, "%d: %s", gs->current_line, msg);
|
|
|
|
}
|
|
|
|
if (sz > 0) {
|
|
|
|
return ostd::ConstCharRange(cs.p_errbuf, sz);
|
|
|
|
}
|
|
|
|
}
|
2016-09-13 22:14:21 +00:00
|
|
|
memcpy(cs.p_errbuf, msg.data(), msg.size());
|
|
|
|
return ostd::ConstCharRange(cs.p_errbuf, msg.size());
|
|
|
|
}
|
|
|
|
|
2016-08-14 15:05:55 +00:00
|
|
|
static void bcode_ref(ostd::Uint32 *code) {
|
2016-08-17 02:57:53 +00:00
|
|
|
if (!code) {
|
|
|
|
return;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
if ((*code & CsCodeOpMask) == CsCodeStart) {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_incr(code);
|
|
|
|
return;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
switch (code[-1]&CsCodeOpMask) {
|
|
|
|
case CsCodeStart:
|
2016-08-17 02:57:53 +00:00
|
|
|
bcode_incr(&code[-1]);
|
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeOffset:
|
2016-08-17 02:57:53 +00:00
|
|
|
code -= ostd::Ptrdiff(code[-1] >> 8);
|
|
|
|
bcode_incr(code);
|
|
|
|
break;
|
2016-08-14 15:05:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bcode_unref(ostd::Uint32 *code) {
|
2016-08-17 02:57:53 +00:00
|
|
|
if (!code) {
|
|
|
|
return;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
if ((*code & CsCodeOpMask) == CsCodeStart) {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_decr(code);
|
|
|
|
return;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
switch (code[-1]&CsCodeOpMask) {
|
|
|
|
case CsCodeStart:
|
2016-08-17 02:57:53 +00:00
|
|
|
bcode_decr(&code[-1]);
|
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeOffset:
|
2016-08-17 02:57:53 +00:00
|
|
|
code -= ostd::Ptrdiff(code[-1] >> 8);
|
|
|
|
bcode_decr(code);
|
|
|
|
break;
|
2016-08-14 15:05:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef::CsBytecodeRef(CsBytecode *v): p_code(v) {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_ref(reinterpret_cast<ostd::Uint32 *>(p_code));
|
|
|
|
}
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef::CsBytecodeRef(CsBytecodeRef const &v): p_code(v.p_code) {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_ref(reinterpret_cast<ostd::Uint32 *>(p_code));
|
|
|
|
}
|
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef::~CsBytecodeRef() {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_unref(reinterpret_cast<ostd::Uint32 *>(p_code));
|
|
|
|
}
|
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef &CsBytecodeRef::operator=(CsBytecodeRef const &v) {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_unref(reinterpret_cast<ostd::Uint32 *>(p_code));
|
|
|
|
p_code = v.p_code;
|
|
|
|
bcode_ref(reinterpret_cast<ostd::Uint32 *>(p_code));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef &CsBytecodeRef::operator=(CsBytecodeRef &&v) {
|
2016-08-14 15:05:55 +00:00
|
|
|
bcode_unref(reinterpret_cast<ostd::Uint32 *>(p_code));
|
|
|
|
p_code = v.p_code;
|
|
|
|
v.p_code = nullptr;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
static inline ostd::Uint32 *forcecode(CsState &cs, CsValue &v) {
|
|
|
|
ostd::Uint32 *code = reinterpret_cast<ostd::Uint32 *>(v.get_code());
|
|
|
|
if (!code) {
|
2016-08-12 17:31:34 +00:00
|
|
|
GenState gs(cs);
|
|
|
|
gs.code.reserve(64);
|
|
|
|
gs.gen_main(v.get_str());
|
2016-09-29 19:21:21 +00:00
|
|
|
gs.done();
|
2016-09-18 17:31:19 +00:00
|
|
|
v.set_code(reinterpret_cast<CsBytecode *>(gs.code.release() + 1));
|
2016-08-30 20:29:09 +00:00
|
|
|
code = reinterpret_cast<ostd::Uint32 *>(v.get_code());
|
2016-08-12 17:31:34 +00:00
|
|
|
}
|
2016-08-30 20:29:09 +00:00
|
|
|
return code;
|
2016-08-12 17:31:34 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
static inline void forcecond(CsState &cs, CsValue &v) {
|
2016-08-12 17:31:34 +00:00
|
|
|
switch (v.get_type()) {
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsValueType::String:
|
|
|
|
case CsValueType::Macro:
|
|
|
|
case CsValueType::Cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
if (!v.get_strr().empty()) {
|
2016-08-17 02:57:53 +00:00
|
|
|
forcecode(cs, v);
|
|
|
|
} else {
|
|
|
|
v.set_int(0);
|
|
|
|
}
|
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2016-08-12 17:31:34 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
static ostd::Uint32 emptyblock[CsValAny][2] = {
|
|
|
|
{ CsCodeStart + 0x100, CsCodeExit | CsRetNull },
|
|
|
|
{ CsCodeStart + 0x100, CsCodeExit | CsRetInt },
|
|
|
|
{ CsCodeStart + 0x100, CsCodeExit | CsRetFloat },
|
|
|
|
{ CsCodeStart + 0x100, CsCodeExit | CsRetString }
|
2016-08-12 16:38:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
static inline void force_arg(CsValue &v, int type) {
|
2016-08-12 16:38:43 +00:00
|
|
|
switch (type) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsRetString:
|
2016-09-07 17:42:12 +00:00
|
|
|
if (v.get_type() != CsValueType::String) {
|
2016-08-17 02:57:53 +00:00
|
|
|
v.force_str();
|
|
|
|
}
|
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsRetInt:
|
2016-09-07 17:42:12 +00:00
|
|
|
if (v.get_type() != CsValueType::Int) {
|
2016-08-17 02:57:53 +00:00
|
|
|
v.force_int();
|
|
|
|
}
|
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsRetFloat:
|
2016-09-07 17:42:12 +00:00
|
|
|
if (v.get_type() != CsValueType::Float) {
|
2016-08-17 02:57:53 +00:00
|
|
|
v.force_float();
|
|
|
|
}
|
|
|
|
break;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-15 18:55:58 +00:00
|
|
|
static ostd::Uint32 *skipcode(ostd::Uint32 *code) {
|
2016-08-12 16:38:43 +00:00
|
|
|
int depth = 0;
|
|
|
|
for (;;) {
|
|
|
|
ostd::Uint32 op = *code++;
|
|
|
|
switch (op & 0xFF) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeMacro:
|
|
|
|
case CsCodeVal | CsRetString: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
code += len / sizeof(ostd::Uint32) + 1;
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeBlock:
|
|
|
|
case CsCodeJump:
|
2016-09-15 00:02:54 +00:00
|
|
|
case CsCodeJumpB | CsCodeFlagTrue:
|
|
|
|
case CsCodeJumpB | CsCodeFlagFalse:
|
|
|
|
case CsCodeJumpResult | CsCodeFlagTrue:
|
|
|
|
case CsCodeJumpResult | CsCodeFlagFalse: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
code += len;
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEnter:
|
|
|
|
case CsCodeEnterResult:
|
2016-08-17 02:57:53 +00:00
|
|
|
++depth;
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeExit | CsRetNull:
|
|
|
|
case CsCodeExit | CsRetString:
|
|
|
|
case CsCodeExit | CsRetInt:
|
|
|
|
case CsCodeExit | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (depth <= 0) {
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
--depth;
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-06 18:06:49 +00:00
|
|
|
CsBytecode *cs_copy_code(CsBytecode *c) {
|
|
|
|
ostd::Uint32 *bcode = reinterpret_cast<ostd::Uint32 *>(c);
|
|
|
|
ostd::Uint32 *end = skipcode(bcode);
|
|
|
|
ostd::Uint32 *dst = new ostd::Uint32[end - bcode + 1];
|
2016-09-07 18:20:36 +00:00
|
|
|
*dst++ = CsCodeStart;
|
2016-09-06 18:06:49 +00:00
|
|
|
memcpy(dst, bcode, (end - bcode) * sizeof(ostd::Uint32));
|
|
|
|
return reinterpret_cast<CsBytecode *>(dst);
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 02:57:53 +00:00
|
|
|
static inline void callcommand(
|
2016-09-02 16:20:53 +00:00
|
|
|
CsState &cs, CsCommand *id, CsValue *args, CsValue &res, int numargs,
|
2016-08-17 02:57:53 +00:00
|
|
|
bool lookup = false
|
|
|
|
) {
|
2016-08-12 16:38:43 +00:00
|
|
|
int i = -1, fakeargs = 0;
|
|
|
|
bool rep = false;
|
2016-09-02 16:20:53 +00:00
|
|
|
for (auto fmt = id->get_args(); !fmt.empty(); ++fmt) {
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (*fmt) {
|
|
|
|
case 'i':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_int(0);
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
args[i].force_int();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
2016-11-15 21:50:11 +00:00
|
|
|
args[i].set_int(ostd::NumericLimitMin<CsInt>);
|
2016-08-17 02:57:53 +00:00
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
args[i].force_int();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_float(0.0f);
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
args[i].force_float();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_float(args[i - 1].get_float());
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
args[i].force_float();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_str("");
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
args[i].force_str();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_cstr("");
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
args[i].force_str();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'T':
|
|
|
|
case 't':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_null();
|
|
|
|
fakeargs++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'E':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_null();
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
forcecond(cs, args[i]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
args[i].set_code(
|
2016-09-07 18:20:36 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(emptyblock[CsValNull] + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
forcecode(cs, args[i]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
if (++i >= numargs) {
|
|
|
|
if (rep) {
|
|
|
|
break;
|
|
|
|
}
|
2016-09-12 18:04:59 +00:00
|
|
|
args[i].set_ident(cs.p_state->identmap[DummyIdx]);
|
2016-08-17 02:57:53 +00:00
|
|
|
fakeargs++;
|
|
|
|
} else {
|
|
|
|
cs.force_ident(args[i]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '$':
|
2016-09-06 18:48:24 +00:00
|
|
|
i += 1;
|
2016-08-17 02:57:53 +00:00
|
|
|
args[i].set_ident(id);
|
|
|
|
break;
|
|
|
|
case 'N':
|
2016-09-06 18:48:24 +00:00
|
|
|
i += 1;
|
2016-08-17 02:57:53 +00:00
|
|
|
args[i].set_int(CsInt(lookup ? -1 : i - fakeargs));
|
|
|
|
break;
|
|
|
|
case 'C': {
|
|
|
|
i = ostd::max(i + 1, numargs);
|
2016-08-21 00:34:03 +00:00
|
|
|
auto buf = ostd::appender<CsString>();
|
2016-08-17 02:57:53 +00:00
|
|
|
cscript::util::tvals_concat(buf, ostd::iter(args, i), " ");
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue tv;
|
2016-09-06 20:57:10 +00:00
|
|
|
tv.set_str(ostd::move(buf.get()));
|
2016-09-11 21:13:39 +00:00
|
|
|
CsCommandInternal::call(cs, id, CsValueRange(&tv, 1), res);
|
2016-09-06 21:54:28 +00:00
|
|
|
return;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
case 'V':
|
|
|
|
i = ostd::max(i + 1, numargs);
|
2016-09-11 21:13:39 +00:00
|
|
|
CsCommandInternal::call(cs, id, ostd::iter(args, i), res);
|
2016-09-06 21:54:28 +00:00
|
|
|
return;
|
2016-08-17 02:57:53 +00:00
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
|
|
|
if (i + 1 < numargs) {
|
|
|
|
fmt -= *fmt - '0' + 1;
|
|
|
|
rep = true;
|
|
|
|
}
|
|
|
|
break;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
++i;
|
2016-09-11 21:13:39 +00:00
|
|
|
CsCommandInternal::call(cs, id, CsValueRange(args, i), res);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result);
|
2016-08-17 02:57:53 +00:00
|
|
|
|
|
|
|
static inline void cs_call_alias(
|
2016-08-29 17:17:11 +00:00
|
|
|
CsState &cs, CsAlias *a, CsValue *args, CsValue &result,
|
2016-08-17 02:57:53 +00:00
|
|
|
int callargs, int &nargs, int offset, int skip, ostd::Uint32 op
|
|
|
|
) {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIvar *anargs = static_cast<CsIvar *>(cs.p_state->identmap[NumargsIdx]);
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentStack argstack[MaxArguments];
|
2016-08-17 02:57:53 +00:00
|
|
|
for(int i = 0; i < callargs; i++) {
|
2016-09-02 20:42:10 +00:00
|
|
|
CsAliasInternal::push_arg(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsAlias *>(cs.p_state->identmap[i]),
|
2016-08-17 22:06:39 +00:00
|
|
|
args[offset + i], argstack[i], false
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-24 17:54:24 +00:00
|
|
|
int oldargs = anargs->get_value();
|
|
|
|
anargs->set_value(callargs);
|
2016-08-17 02:57:53 +00:00
|
|
|
int oldflags = cs.identflags;
|
2016-09-07 18:20:36 +00:00
|
|
|
cs.identflags |= a->get_flags()&CsIdfOverridden;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentLink aliaslink = {
|
2016-09-08 19:30:08 +00:00
|
|
|
a, cs.p_callstack, (1<<callargs)-1, argstack
|
2016-08-17 02:57:53 +00:00
|
|
|
};
|
2016-09-08 19:30:08 +00:00
|
|
|
cs.p_callstack = &aliaslink;
|
2016-09-02 20:42:10 +00:00
|
|
|
ostd::Uint32 *codep = reinterpret_cast<ostd::Uint32 *>(
|
|
|
|
CsAliasInternal::compile_code(a, cs)
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
bcode_incr(codep);
|
2016-09-08 21:42:14 +00:00
|
|
|
cs_do_and_cleanup([&]() {
|
|
|
|
runcode(cs, codep+1, result);
|
|
|
|
}, [&]() {
|
|
|
|
bcode_decr(codep);
|
|
|
|
cs.p_callstack = aliaslink.next;
|
|
|
|
cs.identflags = oldflags;
|
|
|
|
for (int i = 0; i < callargs; i++) {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsAliasInternal::pop_arg(
|
|
|
|
static_cast<CsAlias *>(cs.p_state->identmap[i])
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-08 21:42:14 +00:00
|
|
|
int argmask = aliaslink.usedargs & (~0 << callargs);
|
|
|
|
for (; argmask; ++callargs) {
|
|
|
|
if (argmask & (1 << callargs)) {
|
|
|
|
CsAliasInternal::pop_arg(static_cast<CsAlias *>(
|
2016-09-12 18:04:59 +00:00
|
|
|
cs.p_state->identmap[callargs])
|
2016-09-08 21:42:14 +00:00
|
|
|
);
|
|
|
|
argmask &= ~(1 << callargs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
force_arg(result, op & CsCodeRetMask);
|
|
|
|
anargs->set_value(oldargs);
|
|
|
|
nargs = offset - skip;
|
|
|
|
});
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static constexpr int MaxRunDepth = 255;
|
|
|
|
static thread_local int rundepth = 0;
|
|
|
|
|
2016-09-23 19:04:52 +00:00
|
|
|
struct RunDepthRef {
|
|
|
|
RunDepthRef() = delete;
|
|
|
|
RunDepthRef(CsState &cs) {
|
|
|
|
if (rundepth >= MaxRunDepth) {
|
|
|
|
throw CsErrorException(cs, "exceeded recursion limit");
|
|
|
|
}
|
|
|
|
++rundepth;
|
|
|
|
}
|
|
|
|
RunDepthRef(RunDepthRef const &) = delete;
|
|
|
|
RunDepthRef(RunDepthRef &&) = delete;
|
|
|
|
~RunDepthRef() { --rundepth; }
|
|
|
|
};
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
static inline CsAlias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIdent *id = cs.p_state->identmap[op >> 8];
|
2016-09-07 18:20:36 +00:00
|
|
|
if (id->get_flags() & CsIdfUnknown) {
|
2016-09-15 18:55:58 +00:00
|
|
|
throw CsErrorException(cs, "unknown alias lookup: %s", id->get_name());
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsAlias *>(id);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
static inline CsAlias *cs_get_lookuparg_id(CsState &cs, ostd::Uint32 op) {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIdent *id = cs.p_state->identmap[op >> 8];
|
2016-09-10 17:54:55 +00:00
|
|
|
if (!cs_is_arg_used(cs, id)) {
|
2016-08-17 02:57:53 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsAlias *>(id);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int cs_get_lookupu_type(
|
2016-08-29 17:17:11 +00:00
|
|
|
CsState &cs, CsValue &arg, CsIdent *&id, ostd::Uint32 op
|
2016-08-17 02:57:53 +00:00
|
|
|
) {
|
|
|
|
if (
|
2016-09-07 17:42:12 +00:00
|
|
|
arg.get_type() != CsValueType::String &&
|
|
|
|
arg.get_type() != CsValueType::Macro &&
|
|
|
|
arg.get_type() != CsValueType::Cstring
|
2016-08-17 02:57:53 +00:00
|
|
|
) {
|
|
|
|
return -2; /* default case */
|
|
|
|
}
|
2016-08-30 20:55:35 +00:00
|
|
|
id = cs.get_ident(arg.get_strr());
|
2016-08-17 02:57:53 +00:00
|
|
|
if (id) {
|
2016-08-18 01:53:51 +00:00
|
|
|
switch(id->get_type()) {
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Alias:
|
2016-09-07 18:20:36 +00:00
|
|
|
if (id->get_flags() & CsIdfUnknown) {
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-09-10 17:54:55 +00:00
|
|
|
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
return CsIdUnknown;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
return CsIdAlias;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Svar:
|
2016-09-07 18:20:36 +00:00
|
|
|
return CsIdSvar;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Ivar:
|
2016-09-07 18:20:36 +00:00
|
|
|
return CsIdIvar;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Fvar:
|
2016-09-07 18:20:36 +00:00
|
|
|
return CsIdFvar;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Command: {
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_null();
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue buf[MaxArguments];
|
2016-09-02 16:20:53 +00:00
|
|
|
callcommand(cs, static_cast<CsCommand *>(id), buf, arg, 0, true);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(arg, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
return -2; /* ignore */
|
|
|
|
}
|
|
|
|
default:
|
2016-09-07 18:20:36 +00:00
|
|
|
return CsIdUnknown;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
}
|
2016-09-15 18:55:58 +00:00
|
|
|
throw CsErrorException(cs, "unknown alias lookup: %s", arg.get_strr());
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
|
2016-08-12 16:38:43 +00:00
|
|
|
result.set_null();
|
2016-09-23 19:04:52 +00:00
|
|
|
RunDepthRef level{cs}; /* incr and decr on scope exit */
|
2016-08-12 16:38:43 +00:00
|
|
|
int numargs = 0;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue args[MaxArguments + MaxResults];
|
2016-09-05 19:34:48 +00:00
|
|
|
auto &chook = cs.get_call_hook();
|
|
|
|
if (chook) {
|
2016-09-11 21:13:39 +00:00
|
|
|
chook(cs);
|
2016-09-05 19:34:48 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
for (;;) {
|
|
|
|
ostd::Uint32 op = *code++;
|
|
|
|
switch (op & 0xFF) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeStart:
|
|
|
|
case CsCodeOffset:
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNull | CsRetNull:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_null();
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNull | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_str("");
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNull | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_int(0);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNull | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_float(0.0f);
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFalse | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_str("0");
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFalse | CsRetNull:
|
|
|
|
case CsCodeFalse | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_int(0);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFalse | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_float(0.0f);
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeTrue | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_str("1");
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeTrue | CsRetNull:
|
|
|
|
case CsCodeTrue | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_int(1);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeTrue | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
result.set_float(1.0f);
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNot | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
--numargs;
|
|
|
|
result.set_str(args[numargs].get_bool() ? "0" : "1");
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNot | CsRetNull:
|
|
|
|
case CsCodeNot | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
--numargs;
|
|
|
|
result.set_int(!args[numargs].get_bool());
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeNot | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
--numargs;
|
|
|
|
result.set_float(CsFloat(!args[numargs].get_bool()));
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodePop:
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs -= 1;
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEnter:
|
2016-08-17 02:57:53 +00:00
|
|
|
code = runcode(cs, code, args[numargs++]);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEnterResult:
|
2016-08-17 02:57:53 +00:00
|
|
|
code = runcode(cs, code, result);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeExit | CsRetString:
|
|
|
|
case CsCodeExit | CsRetInt:
|
|
|
|
case CsCodeExit | CsRetFloat:
|
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
/* fallthrough */
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeExit | CsRetNull:
|
2016-09-23 19:06:44 +00:00
|
|
|
return code;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeResultArg | CsRetString:
|
|
|
|
case CsCodeResultArg | CsRetInt:
|
|
|
|
case CsCodeResultArg | CsRetFloat:
|
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
/* fallthrough */
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeResultArg | CsRetNull:
|
2016-09-06 20:57:10 +00:00
|
|
|
args[numargs++] = ostd::move(result);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodePrint:
|
2016-09-12 18:04:59 +00:00
|
|
|
cs.print_var(static_cast<CsVar *>(cs.p_state->identmap[op >> 8]));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLocal: {
|
2016-08-17 02:57:53 +00:00
|
|
|
int numlocals = op >> 8, offset = numargs - numlocals;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentStack locals[MaxArguments];
|
2016-08-17 02:57:53 +00:00
|
|
|
for (int i = 0; i < numlocals; ++i) {
|
2016-08-30 20:29:09 +00:00
|
|
|
cs_push_alias(args[offset + i].get_ident(), locals[i]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-08 21:42:14 +00:00
|
|
|
cs_do_and_cleanup([&]() {
|
|
|
|
code = runcode(cs, code, result);
|
|
|
|
}, [&]() {
|
|
|
|
for (int i = offset; i < numargs; i++) {
|
|
|
|
cs_pop_alias(args[i].get_ident());
|
|
|
|
}
|
|
|
|
});
|
2016-09-23 19:06:44 +00:00
|
|
|
return code;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeDoArgs | CsRetNull:
|
|
|
|
case CsCodeDoArgs | CsRetString:
|
|
|
|
case CsCodeDoArgs | CsRetInt:
|
|
|
|
case CsCodeDoArgs | CsRetFloat:
|
2016-09-10 17:54:55 +00:00
|
|
|
cs_do_args(cs, [&]() {
|
|
|
|
cs.run(args[--numargs].get_code(), result);
|
|
|
|
force_arg(result, op & CsCodeRetMask);
|
|
|
|
});
|
|
|
|
continue;
|
2016-08-17 02:57:53 +00:00
|
|
|
/* fallthrough */
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeDo | CsRetNull:
|
|
|
|
case CsCodeDo | CsRetString:
|
|
|
|
case CsCodeDo | CsRetInt:
|
|
|
|
case CsCodeDo | CsRetFloat:
|
2016-09-07 16:58:56 +00:00
|
|
|
cs.run(args[--numargs].get_code(), result);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeJump: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
code += len;
|
2016-08-12 16:38:43 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-09-15 00:02:54 +00:00
|
|
|
case CsCodeJumpB | CsCodeFlagTrue: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
if (args[--numargs].get_bool()) {
|
|
|
|
code += len;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-15 00:02:54 +00:00
|
|
|
case CsCodeJumpB | CsCodeFlagFalse: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
if (!args[--numargs].get_bool()) {
|
|
|
|
code += len;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-15 00:02:54 +00:00
|
|
|
case CsCodeJumpResult | CsCodeFlagTrue: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
--numargs;
|
2016-09-07 17:42:12 +00:00
|
|
|
if (args[numargs].get_type() == CsValueType::Code) {
|
2016-09-07 16:58:56 +00:00
|
|
|
cs.run(args[numargs].get_code(), result);
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-09-06 20:57:10 +00:00
|
|
|
result = ostd::move(args[numargs]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
if (result.get_bool()) {
|
|
|
|
code += len;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-15 00:02:54 +00:00
|
|
|
case CsCodeJumpResult | CsCodeFlagFalse: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
--numargs;
|
2016-09-07 17:42:12 +00:00
|
|
|
if (args[numargs].get_type() == CsValueType::Code) {
|
2016-09-07 16:58:56 +00:00
|
|
|
cs.run(args[numargs].get_code(), result);
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-09-06 20:57:10 +00:00
|
|
|
result = ostd::move(args[numargs]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
if (!result.get_bool()) {
|
|
|
|
code += len;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-15 00:12:22 +00:00
|
|
|
case CsCodeBreak | CsCodeFlagFalse:
|
|
|
|
if (cs.is_in_loop()) {
|
|
|
|
throw CsBreakException();
|
|
|
|
} else {
|
|
|
|
throw CsErrorException(cs, "no loop to break");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CsCodeBreak | CsCodeFlagTrue:
|
|
|
|
if (cs.is_in_loop()) {
|
|
|
|
throw CsContinueException();
|
|
|
|
} else {
|
|
|
|
throw CsErrorException(cs, "no loop to continue");
|
|
|
|
}
|
|
|
|
break;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeMacro: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
2016-08-30 20:29:09 +00:00
|
|
|
args[numargs++].set_macro(ostd::ConstCharRange(
|
|
|
|
reinterpret_cast<char const *>(code), len
|
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
code += len / sizeof(ostd::Uint32) + 1;
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeVal | CsRetString: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
args[numargs++].set_str(ostd::ConstCharRange(
|
|
|
|
reinterpret_cast<char const *>(code), len
|
|
|
|
));
|
|
|
|
code += len / sizeof(ostd::Uint32) + 1;
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeValInt | CsRetString: {
|
2016-08-17 02:57:53 +00:00
|
|
|
char s[4] = {
|
|
|
|
char((op >> 8) & 0xFF),
|
|
|
|
char((op >> 16) & 0xFF),
|
|
|
|
char((op >> 24) & 0xFF), '\0'
|
|
|
|
};
|
2016-09-10 13:31:13 +00:00
|
|
|
/* gotta cast or r.size() == potentially 3 */
|
|
|
|
args[numargs++].set_str(static_cast<char const *>(s));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeVal | CsRetNull:
|
|
|
|
case CsCodeValInt | CsRetNull:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_null();
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeVal | CsRetInt:
|
2016-09-09 15:43:23 +00:00
|
|
|
args[numargs++].set_int(
|
|
|
|
*reinterpret_cast<CsInt const *>(code)
|
|
|
|
);
|
|
|
|
code += CsTypeStorageSize<CsInt>;
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeValInt | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_int(CsInt(op) >> 8);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeVal | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_float(
|
2016-09-09 15:43:23 +00:00
|
|
|
*reinterpret_cast<CsFloat const *>(code)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-09-09 15:43:23 +00:00
|
|
|
code += CsTypeStorageSize<CsFloat>;
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeValInt | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_float(CsFloat(CsInt(op) >> 8));
|
|
|
|
continue;
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeDup | CsRetNull:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs - 1].get_val(args[numargs]);
|
|
|
|
numargs++;
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeDup | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs].set_int(args[numargs - 1].get_int());
|
|
|
|
numargs++;
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeDup | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs].set_float(args[numargs - 1].get_float());
|
|
|
|
numargs++;
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeDup | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs].set_str(ostd::move(args[numargs - 1].get_str()));
|
|
|
|
numargs++;
|
|
|
|
continue;
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeForce | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs - 1].force_str();
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeForce | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs - 1].force_int();
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeForce | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs - 1].force_float();
|
|
|
|
continue;
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeResult | CsRetNull:
|
2016-09-06 20:57:10 +00:00
|
|
|
result = ostd::move(args[--numargs]);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeResult | CsRetString:
|
|
|
|
case CsCodeResult | CsRetInt:
|
|
|
|
case CsCodeResult | CsRetFloat:
|
2016-09-06 20:57:10 +00:00
|
|
|
result = ostd::move(args[--numargs]);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEmpty | CsRetNull:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_code(
|
2016-09-07 18:20:36 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(emptyblock[CsValNull] + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-08-12 16:38:43 +00:00
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEmpty | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_code(
|
2016-09-07 18:20:36 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(emptyblock[CsValString] + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-08-12 16:38:43 +00:00
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEmpty | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_code(
|
2016-09-07 18:20:36 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(emptyblock[CsValInt] + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-08-12 16:38:43 +00:00
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeEmpty | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_code(
|
2016-09-07 18:20:36 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(emptyblock[CsValFloat] + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-08-12 16:38:43 +00:00
|
|
|
break;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeBlock: {
|
2016-08-17 02:57:53 +00:00
|
|
|
ostd::Uint32 len = op >> 8;
|
|
|
|
args[numargs++].set_code(
|
2016-08-30 20:29:09 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(code + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
code += len;
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeCompile: {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
GenState gs(cs);
|
|
|
|
switch (arg.get_type()) {
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsValueType::Int:
|
2016-08-17 02:57:53 +00:00
|
|
|
gs.code.reserve(8);
|
2016-09-07 18:20:36 +00:00
|
|
|
gs.code.push(CsCodeStart);
|
2016-08-30 20:55:35 +00:00
|
|
|
gs.gen_int(arg.get_int());
|
2016-09-07 18:20:36 +00:00
|
|
|
gs.code.push(CsCodeResult);
|
|
|
|
gs.code.push(CsCodeExit);
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsValueType::Float:
|
2016-08-17 02:57:53 +00:00
|
|
|
gs.code.reserve(8);
|
2016-09-07 18:20:36 +00:00
|
|
|
gs.code.push(CsCodeStart);
|
2016-08-30 20:55:35 +00:00
|
|
|
gs.gen_float(arg.get_float());
|
2016-09-07 18:20:36 +00:00
|
|
|
gs.code.push(CsCodeResult);
|
|
|
|
gs.code.push(CsCodeExit);
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsValueType::String:
|
|
|
|
case CsValueType::Macro:
|
|
|
|
case CsValueType::Cstring:
|
2016-08-17 02:57:53 +00:00
|
|
|
gs.code.reserve(64);
|
2016-08-30 20:55:35 +00:00
|
|
|
gs.gen_main(arg.get_strr());
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
gs.code.reserve(8);
|
2016-09-07 18:20:36 +00:00
|
|
|
gs.code.push(CsCodeStart);
|
2016-08-17 02:57:53 +00:00
|
|
|
gs.gen_null();
|
2016-09-07 18:20:36 +00:00
|
|
|
gs.code.push(CsCodeResult);
|
|
|
|
gs.code.push(CsCodeExit);
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-09-29 19:21:21 +00:00
|
|
|
gs.done();
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_code(
|
2016-09-18 17:31:19 +00:00
|
|
|
reinterpret_cast<CsBytecode *>(gs.code.release() + 1)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeCond: {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (arg.get_type()) {
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsValueType::String:
|
|
|
|
case CsValueType::Macro:
|
|
|
|
case CsValueType::Cstring: {
|
2016-08-30 20:55:35 +00:00
|
|
|
ostd::ConstCharRange s = arg.get_strr();
|
|
|
|
if (!s.empty()) {
|
2016-08-17 02:57:53 +00:00
|
|
|
GenState gs(cs);
|
|
|
|
gs.code.reserve(64);
|
2016-08-30 20:55:35 +00:00
|
|
|
gs.gen_main(s);
|
2016-09-29 19:21:21 +00:00
|
|
|
gs.done();
|
2016-08-30 20:29:09 +00:00
|
|
|
arg.set_code(reinterpret_cast<CsBytecode *>(
|
2016-09-18 17:31:19 +00:00
|
|
|
gs.code.release() + 1
|
2016-08-17 02:57:53 +00:00
|
|
|
));
|
|
|
|
} else {
|
|
|
|
arg.force_null();
|
|
|
|
}
|
|
|
|
break;
|
2016-08-30 20:55:35 +00:00
|
|
|
}
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIdent:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_ident(cs.p_state->identmap[op >> 8]);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIdentArg: {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsAlias *a = static_cast<CsAlias *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
);
|
2016-09-10 17:54:55 +00:00
|
|
|
if (!cs_is_arg_used(cs, a)) {
|
2016-09-06 20:57:10 +00:00
|
|
|
CsValue nv;
|
2016-09-02 20:42:10 +00:00
|
|
|
CsAliasInternal::push_arg(
|
2016-09-08 19:30:08 +00:00
|
|
|
a, nv, cs.p_callstack->argstack[a->get_index()], false
|
2016-08-18 01:53:51 +00:00
|
|
|
);
|
2016-09-08 19:30:08 +00:00
|
|
|
cs.p_callstack->usedargs |= 1 << a->get_index();
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-17 22:06:39 +00:00
|
|
|
args[numargs++].set_ident(a);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIdentU: {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIdent *id = cs.p_state->identmap[DummyIdx];
|
2016-08-17 02:57:53 +00:00
|
|
|
if (
|
2016-09-07 17:42:12 +00:00
|
|
|
arg.get_type() == CsValueType::String ||
|
|
|
|
arg.get_type() == CsValueType::Macro ||
|
|
|
|
arg.get_type() == CsValueType::Cstring
|
2016-08-17 02:57:53 +00:00
|
|
|
) {
|
2016-08-30 20:55:35 +00:00
|
|
|
id = cs.new_ident(arg.get_strr());
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-10 17:54:55 +00:00
|
|
|
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
|
2016-09-06 20:57:10 +00:00
|
|
|
CsValue nv;
|
2016-09-02 20:42:10 +00:00
|
|
|
CsAliasInternal::push_arg(
|
2016-09-06 20:57:10 +00:00
|
|
|
static_cast<CsAlias *>(id), nv,
|
2016-09-08 19:30:08 +00:00
|
|
|
cs.p_callstack->argstack[id->get_index()], false
|
2016-08-17 22:06:39 +00:00
|
|
|
);
|
2016-09-08 19:30:08 +00:00
|
|
|
cs.p_callstack->usedargs |= 1 << id->get_index();
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
arg.set_ident(id);
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupU | CsRetString: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = nullptr;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias:
|
2016-08-17 22:18:36 +00:00
|
|
|
arg.set_str(ostd::move(
|
2016-08-31 18:18:53 +00:00
|
|
|
static_cast<CsAlias *>(id)->get_value().get_str()
|
2016-08-17 22:18:36 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_str(static_cast<CsSvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_str(ostd::move(
|
2016-08-29 17:17:11 +00:00
|
|
|
intstr(static_cast<CsIvar *>(id)->get_value())
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_str(ostd::move(
|
2016-08-29 17:17:11 +00:00
|
|
|
floatstr(static_cast<CsFvar *>(id)->get_value())
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdUnknown:
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_str("");
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookup | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_str(
|
2016-08-31 18:18:53 +00:00
|
|
|
ostd::move(cs_get_lookup_id(cs, op)->get_value().get_str())
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupArg | CsRetString: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = cs_get_lookuparg_id(cs, op);
|
2016-08-17 22:18:36 +00:00
|
|
|
if (!a) {
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_str("");
|
|
|
|
} else {
|
2016-08-31 18:18:53 +00:00
|
|
|
args[numargs++].set_str(
|
|
|
|
ostd::move(a->get_value().get_str())
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupU | CsRetInt: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = nullptr;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias:
|
2016-08-31 18:18:53 +00:00
|
|
|
arg.set_int(
|
|
|
|
static_cast<CsAlias *>(id)->get_value().get_int()
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_int(cs_parse_int(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsSvar *>(id)->get_value()
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_int(static_cast<CsIvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-18 02:14:55 +00:00
|
|
|
arg.set_int(
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt(static_cast<CsFvar *>(id)->get_value())
|
2016-08-18 02:14:55 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdUnknown:
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_int(0);
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookup | CsRetInt:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_int(
|
2016-08-31 18:18:53 +00:00
|
|
|
cs_get_lookup_id(cs, op)->get_value().get_int()
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupArg | CsRetInt: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = cs_get_lookuparg_id(cs, op);
|
2016-08-17 22:18:36 +00:00
|
|
|
if (!a) {
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_int(0);
|
|
|
|
} else {
|
2016-08-31 18:18:53 +00:00
|
|
|
args[numargs++].set_int(a->get_value().get_int());
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupU | CsRetFloat: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = nullptr;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias:
|
2016-08-17 23:53:14 +00:00
|
|
|
arg.set_float(
|
2016-08-31 18:18:53 +00:00
|
|
|
static_cast<CsAlias *>(id)->get_value().get_float()
|
2016-08-17 23:53:14 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_float(cs_parse_float(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsSvar *>(id)->get_value()
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_float(CsFloat(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsIvar *>(id)->get_value()
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-18 02:14:55 +00:00
|
|
|
arg.set_float(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsFvar *>(id)->get_value()
|
2016-08-18 02:14:55 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdUnknown:
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_float(CsFloat(0));
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookup | CsRetFloat:
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_float(
|
2016-08-31 18:18:53 +00:00
|
|
|
cs_get_lookup_id(cs, op)->get_value().get_float()
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupArg | CsRetFloat: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = cs_get_lookuparg_id(cs, op);
|
2016-08-17 22:18:36 +00:00
|
|
|
if (!a) {
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_float(CsFloat(0));
|
|
|
|
} else {
|
2016-08-31 18:18:53 +00:00
|
|
|
args[numargs++].set_float(a->get_value().get_float());
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupU | CsRetNull: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = nullptr;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias:
|
2016-08-31 18:18:53 +00:00
|
|
|
static_cast<CsAlias *>(id)->get_value().get_val(arg);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_str(static_cast<CsSvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_int(static_cast<CsIvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-18 02:14:55 +00:00
|
|
|
arg.set_float(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsFvar *>(id)->get_value()
|
2016-08-18 02:14:55 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdUnknown:
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_null();
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookup | CsRetNull:
|
2016-08-31 18:18:53 +00:00
|
|
|
cs_get_lookup_id(cs, op)->get_value().get_val(args[numargs++]);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupArg | CsRetNull: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = cs_get_lookuparg_id(cs, op);
|
2016-08-17 22:18:36 +00:00
|
|
|
if (!a) {
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_null();
|
|
|
|
} else {
|
2016-08-31 18:18:53 +00:00
|
|
|
a->get_value().get_val(args[numargs++]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupMu | CsRetString: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = nullptr;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias:
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsAlias *>(id)->get_cstr(arg);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_cstr(static_cast<CsSvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_str(ostd::move(
|
2016-08-29 17:17:11 +00:00
|
|
|
intstr(static_cast<CsIvar *>(id)->get_value())
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-17 22:36:37 +00:00
|
|
|
arg.set_str(ostd::move(
|
2016-08-29 17:17:11 +00:00
|
|
|
floatstr(static_cast<CsFvar *>(id)->get_value())
|
2016-08-17 22:36:37 +00:00
|
|
|
));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdUnknown:
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_cstr("");
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupM | CsRetString:
|
2016-08-17 02:57:53 +00:00
|
|
|
cs_get_lookup_id(cs, op)->get_cstr(args[numargs++]);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupMarg | CsRetString: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = cs_get_lookuparg_id(cs, op);
|
2016-08-17 22:18:36 +00:00
|
|
|
if (!a) {
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_cstr("");
|
|
|
|
} else {
|
2016-08-17 22:18:36 +00:00
|
|
|
a->get_cstr(args[numargs++]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupMu | CsRetNull: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = nullptr;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &arg = args[numargs - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias:
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsAlias *>(id)->get_cval(arg);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_cstr(static_cast<CsSvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_int(static_cast<CsIvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-29 17:17:11 +00:00
|
|
|
arg.set_float(static_cast<CsFvar *>(id)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdUnknown:
|
2016-08-17 02:57:53 +00:00
|
|
|
arg.set_null();
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupM | CsRetNull:
|
2016-08-17 02:57:53 +00:00
|
|
|
cs_get_lookup_id(cs, op)->get_cval(args[numargs++]);
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeLookupMarg | CsRetNull: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = cs_get_lookuparg_id(cs, op);
|
2016-08-17 22:18:36 +00:00
|
|
|
if (!a) {
|
2016-08-17 02:57:53 +00:00
|
|
|
args[numargs++].set_null();
|
|
|
|
} else {
|
2016-08-17 22:18:36 +00:00
|
|
|
a->get_cval(args[numargs++]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeSvar | CsRetString:
|
|
|
|
case CsCodeSvar | CsRetNull:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_str(static_cast<CsSvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeSvar | CsRetInt:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_int(cs_parse_int(static_cast<CsSvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value()));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeSvar | CsRetFloat:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_float(cs_parse_float(static_cast<CsSvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value()));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeSvarM:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_cstr(static_cast<CsSvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeSvar1:
|
2016-08-17 21:29:31 +00:00
|
|
|
cs.set_var_str_checked(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsSvar *>(cs.p_state->identmap[op >> 8]),
|
2016-08-30 20:55:35 +00:00
|
|
|
args[--numargs].get_strr()
|
2016-08-17 21:29:31 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIvar | CsRetInt:
|
|
|
|
case CsCodeIvar | CsRetNull:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_int(static_cast<CsIvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIvar | CsRetString:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_str(ostd::move(intstr(static_cast<CsIvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value())));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIvar | CsRetFloat:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_float(CsFloat(static_cast<CsIvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value()));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIvar1:
|
2016-08-17 21:29:31 +00:00
|
|
|
cs.set_var_int_checked(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsIvar *>(cs.p_state->identmap[op >> 8]),
|
2016-08-30 20:55:35 +00:00
|
|
|
args[--numargs].get_int()
|
2016-08-17 21:29:31 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIvar2:
|
2016-08-17 02:57:53 +00:00
|
|
|
numargs -= 2;
|
|
|
|
cs.set_var_int_checked(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsIvar *>(cs.p_state->identmap[op >> 8]),
|
2016-08-30 20:55:35 +00:00
|
|
|
(args[numargs].get_int() << 16)
|
|
|
|
| (args[numargs + 1].get_int() << 8)
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeIvar3:
|
2016-08-17 02:57:53 +00:00
|
|
|
numargs -= 3;
|
|
|
|
cs.set_var_int_checked(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsIvar *>(cs.p_state->identmap[op >> 8]),
|
2016-08-30 20:55:35 +00:00
|
|
|
(args[numargs].get_int() << 16)
|
|
|
|
| (args[numargs + 1].get_int() << 8)
|
|
|
|
| (args[numargs + 2].get_int()));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFvar | CsRetFloat:
|
|
|
|
case CsCodeFvar | CsRetNull:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_float(static_cast<CsFvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value());
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFvar | CsRetString:
|
2016-08-17 22:36:37 +00:00
|
|
|
args[numargs++].set_str(ostd::move(floatstr(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsFvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value()
|
2016-08-17 22:36:37 +00:00
|
|
|
)));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFvar | CsRetInt:
|
2016-09-12 18:04:59 +00:00
|
|
|
args[numargs++].set_int(int(static_cast<CsFvar *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
)->get_value()));
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeFvar1:
|
2016-08-17 21:29:31 +00:00
|
|
|
cs.set_var_float_checked(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsFvar *>(cs.p_state->identmap[op >> 8]),
|
2016-08-30 20:55:35 +00:00
|
|
|
args[--numargs].get_float()
|
2016-08-17 21:29:31 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeCom | CsRetNull:
|
|
|
|
case CsCodeCom | CsRetString:
|
|
|
|
case CsCodeCom | CsRetFloat:
|
|
|
|
case CsCodeCom | CsRetInt: {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsCommand *id = static_cast<CsCommand *>(
|
|
|
|
cs.p_state->identmap[op >> 8]
|
|
|
|
);
|
2016-09-02 16:20:53 +00:00
|
|
|
int offset = numargs - id->get_num_args();
|
2016-08-17 02:57:53 +00:00
|
|
|
result.force_null();
|
2016-09-02 20:49:05 +00:00
|
|
|
CsCommandInternal::call(
|
2016-09-11 21:13:39 +00:00
|
|
|
cs, id, CsValueRange(args + offset, id->get_num_args()),
|
|
|
|
result
|
2016-09-02 16:20:53 +00:00
|
|
|
);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset;
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeComV | CsRetNull:
|
|
|
|
case CsCodeComV | CsRetString:
|
|
|
|
case CsCodeComV | CsRetFloat:
|
|
|
|
case CsCodeComV | CsRetInt: {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsCommand *id = static_cast<CsCommand *>(
|
|
|
|
cs.p_state->identmap[op >> 13]
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
|
|
|
result.force_null();
|
2016-09-02 20:49:05 +00:00
|
|
|
CsCommandInternal::call(
|
2016-09-11 21:13:39 +00:00
|
|
|
cs, id, ostd::iter(&args[offset], callargs), result
|
2016-09-02 19:27:37 +00:00
|
|
|
);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset;
|
2016-08-12 16:38:43 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeComC | CsRetNull:
|
|
|
|
case CsCodeComC | CsRetString:
|
|
|
|
case CsCodeComC | CsRetFloat:
|
|
|
|
case CsCodeComC | CsRetInt: {
|
2016-09-12 18:04:59 +00:00
|
|
|
CsCommand *id = static_cast<CsCommand *>(
|
|
|
|
cs.p_state->identmap[op >> 13]
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
2016-08-12 16:38:43 +00:00
|
|
|
result.force_null();
|
2016-08-17 02:57:53 +00:00
|
|
|
{
|
2016-08-21 00:34:03 +00:00
|
|
|
auto buf = ostd::appender<CsString>();
|
2016-08-17 02:57:53 +00:00
|
|
|
cscript::util::tvals_concat(
|
|
|
|
buf, ostd::iter(&args[offset], callargs), " "
|
|
|
|
);
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue tv;
|
2016-09-06 20:57:10 +00:00
|
|
|
tv.set_str(ostd::move(buf.get()));
|
2016-09-11 21:13:39 +00:00
|
|
|
CsCommandInternal::call(cs, id, CsValueRange(&tv, 1), result);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset;
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeConc | CsRetNull:
|
|
|
|
case CsCodeConc | CsRetString:
|
|
|
|
case CsCodeConc | CsRetFloat:
|
|
|
|
case CsCodeConc | CsRetInt:
|
|
|
|
case CsCodeConcW | CsRetNull:
|
|
|
|
case CsCodeConcW | CsRetString:
|
|
|
|
case CsCodeConcW | CsRetFloat:
|
|
|
|
case CsCodeConcW | CsRetInt: {
|
2016-08-17 02:57:53 +00:00
|
|
|
int numconc = op >> 8;
|
2016-08-21 00:34:03 +00:00
|
|
|
auto buf = ostd::appender<CsString>();
|
2016-08-17 02:57:53 +00:00
|
|
|
cscript::util::tvals_concat(
|
|
|
|
buf, ostd::iter(&args[numargs - numconc], numconc),
|
2016-09-07 18:20:36 +00:00
|
|
|
((op & CsCodeOpMask) == CsCodeConc) ? " " : ""
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = numargs - numconc;
|
2016-09-06 20:57:10 +00:00
|
|
|
args[numargs].set_str(ostd::move(buf.get()));
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(args[numargs], op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
numargs++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeConcM | CsRetNull:
|
|
|
|
case CsCodeConcM | CsRetString:
|
|
|
|
case CsCodeConcM | CsRetFloat:
|
|
|
|
case CsCodeConcM | CsRetInt: {
|
2016-08-17 02:57:53 +00:00
|
|
|
int numconc = op >> 8;
|
2016-08-21 00:34:03 +00:00
|
|
|
auto buf = ostd::appender<CsString>();
|
2016-08-17 02:57:53 +00:00
|
|
|
cscript::util::tvals_concat(
|
|
|
|
buf, ostd::iter(&args[numargs - numconc], numconc)
|
|
|
|
);
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = numargs - numconc;
|
2016-09-06 20:57:10 +00:00
|
|
|
result.set_str(ostd::move(buf.get()));
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-12 16:38:43 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeAlias:
|
2016-09-02 20:42:10 +00:00
|
|
|
CsAliasInternal::set_alias(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsAlias *>(cs.p_state->identmap[op >> 8]),
|
2016-08-17 22:06:39 +00:00
|
|
|
cs, args[--numargs]
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeAliasArg:
|
2016-09-02 20:42:10 +00:00
|
|
|
CsAliasInternal::set_arg(
|
2016-09-12 18:04:59 +00:00
|
|
|
static_cast<CsAlias *>(cs.p_state->identmap[op >> 8]),
|
2016-08-17 22:06:39 +00:00
|
|
|
cs, args[--numargs]
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeAliasU:
|
2016-08-17 02:57:53 +00:00
|
|
|
numargs -= 2;
|
2016-09-06 20:57:10 +00:00
|
|
|
cs.set_alias(
|
|
|
|
args[numargs].get_str(), ostd::move(args[numargs + 1])
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeCall | CsRetNull:
|
|
|
|
case CsCodeCall | CsRetString:
|
|
|
|
case CsCodeCall | CsRetFloat:
|
|
|
|
case CsCodeCall | CsRetInt: {
|
2016-08-17 02:57:53 +00:00
|
|
|
result.force_null();
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIdent *id = cs.p_state->identmap[op >> 13];
|
2016-08-17 02:57:53 +00:00
|
|
|
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
2016-09-07 18:20:36 +00:00
|
|
|
if (id->get_flags() & CsIdfUnknown) {
|
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-09-15 18:55:58 +00:00
|
|
|
throw CsErrorException(
|
|
|
|
cs, "unknown command: %s", id->get_name()
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
cs_call_alias(
|
2016-08-29 17:17:11 +00:00
|
|
|
cs, static_cast<CsAlias *>(id), args, result, callargs,
|
2016-08-17 22:06:39 +00:00
|
|
|
numargs, offset, 0, op
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
2016-08-12 16:38:43 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeCallArg | CsRetNull:
|
|
|
|
case CsCodeCallArg | CsRetString:
|
|
|
|
case CsCodeCallArg | CsRetFloat:
|
|
|
|
case CsCodeCallArg | CsRetInt: {
|
2016-08-17 02:57:53 +00:00
|
|
|
result.force_null();
|
2016-09-12 18:04:59 +00:00
|
|
|
CsIdent *id = cs.p_state->identmap[op >> 13];
|
2016-08-17 02:57:53 +00:00
|
|
|
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
2016-09-10 17:54:55 +00:00
|
|
|
if (!cs_is_arg_used(cs, id)) {
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset;
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
cs_call_alias(
|
2016-08-29 17:17:11 +00:00
|
|
|
cs, static_cast<CsAlias *>(id), args, result, callargs,
|
2016-08-17 22:06:39 +00:00
|
|
|
numargs, offset, 0, op
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsCodeCallU | CsRetNull:
|
|
|
|
case CsCodeCallU | CsRetString:
|
|
|
|
case CsCodeCallU | CsRetFloat:
|
|
|
|
case CsCodeCallU | CsRetInt: {
|
2016-08-17 02:57:53 +00:00
|
|
|
int callargs = op >> 8, offset = numargs - callargs;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue &idarg = args[offset - 1];
|
2016-08-17 02:57:53 +00:00
|
|
|
if (
|
2016-09-07 17:42:12 +00:00
|
|
|
idarg.get_type() != CsValueType::String &&
|
|
|
|
idarg.get_type() != CsValueType::Macro &&
|
|
|
|
idarg.get_type() != CsValueType::Cstring
|
2016-08-17 02:57:53 +00:00
|
|
|
) {
|
|
|
|
litval:
|
2016-09-06 20:57:10 +00:00
|
|
|
result = ostd::move(idarg);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset - 1;
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-08-30 20:55:35 +00:00
|
|
|
CsIdent *id = cs.get_ident(idarg.get_strr());
|
2016-08-17 02:57:53 +00:00
|
|
|
if (!id) {
|
|
|
|
noid:
|
2016-08-30 20:55:35 +00:00
|
|
|
if (cs_check_num(idarg.get_strr())) {
|
2016-08-17 02:57:53 +00:00
|
|
|
goto litval;
|
|
|
|
}
|
|
|
|
result.force_null();
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-09-15 18:55:58 +00:00
|
|
|
throw CsErrorException(
|
|
|
|
cs, "unknown command: %s", idarg.get_strr()
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
result.force_null();
|
2016-08-18 01:53:51 +00:00
|
|
|
switch (id->get_type_raw()) {
|
2016-08-17 02:57:53 +00:00
|
|
|
default:
|
2016-09-02 20:49:05 +00:00
|
|
|
if (!CsCommandInternal::has_cb(id)) {
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset - 1;
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* fallthrough */
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdCommand:
|
2016-08-17 21:04:43 +00:00
|
|
|
callcommand(
|
2016-09-02 16:20:53 +00:00
|
|
|
cs, static_cast<CsCommand *>(id), &args[offset],
|
2016-08-17 21:04:43 +00:00
|
|
|
result, callargs
|
|
|
|
);
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
numargs = offset - 1;
|
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdLocal: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentStack locals[MaxArguments];
|
2016-08-17 02:57:53 +00:00
|
|
|
for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) {
|
2016-08-17 22:06:39 +00:00
|
|
|
cs_push_alias(cs.force_ident(
|
2016-08-17 02:57:53 +00:00
|
|
|
args[offset + j]
|
2016-08-17 22:06:39 +00:00
|
|
|
), locals[j]);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-08 21:42:14 +00:00
|
|
|
cs_do_and_cleanup([&]() {
|
|
|
|
code = runcode(cs, code, result);
|
|
|
|
}, [&]() {
|
|
|
|
for (ostd::Size j = 0; j < ostd::Size(callargs); ++j) {
|
|
|
|
cs_pop_alias(args[offset + j].get_ident());
|
|
|
|
}
|
|
|
|
});
|
2016-09-23 19:06:44 +00:00
|
|
|
return code;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdIvar:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (callargs <= 0) {
|
2016-09-15 19:59:11 +00:00
|
|
|
cs.print_var(static_cast<CsVar *>(id));
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
|
|
|
cs.set_var_int_checked(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsIvar *>(id),
|
2016-08-17 21:29:31 +00:00
|
|
|
ostd::iter(&args[offset], callargs)
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset - 1;
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdFvar:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (callargs <= 0) {
|
2016-09-15 19:59:11 +00:00
|
|
|
cs.print_var(static_cast<CsVar *>(id));
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
|
|
|
cs.set_var_float_checked(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsFvar *>(id),
|
2016-08-17 21:29:31 +00:00
|
|
|
args[offset].force_float()
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset - 1;
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdSvar:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (callargs <= 0) {
|
2016-09-15 19:59:11 +00:00
|
|
|
cs.print_var(static_cast<CsVar *>(id));
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-08-17 21:29:31 +00:00
|
|
|
cs.set_var_str_checked(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsSvar *>(id),
|
2016-08-17 21:29:31 +00:00
|
|
|
args[offset].force_str()
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset - 1;
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
2016-09-07 18:20:36 +00:00
|
|
|
case CsIdAlias: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = static_cast<CsAlias *>(id);
|
2016-08-17 02:57:53 +00:00
|
|
|
if (
|
2016-09-10 17:54:55 +00:00
|
|
|
(a->get_index() < MaxArguments) &&
|
|
|
|
!cs_is_arg_used(cs, a)
|
2016-08-17 02:57:53 +00:00
|
|
|
) {
|
2016-09-06 21:54:28 +00:00
|
|
|
numargs = offset - 1;
|
2016-09-07 18:20:36 +00:00
|
|
|
force_arg(result, op & CsCodeRetMask);
|
2016-08-17 02:57:53 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-09-07 17:42:12 +00:00
|
|
|
if (a->get_value().get_type() == CsValueType::Null) {
|
2016-08-17 02:57:53 +00:00
|
|
|
goto noid;
|
|
|
|
}
|
|
|
|
cs_call_alias(
|
2016-08-17 22:06:39 +00:00
|
|
|
cs, a, args, result, callargs, numargs,
|
2016-08-17 02:57:53 +00:00
|
|
|
offset, 1, op
|
|
|
|
);
|
|
|
|
continue;
|
2016-08-17 22:06:39 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
2016-09-07 16:58:56 +00:00
|
|
|
void CsState::run(CsBytecode *code, CsValue &ret) {
|
2016-08-30 20:29:09 +00:00
|
|
|
runcode(*this, reinterpret_cast<ostd::Uint32 *>(code), ret);
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-10 14:06:01 +00:00
|
|
|
static void cs_run(
|
|
|
|
CsState &cs, ostd::ConstCharRange file, ostd::ConstCharRange code,
|
|
|
|
CsValue &ret
|
|
|
|
) {
|
|
|
|
GenState gs(cs);
|
2016-09-21 23:44:35 +00:00
|
|
|
gs.src_name = file;
|
2016-08-12 16:38:43 +00:00
|
|
|
gs.code.reserve(64);
|
2016-09-29 19:21:21 +00:00
|
|
|
gs.gen_main(code, CsValAny);
|
|
|
|
gs.done();
|
2016-09-10 14:06:01 +00:00
|
|
|
runcode(cs, gs.code.data() + 1, ret);
|
2016-08-17 02:57:53 +00:00
|
|
|
if (int(gs.code[0]) >= 0x100) {
|
2016-09-18 17:31:19 +00:00
|
|
|
gs.code.release();
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-09-10 14:06:01 +00:00
|
|
|
void CsState::run(ostd::ConstCharRange code, CsValue &ret) {
|
|
|
|
cs_run(*this, ostd::ConstCharRange(), code, ret);
|
|
|
|
}
|
|
|
|
|
2016-09-07 16:58:56 +00:00
|
|
|
void CsState::run(CsIdent *id, CsValueRange args, CsValue &ret) {
|
2016-08-12 16:38:43 +00:00
|
|
|
int nargs = int(args.size());
|
|
|
|
ret.set_null();
|
2016-09-23 19:04:52 +00:00
|
|
|
RunDepthRef level{*this}; /* incr and decr on scope exit */
|
|
|
|
if (id) {
|
2016-08-18 01:53:51 +00:00
|
|
|
switch (id->get_type()) {
|
2016-08-17 02:57:53 +00:00
|
|
|
default:
|
2016-09-02 20:49:05 +00:00
|
|
|
if (!CsCommandInternal::has_cb(id)) {
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fallthrough */
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Command:
|
2016-09-02 16:20:53 +00:00
|
|
|
if (nargs < static_cast<CsCommand *>(id)->get_num_args()) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue buf[MaxArguments];
|
|
|
|
memcpy(buf, args.data(), args.size() * sizeof(CsValue));
|
2016-08-17 21:04:43 +00:00
|
|
|
callcommand(
|
2016-09-02 16:20:53 +00:00
|
|
|
*this, static_cast<CsCommand *>(id), buf, ret,
|
2016-08-17 21:04:43 +00:00
|
|
|
nargs, false
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-08-17 21:04:43 +00:00
|
|
|
callcommand(
|
2016-09-02 16:20:53 +00:00
|
|
|
*this, static_cast<CsCommand *>(id), args.data(),
|
2016-08-17 21:04:43 +00:00
|
|
|
ret, nargs, false
|
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
nargs = 0;
|
|
|
|
break;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Ivar:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (args.empty()) {
|
2016-09-15 19:59:11 +00:00
|
|
|
print_var(static_cast<CsVar *>(id));
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-08-29 17:17:11 +00:00
|
|
|
set_var_int_checked(static_cast<CsIvar *>(id), args);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Fvar:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (args.empty()) {
|
2016-09-15 19:59:11 +00:00
|
|
|
print_var(static_cast<CsVar *>(id));
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-08-17 21:29:31 +00:00
|
|
|
set_var_float_checked(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsFvar *>(id), args[0].force_float()
|
2016-08-17 21:29:31 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Svar:
|
2016-08-17 02:57:53 +00:00
|
|
|
if (args.empty()) {
|
2016-09-15 19:59:11 +00:00
|
|
|
print_var(static_cast<CsVar *>(id));
|
2016-08-17 02:57:53 +00:00
|
|
|
} else {
|
2016-08-17 21:29:31 +00:00
|
|
|
set_var_str_checked(
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsSvar *>(id), args[0].force_str()
|
2016-08-17 21:29:31 +00:00
|
|
|
);
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
|
|
|
break;
|
2016-09-07 17:42:12 +00:00
|
|
|
case CsIdentType::Alias: {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = static_cast<CsAlias *>(id);
|
2016-09-10 17:54:55 +00:00
|
|
|
if (
|
|
|
|
(a->get_index() < MaxArguments) && !cs_is_arg_used(*this, a)
|
|
|
|
) {
|
|
|
|
break;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-09-07 17:42:12 +00:00
|
|
|
if (a->get_value().get_type() == CsValueType::Null) {
|
2016-08-17 02:57:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
cs_call_alias(
|
2016-09-07 18:20:36 +00:00
|
|
|
*this, a, args.data(), ret, nargs, nargs, 0, 0, CsRetNull
|
2016-08-17 02:57:53 +00:00
|
|
|
);
|
|
|
|
break;
|
2016-08-17 22:06:39 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
CsString CsState::run_str(CsBytecode *code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_str();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString CsState::run_str(ostd::ConstCharRange code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_str();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsString CsState::run_str(CsIdent *id, CsValueRange args) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(id, args, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_str();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
CsInt CsState::run_int(CsBytecode *code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_int();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt CsState::run_int(ostd::ConstCharRange code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_int();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt CsState::run_int(CsIdent *id, CsValueRange args) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(id, args, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_int();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
CsFloat CsState::run_float(CsBytecode *code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_float();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
CsFloat CsState::run_float(ostd::ConstCharRange code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_float();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFloat CsState::run_float(CsIdent *id, CsValueRange args) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(id, args, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_float();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
bool CsState::run_bool(CsBytecode *code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_bool();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CsState::run_bool(ostd::ConstCharRange code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_bool();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsState::run_bool(CsIdent *id, CsValueRange args) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(id, args, ret);
|
2016-09-06 21:59:24 +00:00
|
|
|
return ret.get_bool();
|
2016-08-12 16:38:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
void CsState::run(CsBytecode *code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsState::run(ostd::ConstCharRange code) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(code, ret);
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::run(CsIdent *id, CsValueRange args) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-09-07 16:58:56 +00:00
|
|
|
run(id, args, ret);
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
2016-09-14 21:24:13 +00:00
|
|
|
CsLoopState CsState::run_loop(CsBytecode *code, CsValue &ret) {
|
|
|
|
++p_inloop;
|
|
|
|
try {
|
|
|
|
run(code, ret);
|
|
|
|
} catch (CsBreakException) {
|
|
|
|
--p_inloop;
|
|
|
|
return CsLoopState::Break;
|
|
|
|
} catch (CsContinueException) {
|
|
|
|
--p_inloop;
|
|
|
|
return CsLoopState::Continue;
|
|
|
|
} catch (...) {
|
|
|
|
--p_inloop;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
return CsLoopState::Normal;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsLoopState CsState::run_loop(CsBytecode *code) {
|
|
|
|
CsValue ret;
|
|
|
|
return run_loop(code, ret);
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:34:24 +00:00
|
|
|
static bool cs_run_file(
|
2016-08-18 18:38:30 +00:00
|
|
|
CsState &cs, ostd::ConstCharRange fname, CsValue &ret
|
2016-08-18 18:34:24 +00:00
|
|
|
) {
|
2016-08-12 23:26:16 +00:00
|
|
|
ostd::Box<char[]> buf;
|
2016-08-12 16:38:43 +00:00
|
|
|
ostd::Size len;
|
|
|
|
|
|
|
|
ostd::FileStream f(fname, ostd::StreamMode::read);
|
2016-08-17 02:57:53 +00:00
|
|
|
if (!f.is_open()) {
|
2016-08-12 16:38:43 +00:00
|
|
|
return false;
|
2016-08-17 02:57:53 +00:00
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
|
|
|
|
len = f.size();
|
2016-08-12 23:26:16 +00:00
|
|
|
buf = ostd::make_box<char[]>(len + 1);
|
|
|
|
if (!buf || f.get(buf.get(), len) != len) {
|
2016-08-12 16:38:43 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
buf[len] = '\0';
|
|
|
|
|
2016-09-10 14:06:01 +00:00
|
|
|
cs_run(cs, fname, ostd::ConstCharRange(buf.get(), len), ret);
|
2016-08-18 18:34:24 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString> CsState::run_file_str(ostd::ConstCharRange fname) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-08-18 18:34:24 +00:00
|
|
|
if (!cs_run_file(*this, fname, ret)) {
|
|
|
|
return ostd::nothing;
|
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
return ostd::move(ret.get_str());
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ostd::Maybe<CsInt> CsState::run_file_int(ostd::ConstCharRange fname) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-08-18 18:34:24 +00:00
|
|
|
if (!cs_run_file(*this, fname, ret)) {
|
|
|
|
return ostd::nothing;
|
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
return ret.get_int();
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ostd::Maybe<CsFloat> CsState::run_file_float(ostd::ConstCharRange fname) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-08-18 18:34:24 +00:00
|
|
|
if (!cs_run_file(*this, fname, ret)) {
|
|
|
|
return ostd::nothing;
|
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
return ret.get_float();
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ostd::Maybe<bool> CsState::run_file_bool(ostd::ConstCharRange fname) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-08-18 18:34:24 +00:00
|
|
|
if (!cs_run_file(*this, fname, ret)) {
|
|
|
|
return ostd::nothing;
|
|
|
|
}
|
2016-09-06 21:54:28 +00:00
|
|
|
return ret.get_bool();
|
2016-08-18 18:34:24 +00:00
|
|
|
}
|
|
|
|
|
2016-09-07 16:58:56 +00:00
|
|
|
bool CsState::run_file(ostd::ConstCharRange fname, CsValue &ret) {
|
2016-08-18 18:34:24 +00:00
|
|
|
return cs_run_file(*this, fname, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CsState::run_file(ostd::ConstCharRange fname) {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue ret;
|
2016-08-18 18:34:24 +00:00
|
|
|
if (!cs_run_file(*this, fname, ret)) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-12 16:38:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
} /* namespace cscript */
|