separate ident and error impls into their own files
parent
f9a49ffba7
commit
702dca0809
|
@ -0,0 +1,84 @@
|
|||
#include <cubescript/cubescript.hh>
|
||||
|
||||
#include "cs_util.hh"
|
||||
#include "cs_vm.hh"
|
||||
|
||||
namespace cscript {
|
||||
|
||||
LIBCUBESCRIPT_EXPORT char *cs_error::request_buf(
|
||||
cs_state &cs, std::size_t bufs, char *&sp
|
||||
) {
|
||||
cs_charbuf &cb = *static_cast<cs_charbuf *>(cs.p_errbuf);
|
||||
cs_gen_state *gs = cs.p_pstate;
|
||||
cb.clear();
|
||||
std::size_t sz = 0;
|
||||
if (gs) {
|
||||
/* we can attach line number */
|
||||
sz = gs->src_name.size() + 32;
|
||||
for (;;) {
|
||||
/* we are using so the buffer tracks the elements and therefore
|
||||
* does not wipe them when we attempt to reserve more capacity
|
||||
*/
|
||||
cb.resize(sz);
|
||||
int nsz;
|
||||
if (!gs->src_name.empty()) {
|
||||
nsz = std::snprintf(
|
||||
cb.data(), sz, "%.*s:%zu: ",
|
||||
int(gs->src_name.size()), gs->src_name.data(),
|
||||
gs->current_line
|
||||
);
|
||||
} else {
|
||||
nsz = std::snprintf(cb.data(), sz, "%zu: ", gs->current_line);
|
||||
}
|
||||
if (nsz <= 0) {
|
||||
throw cs_internal_error{"format error"};
|
||||
} else if (std::size_t(nsz) < sz) {
|
||||
sz = std::size_t(nsz);
|
||||
break;
|
||||
}
|
||||
sz = std::size_t(nsz + 1);
|
||||
}
|
||||
}
|
||||
cb.resize(sz + bufs + 1);
|
||||
sp = cb.data();
|
||||
return &cb[sz];
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT cs_stack_state cs_error::save_stack(cs_state &cs) {
|
||||
cs_ivar *dalias = static_cast<cs_ivar *>(cs.p_state->identmap[DbgaliasIdx]);
|
||||
if (!dalias->get_value()) {
|
||||
return cs_stack_state(cs, nullptr, !!cs.p_callstack);
|
||||
}
|
||||
int total = 0, depth = 0;
|
||||
for (cs_ident_link *l = cs.p_callstack; l; l = l->next) {
|
||||
total++;
|
||||
}
|
||||
if (!total) {
|
||||
return cs_stack_state(cs, nullptr, false);
|
||||
}
|
||||
cs_stack_state_node *st = cs.p_state->create_array<cs_stack_state_node>(
|
||||
std::min(total, dalias->get_value())
|
||||
);
|
||||
cs_stack_state_node *ret = st, *nd = st;
|
||||
++st;
|
||||
for (cs_ident_link *l = cs.p_callstack; l; l = l->next) {
|
||||
++depth;
|
||||
if (depth < dalias->get_value()) {
|
||||
nd->id = l->id;
|
||||
nd->index = total - depth + 1;
|
||||
if (!l->next) {
|
||||
nd->next = nullptr;
|
||||
} else {
|
||||
nd->next = st;
|
||||
}
|
||||
nd = st++;
|
||||
} else if (!l->next) {
|
||||
nd->id = l->id;
|
||||
nd->index = 1;
|
||||
nd->next = nullptr;
|
||||
}
|
||||
}
|
||||
return cs_stack_state(cs, ret, total > dalias->get_value());
|
||||
}
|
||||
|
||||
} /* namespace cscript */
|
|
@ -1162,7 +1162,7 @@ static void compile_and_or(
|
|||
}
|
||||
if (!more) {
|
||||
gs.code.push_back(
|
||||
((id->get_raw_type() == CsIdAnd)
|
||||
((id->get_raw_type() == ID_AND)
|
||||
? CS_CODE_TRUE : CS_CODE_FALSE) | cs_ret_code(rettype)
|
||||
);
|
||||
} else {
|
||||
|
@ -1194,7 +1194,7 @@ static void compile_and_or(
|
|||
(numargs << 8) | (id->get_index() << 13)
|
||||
);
|
||||
} else {
|
||||
uint32_t op = (id->get_raw_type() == CsIdAnd)
|
||||
uint32_t op = (id->get_raw_type() == ID_AND)
|
||||
? (CS_CODE_JUMP_RESULT | CS_CODE_FLAG_FALSE)
|
||||
: (CS_CODE_JUMP_RESULT | CS_CODE_FLAG_TRUE);
|
||||
gs.code.push_back(op);
|
||||
|
@ -1332,36 +1332,36 @@ noid:
|
|||
gs.code.push_back(CS_CODE_RESULT);
|
||||
} else {
|
||||
switch (id->get_raw_type()) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
compile_alias(
|
||||
gs, static_cast<cs_alias *>(id), more, prevargs
|
||||
);
|
||||
break;
|
||||
case CsIdCommand:
|
||||
case ID_COMMAND:
|
||||
compile_cmd(
|
||||
gs, static_cast<cs_command_impl *>(id), more,
|
||||
rettype, prevargs
|
||||
);
|
||||
break;
|
||||
case CsIdLocal:
|
||||
case ID_LOCAL:
|
||||
compile_local(gs, more, prevargs);
|
||||
break;
|
||||
case CsIdDo:
|
||||
case ID_DO:
|
||||
compile_do(gs, more, prevargs, rettype, CS_CODE_DO);
|
||||
break;
|
||||
case CsIdDoArgs:
|
||||
case ID_DOARGS:
|
||||
compile_do(gs, more, prevargs, rettype, CS_CODE_DO_ARGS);
|
||||
break;
|
||||
case CsIdIf:
|
||||
case ID_IF:
|
||||
compile_if(gs, id, more, prevargs, rettype);
|
||||
break;
|
||||
case CsIdBreak:
|
||||
case ID_BREAK:
|
||||
gs.code.push_back(CS_CODE_BREAK | CS_CODE_FLAG_FALSE);
|
||||
break;
|
||||
case CsIdContinue:
|
||||
case ID_CONTINUE:
|
||||
gs.code.push_back(CS_CODE_BREAK | CS_CODE_FLAG_TRUE);
|
||||
break;
|
||||
case CsIdResult:
|
||||
case ID_RESULT:
|
||||
if (more) {
|
||||
more = compilearg(gs, CS_VAL_ANY, prevargs);
|
||||
}
|
||||
|
@ -1370,7 +1370,7 @@ noid:
|
|||
cs_ret_code(rettype)
|
||||
);
|
||||
break;
|
||||
case CsIdNot:
|
||||
case ID_NOT:
|
||||
if (more) {
|
||||
more = compilearg(gs, CS_VAL_ANY, prevargs);
|
||||
}
|
||||
|
@ -1378,11 +1378,11 @@ noid:
|
|||
(more ? CS_CODE_NOT : CS_CODE_TRUE) | cs_ret_code(rettype)
|
||||
);
|
||||
break;
|
||||
case CsIdAnd:
|
||||
case CsIdOr:
|
||||
case ID_AND:
|
||||
case ID_OR:
|
||||
compile_and_or(gs, id, more, prevargs, rettype);
|
||||
break;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
if (!(more = compilearg(gs, CS_VAL_INT, prevargs))) {
|
||||
gs.code.push_back(CS_CODE_PRINT | (id->get_index() << 8));
|
||||
} else if (!(id->get_flags() & CS_IDF_HEX) || !(
|
||||
|
@ -1397,14 +1397,14 @@ noid:
|
|||
gs.code.push_back(CS_CODE_IVAR3 | (id->get_index() << 8));
|
||||
}
|
||||
break;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
if (!(more = compilearg(gs, CS_VAL_FLOAT, prevargs))) {
|
||||
gs.code.push_back(CS_CODE_PRINT | (id->get_index() << 8));
|
||||
} else {
|
||||
gs.code.push_back(CS_CODE_FVAR1 | (id->get_index() << 8));
|
||||
}
|
||||
break;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
if (!(more = compilearg(gs, CS_VAL_STRING, prevargs))) {
|
||||
gs.code.push_back(CS_CODE_PRINT | (id->get_index() << 8));
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
#include "cs_ident.hh"
|
||||
|
||||
#include "cs_bcode.hh"
|
||||
#include "cs_vm.hh"
|
||||
|
||||
namespace cscript {
|
||||
|
||||
void cs_var_impl::changed(cs_state &cs) {
|
||||
if (cb_var) {
|
||||
switch (p_type) {
|
||||
case ID_IVAR:
|
||||
cb_var(cs, *static_cast<cs_ivar_impl *>(this));
|
||||
break;
|
||||
case ID_FVAR:
|
||||
cb_var(cs, *static_cast<cs_fvar_impl *>(this));
|
||||
break;
|
||||
case ID_SVAR:
|
||||
cb_var(cs, *static_cast<cs_svar_impl *>(this));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cs_alias_impl::push_arg(cs_value &v, cs_ident_stack &st, bool um) {
|
||||
if (p_astack == &st) {
|
||||
/* prevent cycles and unnecessary code elsewhere */
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
return;
|
||||
}
|
||||
st.val_s = std::move(p_val);
|
||||
st.next = p_astack;
|
||||
p_astack = &st;
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
if (um) {
|
||||
p_flags &= ~CS_IDF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void cs_alias_impl::pop_arg() {
|
||||
if (!p_astack) {
|
||||
return;
|
||||
}
|
||||
cs_ident_stack *st = p_astack;
|
||||
p_val = std::move(p_astack->val_s);
|
||||
clean_code();
|
||||
p_astack = st->next;
|
||||
}
|
||||
|
||||
void cs_alias_impl::undo_arg(cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = p_astack;
|
||||
st.val_s = std::move(p_val);
|
||||
st.next = prev;
|
||||
p_astack = prev->next;
|
||||
p_val = std::move(prev->val_s);
|
||||
clean_code();
|
||||
}
|
||||
|
||||
void cs_alias_impl::redo_arg(cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = st.next;
|
||||
prev->val_s = std::move(p_val);
|
||||
p_astack = prev;
|
||||
p_val = std::move(st.val_s);
|
||||
clean_code();
|
||||
}
|
||||
|
||||
void cs_alias_impl::set_arg(cs_state &cs, cs_value &v) {
|
||||
if (ident_is_used_arg(this, cs)) {
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
} else {
|
||||
push_arg(v, cs.p_callstack->argstack[get_index()], false);
|
||||
cs.p_callstack->usedargs |= 1 << get_index();
|
||||
}
|
||||
}
|
||||
|
||||
void cs_alias_impl::set_alias(cs_state &cs, cs_value &v) {
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
p_flags = (p_flags & cs.identflags) | cs.identflags;
|
||||
}
|
||||
|
||||
void cs_alias_impl::clean_code() {
|
||||
if (p_acode) {
|
||||
bcode_decr(p_acode->get_raw());
|
||||
p_acode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
cs_bcode *cs_alias_impl::compile_code(cs_state &cs) {
|
||||
if (!p_acode) {
|
||||
cs_gen_state gs(cs);
|
||||
gs.code.reserve(64);
|
||||
gs.gen_main(get_value().get_str());
|
||||
/* i wish i could steal the memory somehow */
|
||||
uint32_t *code = bcode_alloc(cs, gs.code.size());
|
||||
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
|
||||
bcode_incr(code);
|
||||
p_acode = reinterpret_cast<cs_bcode *>(code);
|
||||
}
|
||||
return p_acode;
|
||||
}
|
||||
|
||||
bool ident_is_used_arg(cs_ident *id, cs_state &cs) {
|
||||
if (!cs.p_callstack) {
|
||||
return true;
|
||||
}
|
||||
return cs.p_callstack->usedargs & (1 << id->get_index());
|
||||
}
|
||||
|
||||
} /* namespace cscript */
|
|
@ -0,0 +1,121 @@
|
|||
#ifndef LIBCUBESCRIPT_ALIAS_HH
|
||||
#define LIBCUBESCRIPT_ALIAS_HH
|
||||
|
||||
#include <cubescript/cubescript.hh>
|
||||
|
||||
#include "cs_util.hh"
|
||||
|
||||
namespace cscript {
|
||||
|
||||
enum {
|
||||
ID_UNKNOWN = -1, ID_IVAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_ALIAS,
|
||||
ID_LOCAL, ID_DO, ID_DOARGS, ID_IF, ID_BREAK, ID_CONTINUE, ID_RESULT,
|
||||
ID_NOT, ID_AND, ID_OR
|
||||
};
|
||||
|
||||
struct cs_ident_link {
|
||||
cs_ident *id;
|
||||
cs_ident_link *next;
|
||||
int usedargs;
|
||||
cs_ident_stack *argstack;
|
||||
};
|
||||
|
||||
struct cs_ident_impl {
|
||||
cs_ident_impl() = delete;
|
||||
cs_ident_impl(cs_ident_impl const &) = delete;
|
||||
cs_ident_impl(cs_ident_impl &&) = delete;
|
||||
|
||||
/* trigger destructors for all inherited members properly */
|
||||
virtual ~cs_ident_impl() {};
|
||||
|
||||
cs_ident_impl &operator=(cs_ident_impl const &) = delete;
|
||||
cs_ident_impl &operator=(cs_ident_impl &&) = delete;
|
||||
|
||||
cs_ident_impl(cs_ident_type tp, cs_strref name, int flags = 0);
|
||||
|
||||
cs_strref p_name;
|
||||
/* represents the cs_ident_type above, but internally it has a wider
|
||||
* variety of values, so it's an int here (maps to an internal enum)
|
||||
*/
|
||||
int p_type, p_flags;
|
||||
|
||||
int p_index = -1;
|
||||
};
|
||||
|
||||
struct cs_var_impl: cs_ident_impl {
|
||||
cs_var_impl(
|
||||
cs_ident_type tp, cs_strref name, cs_var_cb func, int flags = 0
|
||||
);
|
||||
|
||||
cs_var_cb cb_var;
|
||||
|
||||
void changed(cs_state &cs);
|
||||
};
|
||||
|
||||
struct cs_ivar_impl: cs_var_impl, cs_ivar {
|
||||
cs_ivar_impl(
|
||||
cs_strref n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
cs_int p_storage, p_minval, p_maxval, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_fvar_impl: cs_var_impl, cs_fvar {
|
||||
cs_fvar_impl(
|
||||
cs_strref n, cs_float m, cs_float x, cs_float v,
|
||||
cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
cs_float p_storage, p_minval, p_maxval, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_svar_impl: cs_var_impl, cs_svar {
|
||||
cs_svar_impl(
|
||||
cs_strref n, cs_strref v, cs_strref ov, cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
cs_strref p_storage, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_alias_impl: cs_ident_impl, cs_alias {
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_strref a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, std::string_view a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_int a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_float a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_value v, int flags);
|
||||
|
||||
void push_arg(cs_value &v, cs_ident_stack &st, bool um = true);
|
||||
void pop_arg();
|
||||
void undo_arg(cs_ident_stack &st);
|
||||
void redo_arg(cs_ident_stack &st);
|
||||
void set_arg(cs_state &cs, cs_value &v);
|
||||
void set_alias(cs_state &cs, cs_value &v);
|
||||
|
||||
void clean_code();
|
||||
cs_bcode *compile_code(cs_state &cs);
|
||||
|
||||
cs_bcode *p_acode;
|
||||
cs_ident_stack *p_astack;
|
||||
cs_value p_val;
|
||||
};
|
||||
|
||||
struct cs_command_impl: cs_ident_impl, cs_command {
|
||||
cs_command_impl(
|
||||
cs_strref name, cs_strref args, int numargs, cs_command_cb func
|
||||
);
|
||||
|
||||
void call(cs_state &cs, std::span<cs_value> args, cs_value &ret) {
|
||||
p_cb_cftv(cs, args, ret);
|
||||
}
|
||||
|
||||
cs_strref p_cargs;
|
||||
cs_command_cb p_cb_cftv;
|
||||
int p_numargs;
|
||||
};
|
||||
|
||||
bool ident_is_used_arg(cs_ident *id, cs_state &cs);
|
||||
|
||||
} /* namespace cscript */
|
||||
|
||||
#endif
|
193
src/cs_vm.cc
193
src/cs_vm.cc
|
@ -61,101 +61,6 @@ bool cs_stack_state::gap() const {
|
|||
return p_gap;
|
||||
}
|
||||
|
||||
char *cs_error::request_buf(cs_state &cs, std::size_t bufs, char *&sp) {
|
||||
cs_charbuf &cb = *static_cast<cs_charbuf *>(cs.p_errbuf);
|
||||
cs_gen_state *gs = cs.p_pstate;
|
||||
cb.clear();
|
||||
std::size_t sz = 0;
|
||||
if (gs) {
|
||||
/* we can attach line number */
|
||||
sz = gs->src_name.size() + 32;
|
||||
for (;;) {
|
||||
/* we are using so the buffer tracks the elements and therefore
|
||||
* does not wipe them when we attempt to reserve more capacity
|
||||
*/
|
||||
cb.resize(sz);
|
||||
int nsz;
|
||||
if (!gs->src_name.empty()) {
|
||||
nsz = std::snprintf(
|
||||
cb.data(), sz, "%.*s:%zu: ",
|
||||
int(gs->src_name.size()), gs->src_name.data(),
|
||||
gs->current_line
|
||||
);
|
||||
} else {
|
||||
nsz = std::snprintf(cb.data(), sz, "%zu: ", gs->current_line);
|
||||
}
|
||||
if (nsz <= 0) {
|
||||
throw cs_internal_error{"format error"};
|
||||
} else if (std::size_t(nsz) < sz) {
|
||||
sz = std::size_t(nsz);
|
||||
break;
|
||||
}
|
||||
sz = std::size_t(nsz + 1);
|
||||
}
|
||||
}
|
||||
cb.resize(sz + bufs + 1);
|
||||
sp = cb.data();
|
||||
return &cb[sz];
|
||||
}
|
||||
|
||||
cs_stack_state cs_error::save_stack(cs_state &cs) {
|
||||
cs_ivar *dalias = static_cast<cs_ivar *>(cs.p_state->identmap[DbgaliasIdx]);
|
||||
if (!dalias->get_value()) {
|
||||
return cs_stack_state(cs, nullptr, !!cs.p_callstack);
|
||||
}
|
||||
int total = 0, depth = 0;
|
||||
for (cs_ident_link *l = cs.p_callstack; l; l = l->next) {
|
||||
total++;
|
||||
}
|
||||
if (!total) {
|
||||
return cs_stack_state(cs, nullptr, false);
|
||||
}
|
||||
cs_stack_state_node *st = cs.p_state->create_array<cs_stack_state_node>(
|
||||
std::min(total, dalias->get_value())
|
||||
);
|
||||
cs_stack_state_node *ret = st, *nd = st;
|
||||
++st;
|
||||
for (cs_ident_link *l = cs.p_callstack; l; l = l->next) {
|
||||
++depth;
|
||||
if (depth < dalias->get_value()) {
|
||||
nd->id = l->id;
|
||||
nd->index = total - depth + 1;
|
||||
if (!l->next) {
|
||||
nd->next = nullptr;
|
||||
} else {
|
||||
nd->next = st;
|
||||
}
|
||||
nd = st++;
|
||||
} else if (!l->next) {
|
||||
nd->id = l->id;
|
||||
nd->index = 1;
|
||||
nd->next = nullptr;
|
||||
}
|
||||
}
|
||||
return cs_stack_state(cs, ret, total > dalias->get_value());
|
||||
}
|
||||
|
||||
void cs_alias_impl::clean_code() {
|
||||
if (p_acode) {
|
||||
bcode_decr(p_acode->get_raw());
|
||||
p_acode = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
cs_bcode *cs_alias_impl::compile_code(cs_state &cs) {
|
||||
if (!p_acode) {
|
||||
cs_gen_state gs(cs);
|
||||
gs.code.reserve(64);
|
||||
gs.gen_main(get_value().get_str());
|
||||
/* i wish i could steal the memory somehow */
|
||||
uint32_t *code = bcode_alloc(cs, gs.code.size());
|
||||
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
|
||||
bcode_incr(code);
|
||||
p_acode = reinterpret_cast<cs_bcode *>(code);
|
||||
}
|
||||
return p_acode;
|
||||
}
|
||||
|
||||
static inline uint32_t *forcecode(cs_state &cs, cs_value &v) {
|
||||
auto *code = v.get_code();
|
||||
if (!code) {
|
||||
|
@ -429,7 +334,7 @@ static inline cs_alias *cs_get_lookup_id(cs_state &cs, uint32_t op) {
|
|||
|
||||
static inline cs_alias *cs_get_lookuparg_id(cs_state &cs, uint32_t op) {
|
||||
cs_ident *id = cs.p_state->identmap[op >> 8];
|
||||
if (!cs_is_arg_used(cs, id)) {
|
||||
if (!ident_is_used_arg(id, cs)) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<cs_alias *>(id);
|
||||
|
@ -448,16 +353,16 @@ static inline int cs_get_lookupu_type(
|
|||
if (id->get_flags() & CS_IDF_UNKNOWN) {
|
||||
break;
|
||||
}
|
||||
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
|
||||
return CsIdUnknown;
|
||||
if ((id->get_index() < MaxArguments) && !ident_is_used_arg(id, cs)) {
|
||||
return ID_UNKNOWN;
|
||||
}
|
||||
return CsIdAlias;
|
||||
return ID_ALIAS;
|
||||
case cs_ident_type::SVAR:
|
||||
return CsIdSvar;
|
||||
return ID_SVAR;
|
||||
case cs_ident_type::IVAR:
|
||||
return CsIdIvar;
|
||||
return ID_IVAR;
|
||||
case cs_ident_type::FVAR:
|
||||
return CsIdFvar;
|
||||
return ID_FVAR;
|
||||
case cs_ident_type::COMMAND: {
|
||||
arg.set_none();
|
||||
cs_valarray<cs_value, MaxArguments> buf{cs};
|
||||
|
@ -469,7 +374,7 @@ static inline int cs_get_lookupu_type(
|
|||
return -2; /* ignore */
|
||||
}
|
||||
default:
|
||||
return CsIdUnknown;
|
||||
return ID_UNKNOWN;
|
||||
}
|
||||
}
|
||||
throw cs_error(cs, "unknown alias lookup: %s", arg.get_str().data());
|
||||
|
@ -841,7 +746,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_alias *a = static_cast<cs_alias *>(
|
||||
cs.p_state->identmap[op >> 8]
|
||||
);
|
||||
if (!cs_is_arg_used(cs, a)) {
|
||||
if (!ident_is_used_arg(a, cs)) {
|
||||
cs_value nv{cs};
|
||||
static_cast<cs_alias_impl *>(a)->push_arg(
|
||||
nv, cs.p_callstack->argstack[a->get_index()], false
|
||||
|
@ -857,7 +762,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
if (arg.get_type() == cs_value_type::STRING) {
|
||||
id = cs.new_ident(arg.get_str());
|
||||
}
|
||||
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
|
||||
if ((id->get_index() < MaxArguments) && !ident_is_used_arg(id, cs)) {
|
||||
cs_value nv{cs};
|
||||
static_cast<cs_alias_impl *>(id)->push_arg(
|
||||
nv, cs.p_callstack->argstack[id->get_index()], false
|
||||
|
@ -872,22 +777,22 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_ident *id = nullptr;
|
||||
cs_value &arg = args[numargs - 1];
|
||||
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
arg = static_cast<cs_alias *>(id)->get_value();
|
||||
arg.force_str();
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
arg.set_str(static_cast<cs_svar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
arg.set_int(static_cast<cs_ivar *>(id)->get_value());
|
||||
arg.force_str();
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
arg.set_float(static_cast<cs_fvar *>(id)->get_value());
|
||||
arg.force_str();
|
||||
continue;
|
||||
case CsIdUnknown:
|
||||
case ID_UNKNOWN:
|
||||
arg.set_str("");
|
||||
continue;
|
||||
default:
|
||||
|
@ -912,25 +817,25 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_ident *id = nullptr;
|
||||
cs_value &arg = args[numargs - 1];
|
||||
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
arg.set_int(
|
||||
static_cast<cs_alias *>(id)->get_value().get_int()
|
||||
);
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
arg.set_int(cs_parse_int(
|
||||
static_cast<cs_svar *>(id)->get_value()
|
||||
));
|
||||
continue;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
arg.set_int(static_cast<cs_ivar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
arg.set_int(
|
||||
cs_int(static_cast<cs_fvar *>(id)->get_value())
|
||||
);
|
||||
continue;
|
||||
case CsIdUnknown:
|
||||
case ID_UNKNOWN:
|
||||
arg.set_int(0);
|
||||
continue;
|
||||
default:
|
||||
|
@ -955,27 +860,27 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_ident *id = nullptr;
|
||||
cs_value &arg = args[numargs - 1];
|
||||
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
arg.set_float(
|
||||
static_cast<cs_alias *>(id)->get_value().get_float()
|
||||
);
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
arg.set_float(cs_parse_float(
|
||||
static_cast<cs_svar *>(id)->get_value()
|
||||
));
|
||||
continue;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
arg.set_float(cs_float(
|
||||
static_cast<cs_ivar *>(id)->get_value()
|
||||
));
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
arg.set_float(
|
||||
static_cast<cs_fvar *>(id)->get_value()
|
||||
);
|
||||
continue;
|
||||
case CsIdUnknown:
|
||||
case ID_UNKNOWN:
|
||||
arg.set_float(cs_float(0));
|
||||
continue;
|
||||
default:
|
||||
|
@ -1000,21 +905,21 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_ident *id = nullptr;
|
||||
cs_value &arg = args[numargs - 1];
|
||||
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
static_cast<cs_alias *>(id)->get_value().get_val(arg);
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
arg.set_str(static_cast<cs_svar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
arg.set_int(static_cast<cs_ivar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
arg.set_float(
|
||||
static_cast<cs_fvar *>(id)->get_value()
|
||||
);
|
||||
continue;
|
||||
case CsIdUnknown:
|
||||
case ID_UNKNOWN:
|
||||
arg.set_none();
|
||||
continue;
|
||||
default:
|
||||
|
@ -1038,22 +943,22 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_ident *id = nullptr;
|
||||
cs_value &arg = args[numargs - 1];
|
||||
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
arg = static_cast<cs_alias *>(id)->get_value();
|
||||
arg.force_str();
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
arg.set_str(static_cast<cs_svar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
arg.set_int(static_cast<cs_ivar *>(id)->get_value());
|
||||
arg.force_str();
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
arg.set_float(static_cast<cs_fvar *>(id)->get_value());
|
||||
arg.force_str();
|
||||
continue;
|
||||
case CsIdUnknown:
|
||||
case ID_UNKNOWN:
|
||||
arg.set_str("");
|
||||
continue;
|
||||
default:
|
||||
|
@ -1078,19 +983,19 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
cs_ident *id = nullptr;
|
||||
cs_value &arg = args[numargs - 1];
|
||||
switch (cs_get_lookupu_type(cs, arg, id, op)) {
|
||||
case CsIdAlias:
|
||||
case ID_ALIAS:
|
||||
static_cast<cs_alias *>(id)->get_cval(arg);
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
arg.set_str(static_cast<cs_svar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
arg.set_int(static_cast<cs_ivar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
arg.set_float(static_cast<cs_fvar *>(id)->get_value());
|
||||
continue;
|
||||
case CsIdUnknown:
|
||||
case ID_UNKNOWN:
|
||||
arg.set_none();
|
||||
continue;
|
||||
default:
|
||||
|
@ -1328,7 +1233,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
result.force_none();
|
||||
cs_ident *id = cs.p_state->identmap[op >> 13];
|
||||
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
||||
if (!cs_is_arg_used(cs, id)) {
|
||||
if (!ident_is_used_arg(id, cs)) {
|
||||
numargs = offset;
|
||||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
continue;
|
||||
|
@ -1376,7 +1281,7 @@ noid:
|
|||
continue;
|
||||
}
|
||||
/* fallthrough */
|
||||
case CsIdCommand:
|
||||
case ID_COMMAND:
|
||||
callcommand(
|
||||
cs, static_cast<cs_command_impl *>(id),
|
||||
&args[offset], result, callargs
|
||||
|
@ -1384,7 +1289,7 @@ noid:
|
|||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
numargs = offset - 1;
|
||||
continue;
|
||||
case CsIdLocal: {
|
||||
case ID_LOCAL: {
|
||||
cs_valarray<cs_ident_stack, MaxArguments> locals{cs};
|
||||
for (size_t j = 0; j < size_t(callargs); ++j) {
|
||||
cs_push_alias(cs, cs.force_ident(
|
||||
|
@ -1400,7 +1305,7 @@ noid:
|
|||
});
|
||||
return code;
|
||||
}
|
||||
case CsIdIvar:
|
||||
case ID_IVAR:
|
||||
if (callargs <= 0) {
|
||||
cs.print_var(*static_cast<cs_var *>(id));
|
||||
} else {
|
||||
|
@ -1412,7 +1317,7 @@ noid:
|
|||
numargs = offset - 1;
|
||||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
continue;
|
||||
case CsIdFvar:
|
||||
case ID_FVAR:
|
||||
if (callargs <= 0) {
|
||||
cs.print_var(*static_cast<cs_var *>(id));
|
||||
} else {
|
||||
|
@ -1424,7 +1329,7 @@ noid:
|
|||
numargs = offset - 1;
|
||||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
continue;
|
||||
case CsIdSvar:
|
||||
case ID_SVAR:
|
||||
if (callargs <= 0) {
|
||||
cs.print_var(*static_cast<cs_var *>(id));
|
||||
} else {
|
||||
|
@ -1436,11 +1341,11 @@ noid:
|
|||
numargs = offset - 1;
|
||||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
continue;
|
||||
case CsIdAlias: {
|
||||
case ID_ALIAS: {
|
||||
cs_alias *a = static_cast<cs_alias *>(id);
|
||||
if (
|
||||
(a->get_index() < MaxArguments) &&
|
||||
!cs_is_arg_used(cs, a)
|
||||
!ident_is_used_arg(a, cs)
|
||||
) {
|
||||
numargs = offset - 1;
|
||||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
|
@ -1549,7 +1454,7 @@ void cs_state::run(cs_ident *id, std::span<cs_value> args, cs_value &ret) {
|
|||
case cs_ident_type::ALIAS: {
|
||||
cs_alias *a = static_cast<cs_alias *>(id);
|
||||
if (
|
||||
(a->get_index() < MaxArguments) && !cs_is_arg_used(*this, a)
|
||||
(a->get_index() < MaxArguments) && !ident_is_used_arg(a, *this)
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
|
162
src/cs_vm.hh
162
src/cs_vm.hh
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "cs_util.hh"
|
||||
#include "cs_bcode.hh"
|
||||
#include "cs_ident.hh"
|
||||
|
||||
namespace cscript {
|
||||
|
||||
|
@ -20,167 +21,6 @@ static constexpr int DummyIdx = MaxArguments;
|
|||
static constexpr int NumargsIdx = MaxArguments + 1;
|
||||
static constexpr int DbgaliasIdx = MaxArguments + 2;
|
||||
|
||||
enum {
|
||||
CsIdUnknown = -1, CsIdIvar, CsIdFvar, CsIdSvar, CsIdCommand, CsIdAlias,
|
||||
CsIdLocal, CsIdDo, CsIdDoArgs, CsIdIf, CsIdBreak, CsIdContinue, CsIdResult,
|
||||
CsIdNot, CsIdAnd, CsIdOr
|
||||
};
|
||||
|
||||
struct cs_ident_impl {
|
||||
cs_ident_impl() = delete;
|
||||
cs_ident_impl(cs_ident_impl const &) = delete;
|
||||
cs_ident_impl(cs_ident_impl &&) = delete;
|
||||
|
||||
/* trigger destructors for all inherited members properly */
|
||||
virtual ~cs_ident_impl() {};
|
||||
|
||||
cs_ident_impl &operator=(cs_ident_impl const &) = delete;
|
||||
cs_ident_impl &operator=(cs_ident_impl &&) = delete;
|
||||
|
||||
cs_ident_impl(cs_ident_type tp, cs_strref name, int flags = 0);
|
||||
|
||||
cs_strref p_name;
|
||||
/* represents the cs_ident_type above, but internally it has a wider variety
|
||||
* of values, so it's an int here (maps to an internal enum)
|
||||
*/
|
||||
int p_type, p_flags;
|
||||
|
||||
int p_index = -1;
|
||||
};
|
||||
|
||||
struct cs_var_impl: cs_ident_impl {
|
||||
cs_var_impl(cs_ident_type tp, cs_strref name, cs_var_cb func, int flags = 0);
|
||||
|
||||
cs_var_cb cb_var;
|
||||
|
||||
void changed(cs_state &cs);
|
||||
};
|
||||
|
||||
struct cs_ivar_impl: cs_var_impl, cs_ivar {
|
||||
cs_ivar_impl(
|
||||
cs_strref n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
cs_int p_storage, p_minval, p_maxval, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_fvar_impl: cs_var_impl, cs_fvar {
|
||||
cs_fvar_impl(
|
||||
cs_strref n, cs_float m, cs_float x, cs_float v,
|
||||
cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
cs_float p_storage, p_minval, p_maxval, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_svar_impl: cs_var_impl, cs_svar {
|
||||
cs_svar_impl(cs_strref n, cs_strref v, cs_strref ov, cs_var_cb f, int flags);
|
||||
|
||||
cs_strref p_storage, p_overrideval;
|
||||
};
|
||||
|
||||
struct cs_ident_link {
|
||||
cs_ident *id;
|
||||
cs_ident_link *next;
|
||||
int usedargs;
|
||||
cs_ident_stack *argstack;
|
||||
};
|
||||
|
||||
static inline bool cs_is_arg_used(cs_state &cs, cs_ident *id) {
|
||||
if (!cs.p_callstack) {
|
||||
return true;
|
||||
}
|
||||
return cs.p_callstack->usedargs & (1 << id->get_index());
|
||||
}
|
||||
|
||||
struct cs_alias_impl: cs_ident_impl, cs_alias {
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_strref a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, std::string_view a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_int a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_float a, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, int flags);
|
||||
cs_alias_impl(cs_state &cs, cs_strref n, cs_value v, int flags);
|
||||
|
||||
void push_arg(cs_value &v, cs_ident_stack &st, bool um = true) {
|
||||
if (p_astack == &st) {
|
||||
/* prevent cycles and unnecessary code elsewhere */
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
return;
|
||||
}
|
||||
st.val_s = std::move(p_val);
|
||||
st.next = p_astack;
|
||||
p_astack = &st;
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
if (um) {
|
||||
p_flags &= ~CS_IDF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void pop_arg() {
|
||||
if (!p_astack) {
|
||||
return;
|
||||
}
|
||||
cs_ident_stack *st = p_astack;
|
||||
p_val = std::move(p_astack->val_s);
|
||||
clean_code();
|
||||
p_astack = st->next;
|
||||
}
|
||||
|
||||
void undo_arg(cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = p_astack;
|
||||
st.val_s = std::move(p_val);
|
||||
st.next = prev;
|
||||
p_astack = prev->next;
|
||||
p_val = std::move(prev->val_s);
|
||||
clean_code();
|
||||
}
|
||||
|
||||
void redo_arg(cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = st.next;
|
||||
prev->val_s = std::move(p_val);
|
||||
p_astack = prev;
|
||||
p_val = std::move(st.val_s);
|
||||
clean_code();
|
||||
}
|
||||
|
||||
void set_arg(cs_state &cs, cs_value &v) {
|
||||
if (cs_is_arg_used(cs, this)) {
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
} else {
|
||||
push_arg(v, cs.p_callstack->argstack[get_index()], false);
|
||||
cs.p_callstack->usedargs |= 1 << get_index();
|
||||
}
|
||||
}
|
||||
|
||||
void set_alias(cs_state &cs, cs_value &v) {
|
||||
p_val = std::move(v);
|
||||
clean_code();
|
||||
p_flags = (p_flags & cs.identflags) | cs.identflags;
|
||||
}
|
||||
|
||||
void clean_code();
|
||||
cs_bcode *compile_code(cs_state &cs);
|
||||
|
||||
cs_bcode *p_acode;
|
||||
cs_ident_stack *p_astack;
|
||||
cs_value p_val;
|
||||
};
|
||||
|
||||
struct cs_command_impl: cs_ident_impl, cs_command {
|
||||
cs_command_impl(cs_strref name, cs_strref args, int numargs, cs_command_cb func);
|
||||
|
||||
void call(cs_state &cs, std::span<cs_value> args, cs_value &ret) {
|
||||
p_cb_cftv(cs, args, ret);
|
||||
}
|
||||
|
||||
cs_strref p_cargs;
|
||||
cs_command_cb p_cb_cftv;
|
||||
int p_numargs;
|
||||
};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct cs_valarray {
|
||||
cs_valarray(cs_state &cs) {
|
||||
|
|
|
@ -203,24 +203,6 @@ cs_svar const *cs_ident::get_svar() const {
|
|||
return static_cast<cs_svar const *>(this);
|
||||
}
|
||||
|
||||
void cs_var_impl::changed(cs_state &cs) {
|
||||
if (cb_var) {
|
||||
switch (p_type) {
|
||||
case CsIdIvar:
|
||||
cb_var(cs, *static_cast<cs_ivar_impl *>(this));
|
||||
break;
|
||||
case CsIdFvar:
|
||||
cb_var(cs, *static_cast<cs_fvar_impl *>(this));
|
||||
break;
|
||||
case CsIdSvar:
|
||||
cb_var(cs, *static_cast<cs_svar_impl *>(this));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cs_int cs_ivar::get_val_min() const {
|
||||
return static_cast<cs_ivar_impl const *>(this)->p_minval;
|
||||
}
|
||||
|
@ -318,29 +300,29 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
p = new_command("do", "e", [](auto &cs, auto args, auto &res) {
|
||||
cs.run(args[0].get_code(), res);
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdDo;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_DO;
|
||||
|
||||
p = new_command("doargs", "e", [](auto &cs, auto args, auto &res) {
|
||||
cs_do_args(cs, [&cs, &res, &args]() {
|
||||
cs.run(args[0].get_code(), res);
|
||||
});
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdDoArgs;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_DOARGS;
|
||||
|
||||
p = new_command("if", "tee", [](auto &cs, auto args, auto &res) {
|
||||
cs.run((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdIf;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_IF;
|
||||
|
||||
p = new_command("result", "t", [](auto &, auto args, auto &res) {
|
||||
res = std::move(args[0]);
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdResult;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_RESULT;
|
||||
|
||||
p = new_command("!", "t", [](auto &, auto args, auto &res) {
|
||||
res.set_int(!args[0].get_bool());
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdNot;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_NOT;
|
||||
|
||||
p = new_command("&&", "E1V", [](auto &cs, auto args, auto &res) {
|
||||
if (args.empty()) {
|
||||
|
@ -359,7 +341,7 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
}
|
||||
}
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdAnd;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_AND;
|
||||
|
||||
p = new_command("||", "E1V", [](auto &cs, auto args, auto &res) {
|
||||
if (args.empty()) {
|
||||
|
@ -378,10 +360,10 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
}
|
||||
}
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdOr;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_OR;
|
||||
|
||||
p = new_command("local", "", nullptr);
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdLocal;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_LOCAL;
|
||||
|
||||
p = new_command("break", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
|
@ -390,7 +372,7 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
throw cs_error(cs, "no loop to break");
|
||||
}
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdBreak;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_BREAK;
|
||||
|
||||
p = new_command("continue", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
|
@ -399,7 +381,7 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
throw cs_error(cs, "no loop to continue");
|
||||
}
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdContinue;
|
||||
static_cast<cs_command_impl *>(p)->p_type = ID_CONTINUE;
|
||||
|
||||
cs_init_lib_base(*this);
|
||||
}
|
||||
|
@ -699,7 +681,7 @@ int cs_ident::get_raw_type() const {
|
|||
}
|
||||
|
||||
cs_ident_type cs_ident::get_type() const {
|
||||
if (p_impl->p_type > CsIdAlias) {
|
||||
if (p_impl->p_type > ID_ALIAS) {
|
||||
return cs_ident_type::SPECIAL;
|
||||
}
|
||||
return cs_ident_type(p_impl->p_type);
|
||||
|
@ -868,7 +850,7 @@ cs_state::get_alias_val(std::string_view name) {
|
|||
if (!a) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if ((a->get_index() < MaxArguments) && !cs_is_arg_used(*this, a)) {
|
||||
if ((a->get_index() < MaxArguments) && !ident_is_used_arg(a, *this)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return a->get_value().get_str();
|
||||
|
|
|
@ -5,7 +5,9 @@ libcubescript_header_src = [
|
|||
|
||||
libcubescript_src = [
|
||||
'cs_bcode.cc',
|
||||
'cs_error.cc',
|
||||
'cs_gen.cc',
|
||||
'cs_ident.cc',
|
||||
'cs_util.cc',
|
||||
'cs_val.cc',
|
||||
'cs_vm.cc',
|
||||
|
|
Loading…
Reference in New Issue