hide implementation details of idents
parent
3905ff0e9d
commit
f8eb07ee2b
|
@ -56,6 +56,7 @@ struct cs_bcode;
|
|||
struct cs_value;
|
||||
struct cs_state;
|
||||
struct cs_shared_state;
|
||||
struct cs_ident_impl;
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_bcode_ref {
|
||||
cs_bcode_ref():
|
||||
|
@ -206,19 +207,7 @@ struct cs_alias;
|
|||
struct cs_command;
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
cs_ident() = delete;
|
||||
cs_ident(cs_ident const &) = delete;
|
||||
cs_ident(cs_ident &&) = delete;
|
||||
|
||||
/* trigger destructors for all inherited members properly */
|
||||
virtual ~cs_ident() {};
|
||||
|
||||
cs_ident &operator=(cs_ident const &) = delete;
|
||||
cs_ident &operator=(cs_ident &&) = delete;
|
||||
|
||||
int get_raw_type() const;
|
||||
cs_ident_type get_type() const;
|
||||
std::string_view get_name() const;
|
||||
int get_flags() const;
|
||||
|
@ -250,127 +239,64 @@ struct LIBCUBESCRIPT_EXPORT cs_ident {
|
|||
cs_svar *get_svar();
|
||||
cs_svar const *get_svar() const;
|
||||
|
||||
int get_type_raw() const {
|
||||
return p_type;
|
||||
}
|
||||
|
||||
protected:
|
||||
cs_ident(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;
|
||||
cs_ident() = default;
|
||||
|
||||
private:
|
||||
int p_index = -1;
|
||||
friend struct cs_state;
|
||||
|
||||
cs_ident_impl *p_impl{};
|
||||
};
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_var: cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
protected:
|
||||
cs_var(cs_ident_type tp, cs_strref name, cs_var_cb func, int flags = 0);
|
||||
|
||||
private:
|
||||
cs_var_cb cb_var;
|
||||
|
||||
void changed(cs_state &cs) {
|
||||
if (cb_var) {
|
||||
cb_var(cs, *this);
|
||||
}
|
||||
}
|
||||
cs_var() = default;
|
||||
};
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_ivar: cs_var {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
cs_int get_val_min() const;
|
||||
cs_int get_val_max() const;
|
||||
|
||||
cs_int get_value() const;
|
||||
void set_value(cs_int val);
|
||||
|
||||
private:
|
||||
cs_ivar(
|
||||
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;
|
||||
protected:
|
||||
cs_ivar() = default;
|
||||
};
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_fvar: cs_var {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
cs_float get_val_min() const;
|
||||
cs_float get_val_max() const;
|
||||
|
||||
cs_float get_value() const;
|
||||
void set_value(cs_float val);
|
||||
|
||||
private:
|
||||
cs_fvar(
|
||||
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;
|
||||
protected:
|
||||
cs_fvar() = default;
|
||||
};
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_svar: cs_var {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
cs_strref get_value() const;
|
||||
void set_value(cs_strref val);
|
||||
|
||||
private:
|
||||
cs_svar(cs_strref n, cs_strref v, cs_strref ov, cs_var_cb f, int flags);
|
||||
|
||||
cs_strref p_storage, p_overrideval;
|
||||
protected:
|
||||
cs_svar() = default;
|
||||
};
|
||||
|
||||
struct LIBCUBESCRIPT_EXPORT cs_alias: cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
friend struct cs_alias_internal;
|
||||
|
||||
cs_value get_value() const {
|
||||
return p_val;
|
||||
}
|
||||
|
||||
cs_value get_value() const;
|
||||
void get_cval(cs_value &v) const;
|
||||
private:
|
||||
cs_alias(cs_state &cs, cs_strref n, cs_strref a, int flags);
|
||||
cs_alias(cs_state &cs, cs_strref n, std::string_view a, int flags);
|
||||
cs_alias(cs_state &cs, cs_strref n, cs_int a, int flags);
|
||||
cs_alias(cs_state &cs, cs_strref n, cs_float a, int flags);
|
||||
cs_alias(cs_state &cs, cs_strref n, int flags);
|
||||
cs_alias(cs_state &cs, cs_strref n, cs_value v, int flags);
|
||||
|
||||
cs_bcode *p_acode;
|
||||
cs_ident_stack *p_astack;
|
||||
cs_value p_val;
|
||||
protected:
|
||||
cs_alias() = default;
|
||||
};
|
||||
|
||||
struct cs_command: cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
friend struct cs_cmd_internal;
|
||||
|
||||
std::string_view get_args() const;
|
||||
int get_num_args() const;
|
||||
|
||||
private:
|
||||
cs_command(cs_strref name, cs_strref args, int numargs, cs_command_cb func);
|
||||
|
||||
cs_strref p_cargs;
|
||||
cs_command_cb p_cb_cftv;
|
||||
int p_numargs;
|
||||
protected:
|
||||
cs_command() = default;
|
||||
};
|
||||
|
||||
struct cs_ident_link;
|
||||
|
@ -524,7 +450,7 @@ struct LIBCUBESCRIPT_EXPORT cs_state {
|
|||
private:
|
||||
LIBCUBESCRIPT_LOCAL cs_state(cs_shared_state *s);
|
||||
|
||||
cs_ident *add_ident(cs_ident *id);
|
||||
cs_ident *add_ident(cs_ident *id, cs_ident_impl *impl);
|
||||
|
||||
LIBCUBESCRIPT_LOCAL void *alloc(void *ptr, size_t olds, size_t news);
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ lookupid:
|
|||
if (prevargs >= MaxResults) {
|
||||
gs.code.push_back(CS_CODE_ENTER);
|
||||
}
|
||||
auto fmt = static_cast<cs_command *>(id)->get_args();
|
||||
auto fmt = static_cast<cs_command_impl *>(id)->get_args();
|
||||
for (char c: fmt) {
|
||||
switch (c) {
|
||||
case 'S':
|
||||
|
@ -847,7 +847,7 @@ static bool compilearg(
|
|||
}
|
||||
|
||||
static void compile_cmd(
|
||||
cs_gen_state &gs, cs_command *id, bool &more, int rettype, int prevargs
|
||||
cs_gen_state &gs, cs_command_impl *id, bool &more, int rettype, int prevargs
|
||||
) {
|
||||
int comtype = CS_CODE_COM, numargs = 0, fakeargs = 0;
|
||||
bool rep = false;
|
||||
|
@ -1159,8 +1159,8 @@ static void compile_and_or(
|
|||
}
|
||||
if (!more) {
|
||||
gs.code.push_back(
|
||||
((id->get_type_raw() == CsIdAnd) ? CS_CODE_TRUE : CS_CODE_FALSE)
|
||||
| cs_ret_code(rettype)
|
||||
((id->get_raw_type() == CsIdAnd)
|
||||
? CS_CODE_TRUE : CS_CODE_FALSE) | cs_ret_code(rettype)
|
||||
);
|
||||
} else {
|
||||
numargs++;
|
||||
|
@ -1191,7 +1191,7 @@ static void compile_and_or(
|
|||
(numargs << 8) | (id->get_index() << 13)
|
||||
);
|
||||
} else {
|
||||
uint32_t op = (id->get_type_raw() == CsIdAnd)
|
||||
uint32_t op = (id->get_raw_type() == CsIdAnd)
|
||||
? (CS_CODE_JUMP_RESULT | CS_CODE_FLAG_FALSE)
|
||||
: (CS_CODE_JUMP_RESULT | CS_CODE_FLAG_TRUE);
|
||||
gs.code.push_back(op);
|
||||
|
@ -1328,7 +1328,7 @@ noid:
|
|||
}
|
||||
gs.code.push_back(CS_CODE_RESULT);
|
||||
} else {
|
||||
switch (id->get_type_raw()) {
|
||||
switch (id->get_raw_type()) {
|
||||
case CsIdAlias:
|
||||
compile_alias(
|
||||
gs, static_cast<cs_alias *>(id), more, prevargs
|
||||
|
@ -1336,7 +1336,7 @@ noid:
|
|||
break;
|
||||
case CsIdCommand:
|
||||
compile_cmd(
|
||||
gs, static_cast<cs_command *>(id), more,
|
||||
gs, static_cast<cs_command_impl *>(id), more,
|
||||
rettype, prevargs
|
||||
);
|
||||
break;
|
||||
|
|
|
@ -417,7 +417,9 @@ bool cs_stacked_value::push() {
|
|||
if (!p_a) {
|
||||
return false;
|
||||
}
|
||||
cs_alias_internal::push_arg(p_a, *this, p_stack);
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias_impl *>(p_a), *this, p_stack
|
||||
);
|
||||
p_pushed = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -426,7 +428,7 @@ bool cs_stacked_value::pop() {
|
|||
if (!p_pushed || !p_a) {
|
||||
return false;
|
||||
}
|
||||
cs_alias_internal::pop_arg(p_a);
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias_impl *>(p_a));
|
||||
p_pushed = false;
|
||||
return true;
|
||||
}
|
||||
|
|
52
src/cs_vm.cc
52
src/cs_vm.cc
|
@ -11,14 +11,14 @@ struct cs_cmd_internal {
|
|||
static void call(
|
||||
cs_state &cs, cs_command *c, std::span<cs_value> args, cs_value &ret
|
||||
) {
|
||||
c->p_cb_cftv(cs, args, ret);
|
||||
static_cast<cs_command_impl *>(c)->p_cb_cftv(cs, args, ret);
|
||||
}
|
||||
|
||||
static bool has_cb(cs_ident *id) {
|
||||
if (!id->is_command() && !id->is_special()) {
|
||||
return false;
|
||||
}
|
||||
cs_command *cb = static_cast<cs_command *>(id);
|
||||
cs_command_impl *cb = static_cast<cs_command_impl *>(id);
|
||||
return !!cb->p_cb_cftv;
|
||||
}
|
||||
};
|
||||
|
@ -26,13 +26,13 @@ struct cs_cmd_internal {
|
|||
static inline void cs_push_alias(cs_state &cs, cs_ident *id, cs_ident_stack &st) {
|
||||
if (id->is_alias() && (id->get_index() >= MaxArguments)) {
|
||||
cs_value nv{cs};
|
||||
cs_alias_internal::push_arg(static_cast<cs_alias *>(id), nv, st);
|
||||
cs_alias_internal::push_arg(static_cast<cs_alias_impl *>(id), nv, st);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cs_pop_alias(cs_ident *id) {
|
||||
if (id->is_alias() && (id->get_index() >= MaxArguments)) {
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias *>(id));
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias_impl *>(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,8 +310,8 @@ cs_bcode *cs_copy_code(cs_bcode *c) {
|
|||
}
|
||||
|
||||
static inline void callcommand(
|
||||
cs_state &cs, cs_command *id, cs_value *args, cs_value &res, int numargs,
|
||||
bool lookup = false
|
||||
cs_state &cs, cs_command_impl *id, cs_value *args, cs_value &res,
|
||||
int numargs, bool lookup = false
|
||||
) {
|
||||
int i = -1, fakeargs = 0;
|
||||
bool rep = false;
|
||||
|
@ -470,7 +470,7 @@ static inline void cs_call_alias(
|
|||
cs_valarray<cs_ident_stack, MaxArguments> argstack{cs};
|
||||
for(int i = 0; i < callargs; i++) {
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[i]),
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i]),
|
||||
args[offset + i], argstack[i], false
|
||||
);
|
||||
}
|
||||
|
@ -483,7 +483,7 @@ static inline void cs_call_alias(
|
|||
};
|
||||
cs.p_callstack = &aliaslink;
|
||||
uint32_t *codep = reinterpret_cast<uint32_t *>(
|
||||
cs_alias_internal::compile_code(a, cs)
|
||||
cs_alias_internal::compile_code(static_cast<cs_alias_impl *>(a), cs)
|
||||
);
|
||||
bcode_incr(codep);
|
||||
cs_do_and_cleanup([&]() {
|
||||
|
@ -494,13 +494,13 @@ static inline void cs_call_alias(
|
|||
cs.identflags = oldflags;
|
||||
for (int i = 0; i < callargs; i++) {
|
||||
cs_alias_internal::pop_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[i])
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i])
|
||||
);
|
||||
}
|
||||
int argmask = aliaslink.usedargs & int(~0U << callargs);
|
||||
for (; argmask; ++callargs) {
|
||||
if (argmask & (1 << callargs)) {
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias *>(
|
||||
cs_alias_internal::pop_arg(static_cast<cs_alias_impl *>(
|
||||
cs.p_state->identmap[callargs])
|
||||
);
|
||||
argmask &= ~(1 << callargs);
|
||||
|
@ -570,7 +570,10 @@ static inline int cs_get_lookupu_type(
|
|||
case cs_ident_type::COMMAND: {
|
||||
arg.set_none();
|
||||
cs_valarray<cs_value, MaxArguments> buf{cs};
|
||||
callcommand(cs, static_cast<cs_command *>(id), &buf[0], arg, 0, true);
|
||||
callcommand(
|
||||
cs, static_cast<cs_command_impl *>(id),
|
||||
&buf[0], arg, 0, true
|
||||
);
|
||||
force_arg(arg, op & CS_CODE_RET_MASK);
|
||||
return -2; /* ignore */
|
||||
}
|
||||
|
@ -950,7 +953,8 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
if (!cs_is_arg_used(cs, a)) {
|
||||
cs_value nv{cs};
|
||||
cs_alias_internal::push_arg(
|
||||
a, nv, cs.p_callstack->argstack[a->get_index()], false
|
||||
static_cast<cs_alias_impl *>(a), nv,
|
||||
cs.p_callstack->argstack[a->get_index()], false
|
||||
);
|
||||
cs.p_callstack->usedargs |= 1 << a->get_index();
|
||||
}
|
||||
|
@ -966,7 +970,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
if ((id->get_index() < MaxArguments) && !cs_is_arg_used(cs, id)) {
|
||||
cs_value nv{cs};
|
||||
cs_alias_internal::push_arg(
|
||||
static_cast<cs_alias *>(id), nv,
|
||||
static_cast<cs_alias_impl *>(id), nv,
|
||||
cs.p_callstack->argstack[id->get_index()], false
|
||||
);
|
||||
cs.p_callstack->usedargs |= 1 << id->get_index();
|
||||
|
@ -1308,7 +1312,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
case CS_CODE_COM | CS_RET_STRING:
|
||||
case CS_CODE_COM | CS_RET_FLOAT:
|
||||
case CS_CODE_COM | CS_RET_INT: {
|
||||
cs_command *id = static_cast<cs_command *>(
|
||||
cs_command_impl *id = static_cast<cs_command_impl *>(
|
||||
cs.p_state->identmap[op >> 8]
|
||||
);
|
||||
int offset = numargs - id->get_num_args();
|
||||
|
@ -1325,7 +1329,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
case CS_CODE_COM_V | CS_RET_STRING:
|
||||
case CS_CODE_COM_V | CS_RET_FLOAT:
|
||||
case CS_CODE_COM_V | CS_RET_INT: {
|
||||
cs_command *id = static_cast<cs_command *>(
|
||||
cs_command_impl *id = static_cast<cs_command_impl *>(
|
||||
cs.p_state->identmap[op >> 13]
|
||||
);
|
||||
std::size_t callargs = (op >> 8) & 0x1F,
|
||||
|
@ -1342,7 +1346,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
case CS_CODE_COM_C | CS_RET_STRING:
|
||||
case CS_CODE_COM_C | CS_RET_FLOAT:
|
||||
case CS_CODE_COM_C | CS_RET_INT: {
|
||||
cs_command *id = static_cast<cs_command *>(
|
||||
cs_command_impl *id = static_cast<cs_command_impl *>(
|
||||
cs.p_state->identmap[op >> 13]
|
||||
);
|
||||
std::size_t callargs = (op >> 8) & 0x1F,
|
||||
|
@ -1398,13 +1402,13 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
|
|||
|
||||
case CS_CODE_ALIAS:
|
||||
cs_alias_internal::set_alias(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[op >> 8]),
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[op >> 8]),
|
||||
cs, args[--numargs]
|
||||
);
|
||||
continue;
|
||||
case CS_CODE_ALIAS_ARG:
|
||||
cs_alias_internal::set_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[op >> 8]),
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[op >> 8]),
|
||||
cs, args[--numargs]
|
||||
);
|
||||
continue;
|
||||
|
@ -1481,7 +1485,7 @@ noid:
|
|||
);
|
||||
}
|
||||
result.force_none();
|
||||
switch (id->get_type_raw()) {
|
||||
switch (id->get_raw_type()) {
|
||||
default:
|
||||
if (!cs_cmd_internal::has_cb(id)) {
|
||||
numargs = offset - 1;
|
||||
|
@ -1491,8 +1495,8 @@ noid:
|
|||
/* fallthrough */
|
||||
case CsIdCommand:
|
||||
callcommand(
|
||||
cs, static_cast<cs_command *>(id), &args[offset],
|
||||
result, callargs
|
||||
cs, static_cast<cs_command_impl *>(id),
|
||||
&args[offset], result, callargs
|
||||
);
|
||||
force_arg(result, op & CS_CODE_RET_MASK);
|
||||
numargs = offset - 1;
|
||||
|
@ -1618,18 +1622,18 @@ void cs_state::run(cs_ident *id, std::span<cs_value> args, cs_value &ret) {
|
|||
}
|
||||
/* fallthrough */
|
||||
case cs_ident_type::COMMAND:
|
||||
if (nargs < static_cast<cs_command *>(id)->get_num_args()) {
|
||||
if (nargs < static_cast<cs_command_impl *>(id)->get_num_args()) {
|
||||
cs_valarray<cs_value, MaxArguments> buf{*this};
|
||||
for (std::size_t i = 0; i < args.size(); ++i) {
|
||||
buf[i] = args[i];
|
||||
}
|
||||
callcommand(
|
||||
*this, static_cast<cs_command *>(id), &buf[0], ret,
|
||||
*this, static_cast<cs_command_impl *>(id), &buf[0], ret,
|
||||
nargs, false
|
||||
);
|
||||
} else {
|
||||
callcommand(
|
||||
*this, static_cast<cs_command *>(id), &args[0],
|
||||
*this, static_cast<cs_command_impl *>(id), &args[0],
|
||||
ret, nargs, false
|
||||
);
|
||||
}
|
||||
|
|
94
src/cs_vm.hh
94
src/cs_vm.hh
|
@ -25,6 +25,80 @@ enum {
|
|||
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_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);
|
||||
|
||||
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);
|
||||
|
||||
cs_strref p_cargs;
|
||||
cs_command_cb p_cb_cftv;
|
||||
int p_numargs;
|
||||
};
|
||||
|
||||
struct cs_ident_link {
|
||||
cs_ident *id;
|
||||
cs_ident_link *next;
|
||||
|
@ -293,7 +367,7 @@ static inline bool cs_is_arg_used(cs_state &cs, cs_ident *id) {
|
|||
|
||||
struct cs_alias_internal {
|
||||
static void push_arg(
|
||||
cs_alias *a, cs_value &v, cs_ident_stack &st, bool um = true
|
||||
cs_alias_impl *a, cs_value &v, cs_ident_stack &st, bool um = true
|
||||
) {
|
||||
if (a->p_astack == &st) {
|
||||
/* prevent cycles and unnecessary code elsewhere */
|
||||
|
@ -311,7 +385,7 @@ struct cs_alias_internal {
|
|||
}
|
||||
}
|
||||
|
||||
static void pop_arg(cs_alias *a) {
|
||||
static void pop_arg(cs_alias_impl *a) {
|
||||
if (!a->p_astack) {
|
||||
return;
|
||||
}
|
||||
|
@ -321,7 +395,7 @@ struct cs_alias_internal {
|
|||
a->p_astack = st->next;
|
||||
}
|
||||
|
||||
static void undo_arg(cs_alias *a, cs_ident_stack &st) {
|
||||
static void undo_arg(cs_alias_impl *a, cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = a->p_astack;
|
||||
st.val_s = std::move(a->p_val);
|
||||
st.next = prev;
|
||||
|
@ -330,7 +404,7 @@ struct cs_alias_internal {
|
|||
clean_code(a);
|
||||
}
|
||||
|
||||
static void redo_arg(cs_alias *a, cs_ident_stack &st) {
|
||||
static void redo_arg(cs_alias_impl *a, cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = st.next;
|
||||
prev->val_s = std::move(a->p_val);
|
||||
a->p_astack = prev;
|
||||
|
@ -338,7 +412,7 @@ struct cs_alias_internal {
|
|||
clean_code(a);
|
||||
}
|
||||
|
||||
static void set_arg(cs_alias *a, cs_state &cs, cs_value &v) {
|
||||
static void set_arg(cs_alias_impl *a, cs_state &cs, cs_value &v) {
|
||||
if (cs_is_arg_used(cs, a)) {
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
|
@ -348,13 +422,13 @@ struct cs_alias_internal {
|
|||
}
|
||||
}
|
||||
|
||||
static void set_alias(cs_alias *a, cs_state &cs, cs_value &v) {
|
||||
static void set_alias(cs_alias_impl *a, cs_state &cs, cs_value &v) {
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
a->p_flags = (a->p_flags & cs.identflags) | cs.identflags;
|
||||
}
|
||||
|
||||
static void clean_code(cs_alias *a) {
|
||||
static void clean_code(cs_alias_impl *a) {
|
||||
uint32_t *bcode = reinterpret_cast<uint32_t *>(a->p_acode);
|
||||
if (bcode) {
|
||||
bcode_decr(bcode);
|
||||
|
@ -362,7 +436,7 @@ struct cs_alias_internal {
|
|||
}
|
||||
}
|
||||
|
||||
static cs_bcode *compile_code(cs_alias *a, cs_state &cs) {
|
||||
static cs_bcode *compile_code(cs_alias_impl *a, cs_state &cs) {
|
||||
if (!a->p_acode) {
|
||||
cs_gen_state gs(cs);
|
||||
gs.code.reserve(64);
|
||||
|
@ -388,7 +462,7 @@ static void cs_do_args(cs_state &cs, F body) {
|
|||
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
|
||||
if (argmask1 & 1) {
|
||||
cs_alias_internal::undo_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[i]), argstack[i]
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i]), argstack[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +482,7 @@ static void cs_do_args(cs_state &cs, F body) {
|
|||
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
|
||||
if (argmask2 & 1) {
|
||||
cs_alias_internal::redo_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[i]), argstack[i]
|
||||
static_cast<cs_alias_impl *>(cs.p_state->identmap[i]), argstack[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,73 +20,73 @@ bool cs_check_num(std::string_view s) {
|
|||
}
|
||||
}
|
||||
|
||||
cs_ident::cs_ident(cs_ident_type tp, cs_strref nm, int fl):
|
||||
cs_ident_impl::cs_ident_impl(cs_ident_type tp, cs_strref nm, int fl):
|
||||
p_name(nm), p_type(int(tp)), p_flags(fl)
|
||||
{}
|
||||
|
||||
cs_var::cs_var(cs_ident_type tp, cs_strref name, cs_var_cb f, int fl):
|
||||
cs_ident(tp, name, fl), cb_var(std::move(f))
|
||||
cs_var_impl::cs_var_impl(cs_ident_type tp, cs_strref name, cs_var_cb f, int fl):
|
||||
cs_ident_impl(tp, name, fl), cb_var(std::move(f))
|
||||
{}
|
||||
|
||||
cs_ivar::cs_ivar(
|
||||
cs_ivar_impl::cs_ivar_impl(
|
||||
cs_strref name, cs_int m, cs_int x, cs_int v, cs_var_cb f, int fl
|
||||
):
|
||||
cs_var(cs_ident_type::IVAR, name, std::move(f), fl | ((m > x) ? CS_IDF_READONLY : 0)),
|
||||
cs_var_impl(cs_ident_type::IVAR, name, std::move(f), fl | ((m > x) ? CS_IDF_READONLY : 0)),
|
||||
p_storage(v), p_minval(m), p_maxval(x), p_overrideval(0)
|
||||
{}
|
||||
|
||||
cs_fvar::cs_fvar(
|
||||
cs_fvar_impl::cs_fvar_impl(
|
||||
cs_strref name, cs_float m, cs_float x, cs_float v, cs_var_cb f, int fl
|
||||
):
|
||||
cs_var(cs_ident_type::FVAR, name, std::move(f), fl | ((m > x) ? CS_IDF_READONLY : 0)),
|
||||
cs_var_impl(cs_ident_type::FVAR, name, std::move(f), fl | ((m > x) ? CS_IDF_READONLY : 0)),
|
||||
p_storage(v), p_minval(m), p_maxval(x), p_overrideval(0)
|
||||
{}
|
||||
|
||||
cs_svar::cs_svar(cs_strref name, cs_strref v, cs_strref ov, cs_var_cb f, int fl):
|
||||
cs_var(cs_ident_type::SVAR, name, std::move(f), fl),
|
||||
cs_svar_impl::cs_svar_impl(cs_strref name, cs_strref v, cs_strref ov, cs_var_cb f, int fl):
|
||||
cs_var_impl(cs_ident_type::SVAR, name, std::move(f), fl),
|
||||
p_storage{v}, p_overrideval{ov}
|
||||
{}
|
||||
|
||||
cs_alias::cs_alias(cs_state &cs, cs_strref name, cs_strref a, int fl):
|
||||
cs_ident(cs_ident_type::ALIAS, name, fl),
|
||||
cs_alias_impl::cs_alias_impl(cs_state &cs, cs_strref name, cs_strref a, int fl):
|
||||
cs_ident_impl(cs_ident_type::ALIAS, name, fl),
|
||||
p_acode(nullptr), p_astack(nullptr), p_val{cs}
|
||||
{
|
||||
p_val.set_str(a);
|
||||
}
|
||||
cs_alias::cs_alias(cs_state &cs, cs_strref name, std::string_view a, int fl):
|
||||
cs_ident(cs_ident_type::ALIAS, name, fl),
|
||||
cs_alias_impl::cs_alias_impl(cs_state &cs, cs_strref name, std::string_view a, int fl):
|
||||
cs_ident_impl(cs_ident_type::ALIAS, name, fl),
|
||||
p_acode(nullptr), p_astack(nullptr), p_val{cs}
|
||||
{
|
||||
p_val.set_str(a);
|
||||
}
|
||||
cs_alias::cs_alias(cs_state &cs, cs_strref name, cs_int a, int fl):
|
||||
cs_ident(cs_ident_type::ALIAS, name, fl),
|
||||
cs_alias_impl::cs_alias_impl(cs_state &cs, cs_strref name, cs_int a, int fl):
|
||||
cs_ident_impl(cs_ident_type::ALIAS, name, fl),
|
||||
p_acode(nullptr), p_astack(nullptr), p_val{cs}
|
||||
{
|
||||
p_val.set_int(a);
|
||||
}
|
||||
cs_alias::cs_alias(cs_state &cs, cs_strref name, cs_float a, int fl):
|
||||
cs_ident(cs_ident_type::ALIAS, name, fl),
|
||||
cs_alias_impl::cs_alias_impl(cs_state &cs, cs_strref name, cs_float a, int fl):
|
||||
cs_ident_impl(cs_ident_type::ALIAS, name, fl),
|
||||
p_acode(nullptr), p_astack(nullptr), p_val{cs}
|
||||
{
|
||||
p_val.set_float(a);
|
||||
}
|
||||
cs_alias::cs_alias(cs_state &cs, cs_strref name, int fl):
|
||||
cs_ident(cs_ident_type::ALIAS, name, fl),
|
||||
cs_alias_impl::cs_alias_impl(cs_state &cs, cs_strref name, int fl):
|
||||
cs_ident_impl(cs_ident_type::ALIAS, name, fl),
|
||||
p_acode(nullptr), p_astack(nullptr), p_val{cs}
|
||||
{
|
||||
p_val.set_none();
|
||||
}
|
||||
/* FIXME: use cs rather than val's cs */
|
||||
cs_alias::cs_alias(cs_state &, cs_strref name, cs_value v, int fl):
|
||||
cs_ident(cs_ident_type::ALIAS, name, fl),
|
||||
cs_alias_impl::cs_alias_impl(cs_state &, cs_strref name, cs_value v, int fl):
|
||||
cs_ident_impl(cs_ident_type::ALIAS, name, fl),
|
||||
p_acode(nullptr), p_astack(nullptr), p_val(v)
|
||||
{}
|
||||
|
||||
cs_command::cs_command(
|
||||
cs_command_impl::cs_command_impl(
|
||||
cs_strref name, cs_strref args, int nargs, cs_command_cb f
|
||||
):
|
||||
cs_ident(cs_ident_type::COMMAND, name, 0),
|
||||
cs_ident_impl(cs_ident_type::COMMAND, name, 0),
|
||||
p_cargs(args), p_cb_cftv(std::move(f)), p_numargs(nargs)
|
||||
{}
|
||||
|
||||
|
@ -116,14 +116,14 @@ cs_command *cs_ident::get_command() {
|
|||
if (!is_command()) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<cs_command *>(this);
|
||||
return static_cast<cs_command_impl *>(this);
|
||||
}
|
||||
|
||||
cs_command const *cs_ident::get_command() const {
|
||||
if (!is_command()) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<cs_command const *>(this);
|
||||
return static_cast<cs_command_impl const *>(this);
|
||||
}
|
||||
|
||||
bool cs_ident::is_special() const {
|
||||
|
@ -203,47 +203,65 @@ 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 p_minval;
|
||||
return static_cast<cs_ivar_impl const *>(this)->p_minval;
|
||||
}
|
||||
cs_int cs_ivar::get_val_max() const {
|
||||
return p_maxval;
|
||||
return static_cast<cs_ivar_impl const *>(this)->p_maxval;
|
||||
}
|
||||
|
||||
cs_int cs_ivar::get_value() const {
|
||||
return p_storage;
|
||||
return static_cast<cs_ivar_impl const *>(this)->p_storage;
|
||||
}
|
||||
void cs_ivar::set_value(cs_int val) {
|
||||
p_storage = val;
|
||||
static_cast<cs_ivar_impl *>(this)->p_storage = val;
|
||||
}
|
||||
|
||||
cs_float cs_fvar::get_val_min() const {
|
||||
return p_minval;
|
||||
return static_cast<cs_fvar_impl const *>(this)->p_minval;
|
||||
}
|
||||
cs_float cs_fvar::get_val_max() const {
|
||||
return p_maxval;
|
||||
return static_cast<cs_fvar_impl const *>(this)->p_maxval;
|
||||
}
|
||||
|
||||
cs_float cs_fvar::get_value() const {
|
||||
return p_storage;
|
||||
return static_cast<cs_fvar_impl const *>(this)->p_storage;
|
||||
}
|
||||
void cs_fvar::set_value(cs_float val) {
|
||||
p_storage = val;
|
||||
static_cast<cs_fvar_impl *>(this)->p_storage = val;
|
||||
}
|
||||
|
||||
cs_strref cs_svar::get_value() const {
|
||||
return p_storage;
|
||||
return static_cast<cs_svar_impl const *>(this)->p_storage;
|
||||
}
|
||||
void cs_svar::set_value(cs_strref val) {
|
||||
p_storage = val;
|
||||
static_cast<cs_svar_impl *>(this)->p_storage = val;
|
||||
}
|
||||
|
||||
std::string_view cs_command::get_args() const {
|
||||
return p_cargs;
|
||||
return static_cast<cs_command_impl const *>(this)->p_cargs;
|
||||
}
|
||||
|
||||
int cs_command::get_num_args() const {
|
||||
return p_numargs;
|
||||
return static_cast<cs_command_impl const *>(this)->p_numargs;
|
||||
}
|
||||
|
||||
void cs_init_lib_base(cs_state &cs);
|
||||
|
@ -261,6 +279,8 @@ cs_state::cs_state(): cs_state{cs_default_alloc, nullptr} {}
|
|||
cs_state::cs_state(cs_alloc_cb func, void *data):
|
||||
p_state(nullptr), p_callhook()
|
||||
{
|
||||
cs_command *p;
|
||||
|
||||
if (!func) {
|
||||
func = cs_default_alloc;
|
||||
}
|
||||
|
@ -295,29 +315,34 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
throw cs_internal_error{"invalid dbgalias index"};
|
||||
}
|
||||
|
||||
new_command("do", "e", [](auto &cs, auto args, auto &res) {
|
||||
p = new_command("do", "e", [](auto &cs, auto args, auto &res) {
|
||||
cs.run(args[0].get_code(), res);
|
||||
})->p_type = CsIdDo;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdDo;
|
||||
|
||||
new_command("doargs", "e", [](auto &cs, auto args, auto &res) {
|
||||
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);
|
||||
});
|
||||
})->p_type = CsIdDoArgs;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdDoArgs;
|
||||
|
||||
new_command("if", "tee", [](auto &cs, auto args, auto &res) {
|
||||
p = new_command("if", "tee", [](auto &cs, auto args, auto &res) {
|
||||
cs.run((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
|
||||
})->p_type = CsIdIf;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdIf;
|
||||
|
||||
new_command("result", "t", [](auto &, auto args, auto &res) {
|
||||
p = new_command("result", "t", [](auto &, auto args, auto &res) {
|
||||
res = std::move(args[0]);
|
||||
})->p_type = CsIdResult;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdResult;
|
||||
|
||||
new_command("!", "t", [](auto &, auto args, auto &res) {
|
||||
p = new_command("!", "t", [](auto &, auto args, auto &res) {
|
||||
res.set_int(!args[0].get_bool());
|
||||
})->p_type = CsIdNot;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdNot;
|
||||
|
||||
new_command("&&", "E1V", [](auto &cs, auto args, auto &res) {
|
||||
p = new_command("&&", "E1V", [](auto &cs, auto args, auto &res) {
|
||||
if (args.empty()) {
|
||||
res.set_int(1);
|
||||
} else {
|
||||
|
@ -333,9 +358,10 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
}
|
||||
}
|
||||
}
|
||||
})->p_type = CsIdAnd;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdAnd;
|
||||
|
||||
new_command("||", "E1V", [](auto &cs, auto args, auto &res) {
|
||||
p = new_command("||", "E1V", [](auto &cs, auto args, auto &res) {
|
||||
if (args.empty()) {
|
||||
res.set_int(0);
|
||||
} else {
|
||||
|
@ -351,25 +377,29 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
|
|||
}
|
||||
}
|
||||
}
|
||||
})->p_type = CsIdOr;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdOr;
|
||||
|
||||
new_command("local", "", nullptr)->p_type = CsIdLocal;
|
||||
p = new_command("local", "", nullptr);
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdLocal;
|
||||
|
||||
new_command("break", "", [](auto &cs, auto, auto &) {
|
||||
p = new_command("break", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsBreakException();
|
||||
} else {
|
||||
throw cs_error(cs, "no loop to break");
|
||||
}
|
||||
})->p_type = CsIdBreak;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdBreak;
|
||||
|
||||
new_command("continue", "", [](auto &cs, auto, auto &) {
|
||||
p = new_command("continue", "", [](auto &cs, auto, auto &) {
|
||||
if (cs.is_in_loop()) {
|
||||
throw CsContinueException();
|
||||
} else {
|
||||
throw cs_error(cs, "no loop to continue");
|
||||
}
|
||||
})->p_type = CsIdContinue;
|
||||
});
|
||||
static_cast<cs_command_impl *>(p)->p_type = CsIdContinue;
|
||||
|
||||
cs_init_lib_base(*this);
|
||||
}
|
||||
|
@ -387,7 +417,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::destroy() {
|
|||
cs_alias *a = i->get_alias();
|
||||
if (a) {
|
||||
a->get_value().force_none();
|
||||
cs_alias_internal::clean_code(a);
|
||||
cs_alias_internal::clean_code(static_cast<cs_alias_impl *>(a));
|
||||
}
|
||||
p_state->destroy(i);
|
||||
}
|
||||
|
@ -438,25 +468,25 @@ LIBCUBESCRIPT_EXPORT void cs_state::clear_override(cs_ident &id) {
|
|||
}
|
||||
switch (id.get_type()) {
|
||||
case cs_ident_type::ALIAS: {
|
||||
cs_alias &a = static_cast<cs_alias &>(id);
|
||||
cs_alias_impl &a = static_cast<cs_alias_impl &>(id);
|
||||
cs_alias_internal::clean_code(&a);
|
||||
a.get_value().set_str("");
|
||||
break;
|
||||
}
|
||||
case cs_ident_type::IVAR: {
|
||||
cs_ivar &iv = static_cast<cs_ivar &>(id);
|
||||
cs_ivar_impl &iv = static_cast<cs_ivar_impl &>(id);
|
||||
iv.set_value(iv.p_overrideval);
|
||||
iv.changed(*this);
|
||||
break;
|
||||
}
|
||||
case cs_ident_type::FVAR: {
|
||||
cs_fvar &fv = static_cast<cs_fvar &>(id);
|
||||
cs_fvar_impl &fv = static_cast<cs_fvar_impl &>(id);
|
||||
fv.set_value(fv.p_overrideval);
|
||||
fv.changed(*this);
|
||||
break;
|
||||
}
|
||||
case cs_ident_type::SVAR: {
|
||||
cs_svar &sv = static_cast<cs_svar &>(id);
|
||||
cs_svar_impl &sv = static_cast<cs_svar_impl &>(id);
|
||||
sv.set_value(sv.p_overrideval);
|
||||
sv.changed(*this);
|
||||
break;
|
||||
|
@ -464,7 +494,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::clear_override(cs_ident &id) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
id.p_flags &= ~CS_IDF_OVERRIDDEN;
|
||||
id.p_impl->p_flags &= ~CS_IDF_OVERRIDDEN;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void cs_state::clear_overrides() {
|
||||
|
@ -473,12 +503,15 @@ LIBCUBESCRIPT_EXPORT void cs_state::clear_overrides() {
|
|||
}
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT cs_ident *cs_state::add_ident(cs_ident *id) {
|
||||
LIBCUBESCRIPT_EXPORT cs_ident *cs_state::add_ident(
|
||||
cs_ident *id, cs_ident_impl *impl
|
||||
) {
|
||||
if (!id) {
|
||||
return nullptr;
|
||||
}
|
||||
id->p_impl = impl;
|
||||
p_state->idents[id->get_name()] = id;
|
||||
id->p_index = p_state->identmap.size();
|
||||
static_cast<cs_ident_impl *>(impl)->p_index = p_state->identmap.size();
|
||||
p_state->identmap.push_back(id);
|
||||
return p_state->identmap.back();
|
||||
}
|
||||
|
@ -491,9 +524,10 @@ LIBCUBESCRIPT_EXPORT cs_ident *cs_state::new_ident(std::string_view name, int fl
|
|||
*this, "number %s is not a valid identifier name", name.data()
|
||||
);
|
||||
}
|
||||
id = add_ident(p_state->create<cs_alias>(
|
||||
auto *inst = p_state->create<cs_alias_impl>(
|
||||
*this, cs_strref{*p_state, name}, flags
|
||||
));
|
||||
);
|
||||
id = add_ident(inst, inst);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
@ -549,26 +583,32 @@ LIBCUBESCRIPT_EXPORT std::span<cs_ident const *> cs_state::get_idents() const {
|
|||
LIBCUBESCRIPT_EXPORT cs_ivar *cs_state::new_ivar(
|
||||
std::string_view n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
|
||||
) {
|
||||
return add_ident(p_state->create<cs_ivar>(
|
||||
auto *iv = p_state->create<cs_ivar_impl>(
|
||||
cs_strref{*p_state, n}, m, x, v, std::move(f), flags
|
||||
))->get_ivar();
|
||||
);
|
||||
add_ident(iv, iv);
|
||||
return iv;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT cs_fvar *cs_state::new_fvar(
|
||||
std::string_view n, cs_float m, cs_float x, cs_float v, cs_var_cb f, int flags
|
||||
) {
|
||||
return add_ident(p_state->create<cs_fvar>(
|
||||
auto *fv = p_state->create<cs_fvar_impl>(
|
||||
cs_strref{*p_state, n}, m, x, v, std::move(f), flags
|
||||
))->get_fvar();
|
||||
);
|
||||
add_ident(fv, fv);
|
||||
return fv;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT cs_svar *cs_state::new_svar(
|
||||
std::string_view n, std::string_view v, cs_var_cb f, int flags
|
||||
) {
|
||||
return add_ident(p_state->create<cs_svar>(
|
||||
auto *sv = p_state->create<cs_svar_impl>(
|
||||
cs_strref{*p_state, n}, cs_strref{*p_state, v},
|
||||
cs_strref{*p_state, ""}, std::move(f), flags
|
||||
))->get_svar();
|
||||
);
|
||||
add_ident(sv, sv);
|
||||
return sv;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void cs_state::reset_var(std::string_view name) {
|
||||
|
@ -585,7 +625,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::reset_var(std::string_view name) {
|
|||
LIBCUBESCRIPT_EXPORT void cs_state::touch_var(std::string_view name) {
|
||||
cs_ident *id = get_ident(name);
|
||||
if (id && id->is_var()) {
|
||||
static_cast<cs_var *>(id)->changed(*this);
|
||||
static_cast<cs_var_impl *>(id->p_impl)->changed(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,7 +634,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_alias(std::string_view name, cs_value v)
|
|||
if (id) {
|
||||
switch (id->get_type()) {
|
||||
case cs_ident_type::ALIAS: {
|
||||
cs_alias *a = static_cast<cs_alias *>(id);
|
||||
cs_alias_impl *a = static_cast<cs_alias_impl *>(id);
|
||||
if (a->get_index() < MaxArguments) {
|
||||
cs_alias_internal::set_arg(a, *this, v);
|
||||
} else {
|
||||
|
@ -620,9 +660,10 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_alias(std::string_view name, cs_value v)
|
|||
} else if (cs_check_num(name)) {
|
||||
throw cs_error(*this, "cannot alias number %s", name.data());
|
||||
} else {
|
||||
add_ident(p_state->create<cs_alias>(
|
||||
auto *a = p_state->create<cs_alias_impl>(
|
||||
*this, cs_strref{*p_state, name}, std::move(v), identflags
|
||||
));
|
||||
);
|
||||
add_ident(a, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,16 +671,21 @@ LIBCUBESCRIPT_EXPORT void cs_state::print_var(cs_var const &v) const {
|
|||
p_state->varprintf(*this, v);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT cs_value cs_alias::get_value() const {
|
||||
return static_cast<cs_alias_impl const *>(this)->p_val;
|
||||
}
|
||||
|
||||
void cs_alias::get_cval(cs_value &v) const {
|
||||
switch (p_val.get_type()) {
|
||||
auto *imp = static_cast<cs_alias_impl const *>(this);
|
||||
switch (imp->p_val.get_type()) {
|
||||
case cs_value_type::STRING:
|
||||
v = p_val;
|
||||
v = imp->p_val;
|
||||
break;
|
||||
case cs_value_type::INT:
|
||||
v.set_int(p_val.get_int());
|
||||
v.set_int(imp->p_val.get_int());
|
||||
break;
|
||||
case cs_value_type::FLOAT:
|
||||
v.set_float(p_val.get_float());
|
||||
v.set_float(imp->p_val.get_float());
|
||||
break;
|
||||
default:
|
||||
v.set_none();
|
||||
|
@ -647,23 +693,27 @@ void cs_alias::get_cval(cs_value &v) const {
|
|||
}
|
||||
}
|
||||
|
||||
int cs_ident::get_raw_type() const {
|
||||
return p_impl->p_type;
|
||||
}
|
||||
|
||||
cs_ident_type cs_ident::get_type() const {
|
||||
if (p_type > CsIdAlias) {
|
||||
if (p_impl->p_type > CsIdAlias) {
|
||||
return cs_ident_type::SPECIAL;
|
||||
}
|
||||
return cs_ident_type(p_type);
|
||||
return cs_ident_type(p_impl->p_type);
|
||||
}
|
||||
|
||||
std::string_view cs_ident::get_name() const {
|
||||
return p_name;
|
||||
return p_impl->p_name;
|
||||
}
|
||||
|
||||
int cs_ident::get_flags() const {
|
||||
return p_flags;
|
||||
return p_impl->p_flags;
|
||||
}
|
||||
|
||||
int cs_ident::get_index() const {
|
||||
return p_index;
|
||||
return p_impl->p_index;
|
||||
}
|
||||
|
||||
template<typename SF>
|
||||
|
@ -693,7 +743,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_var_int(
|
|||
if (!id || id->is_ivar()) {
|
||||
return;
|
||||
}
|
||||
cs_ivar *iv = static_cast<cs_ivar *>(id);
|
||||
cs_ivar_impl *iv = static_cast<cs_ivar_impl *>(id);
|
||||
cs_override_var(
|
||||
*this, iv, iv->p_flags,
|
||||
[&iv]() { iv->p_overrideval = iv->get_value(); }
|
||||
|
@ -715,7 +765,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_var_float(
|
|||
if (!id || id->is_fvar()) {
|
||||
return;
|
||||
}
|
||||
cs_fvar *fv = static_cast<cs_fvar *>(id);
|
||||
cs_fvar_impl *fv = static_cast<cs_fvar_impl *>(id);
|
||||
cs_override_var(
|
||||
*this, fv, fv->p_flags,
|
||||
[&fv]() { fv->p_overrideval = fv->get_value(); }
|
||||
|
@ -737,7 +787,7 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_var_str(
|
|||
if (!id || id->is_svar()) {
|
||||
return;
|
||||
}
|
||||
cs_svar *sv = static_cast<cs_svar *>(id);
|
||||
cs_svar_impl *sv = static_cast<cs_svar_impl *>(id);
|
||||
cs_override_var(
|
||||
*this, sv, sv->p_flags,
|
||||
[&sv]() { sv->p_overrideval = sv->get_value(); }
|
||||
|
@ -850,15 +900,16 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_var_int_checked(cs_ivar *iv, cs_int v) {
|
|||
*this, "variable '%s' is read only", iv->get_name().data()
|
||||
);
|
||||
}
|
||||
cs_ivar_impl *ivp = static_cast<cs_ivar_impl *>(iv);
|
||||
cs_override_var(
|
||||
*this, iv, iv->p_flags,
|
||||
[&iv]() { iv->p_overrideval = iv->get_value(); }
|
||||
*this, iv, ivp->p_flags,
|
||||
[&ivp]() { ivp->p_overrideval = ivp->p_storage; }
|
||||
);
|
||||
if ((v < iv->get_val_min()) || (v > iv->get_val_max())) {
|
||||
v = cs_clamp_var(*this, iv, v);
|
||||
}
|
||||
iv->set_value(v);
|
||||
iv->changed(*this);
|
||||
ivp->changed(*this);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void cs_state::set_var_int_checked(
|
||||
|
@ -898,15 +949,16 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_var_float_checked(cs_fvar *fv, cs_float
|
|||
*this, "variable '%s' is read only", fv->get_name().data()
|
||||
);
|
||||
}
|
||||
cs_fvar_impl *fvp = static_cast<cs_fvar_impl *>(fv);
|
||||
cs_override_var(
|
||||
*this, fv, fv->p_flags,
|
||||
[&fv]() { fv->p_overrideval = fv->get_value(); }
|
||||
*this, fv, fvp->p_flags,
|
||||
[&fvp]() { fvp->p_overrideval = fvp->p_storage; }
|
||||
);
|
||||
if ((v < fv->get_val_min()) || (v > fv->get_val_max())) {
|
||||
v = cs_clamp_fvar(*this, fv, v);
|
||||
}
|
||||
fv->set_value(v);
|
||||
fv->changed(*this);
|
||||
fvp->changed(*this);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void cs_state::set_var_str_checked(
|
||||
|
@ -917,12 +969,13 @@ LIBCUBESCRIPT_EXPORT void cs_state::set_var_str_checked(
|
|||
*this, "variable '%s' is read only", sv->get_name().data()
|
||||
);
|
||||
}
|
||||
cs_svar_impl *svp = static_cast<cs_svar_impl *>(sv);
|
||||
cs_override_var(
|
||||
*this, sv, sv->p_flags,
|
||||
[&sv]() { sv->p_overrideval = sv->get_value(); }
|
||||
*this, sv, svp->p_flags,
|
||||
[&svp]() { svp->p_overrideval = svp->p_storage; }
|
||||
);
|
||||
sv->set_value(cs_strref{*p_state, v});
|
||||
sv->changed(*this);
|
||||
svp->changed(*this);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT cs_command *cs_state::new_command(
|
||||
|
@ -974,10 +1027,12 @@ LIBCUBESCRIPT_EXPORT cs_command *cs_state::new_command(
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
return static_cast<cs_command *>(add_ident(p_state->create<cs_command>(
|
||||
auto *cmd = p_state->create<cs_command_impl>(
|
||||
cs_strref{*p_state, name}, cs_strref{*p_state, args}, nargs,
|
||||
std::move(func))
|
||||
));
|
||||
std::move(func)
|
||||
);
|
||||
add_ident(cmd, cmd);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static inline void cs_do_loop(
|
||||
|
@ -1061,8 +1116,12 @@ void cs_init_lib_base(cs_state &gcs) {
|
|||
rc = false;
|
||||
}
|
||||
ret.set_int(rc);
|
||||
cs_alias_internal::set_alias(cret, cs, result);
|
||||
cs_alias_internal::set_alias(css, cs, tback);
|
||||
cs_alias_internal::set_alias(
|
||||
static_cast<cs_alias_impl *>(cret), cs, result
|
||||
);
|
||||
cs_alias_internal::set_alias(
|
||||
static_cast<cs_alias_impl *>(css), cs, tback
|
||||
);
|
||||
});
|
||||
|
||||
gcs.new_command("?", "ttt", [](auto &, auto args, auto &res) {
|
||||
|
|
Loading…
Reference in New Issue