use any_value for var storage and return it from value()

master
Daniel Kolesa 2021-05-06 03:34:25 +02:00
parent 344bba07f3
commit a57072fb73
8 changed files with 63 additions and 156 deletions

View File

@ -185,6 +185,9 @@ struct LIBCUBESCRIPT_EXPORT global_var: ident {
*/ */
any_value call(span_type<any_value> args, state &cs); any_value call(span_type<any_value> args, state &cs);
/** @brief Get the value of the variable. */
any_value value() const;
protected: protected:
global_var() = default; global_var() = default;
}; };
@ -194,9 +197,6 @@ protected:
* A specialization of cubescript::global_var for integer values. * A specialization of cubescript::global_var for integer values.
*/ */
struct LIBCUBESCRIPT_EXPORT integer_var: global_var { struct LIBCUBESCRIPT_EXPORT integer_var: global_var {
/** @brief Get the value of the variable. */
integer_type value() const;
/** @brief Set the value of the variable. /** @brief Set the value of the variable.
* *
* If read only, an error is raised. If `do_write` is `false`, nothing * If read only, an error is raised. If `do_write` is `false`, nothing
@ -231,9 +231,6 @@ protected:
* A specialization of cubescript::global_var for float values. * A specialization of cubescript::global_var for float values.
*/ */
struct LIBCUBESCRIPT_EXPORT float_var: global_var { struct LIBCUBESCRIPT_EXPORT float_var: global_var {
/** @brief Get the value of the variable. */
float_type value() const;
/** @brief Set the value of the variable. /** @brief Set the value of the variable.
* *
* If read only, an error is raised. If `do_write` is `false`, nothing * If read only, an error is raised. If `do_write` is `false`, nothing
@ -268,9 +265,6 @@ protected:
* A specialization of cubescript::global_var for string values. * A specialization of cubescript::global_var for string values.
*/ */
struct LIBCUBESCRIPT_EXPORT string_var: global_var { struct LIBCUBESCRIPT_EXPORT string_var: global_var {
/** @brief Get the value of the variable. */
string_ref value() const;
/** @brief Set the value of the variable. /** @brief Set the value of the variable.
* *
* If read only, an error is raised. If `do_write` is `false`, nothing * If read only, an error is raised. If `do_write` is `false`, nothing

View File

@ -87,7 +87,7 @@ LIBCUBESCRIPT_EXPORT stack_state error::save_stack(state &cs) {
auto &ts = state_p{cs}.ts(); auto &ts = state_p{cs}.ts();
integer_var *dalias = ts.istate->ivar_dbgalias; integer_var *dalias = ts.istate->ivar_dbgalias;
auto dval = std::clamp( auto dval = std::clamp(
dalias->value(), integer_type(0), integer_type(1000) dalias->value().get_integer(), integer_type(0), integer_type(1000)
); );
if (!dval) { if (!dval) {
return stack_state{cs, nullptr, !!ts.callstack}; return stack_state{cs, nullptr, !!ts.callstack};

View File

@ -18,23 +18,27 @@ bool ident_is_callable(ident const *id) {
return !!static_cast<command_impl const *>(id)->p_cb_cftv; return !!static_cast<command_impl const *>(id)->p_cb_cftv;
} }
var_impl::var_impl( var_impl::var_impl(ident_type tp, string_ref name, int fl):
ident_type tp, string_ref name, int fl
):
ident_impl{tp, name, fl} ident_impl{tp, name, fl}
{} {}
ivar_impl::ivar_impl(string_ref name, integer_type v, int fl): ivar_impl::ivar_impl(string_ref name, integer_type v, int fl):
var_impl{ident_type::IVAR, name, fl}, p_storage{v}, p_override{v} var_impl{ident_type::IVAR, name, fl}
{} {
p_storage.set_integer(v);
}
fvar_impl::fvar_impl(string_ref name, float_type v, int fl): fvar_impl::fvar_impl(string_ref name, float_type v, int fl):
var_impl{ident_type::FVAR, name, fl}, p_storage{v}, p_override{v} var_impl{ident_type::FVAR, name, fl}
{} {
p_storage.set_float(v);
}
svar_impl::svar_impl(string_ref name, string_ref v, int fl): svar_impl::svar_impl(string_ref name, string_ref v, int fl):
var_impl{ident_type::SVAR, name, fl}, p_storage{v}, p_override{v} var_impl{ident_type::SVAR, name, fl}
{} {
p_storage.set_string(v);
}
alias_impl::alias_impl( alias_impl::alias_impl(
state &, string_ref name, string_ref a, int fl state &, string_ref name, string_ref a, int fl
@ -94,13 +98,9 @@ void var_changed(thread_state &ts, ident *id, any_value &oldval) {
val[1] = std::move(oldval); val[1] = std::move(oldval);
switch (id->type()) { switch (id->type()) {
case ident_type::IVAR: case ident_type::IVAR:
val[2].set_integer(static_cast<integer_var *>(id)->value());
break;
case ident_type::FVAR: case ident_type::FVAR:
val[2].set_float(static_cast<float_var *>(id)->value());
break;
case ident_type::SVAR: case ident_type::SVAR:
val[2].set_string(static_cast<string_var *>(id)->value()); val[2] = static_cast<global_var *>(id)->value();
break; break;
default: default:
return; return;
@ -110,15 +110,7 @@ void var_changed(thread_state &ts, ident *id, any_value &oldval) {
}, val[0]); }, val[0]);
} }
void ivar_impl::save_val() { void var_impl::save_val() {
p_override = p_storage;
}
void fvar_impl::save_val() {
p_override = p_storage;
}
void svar_impl::save_val() {
p_override = std::move(p_storage); p_override = std::move(p_storage);
} }
@ -288,8 +280,8 @@ LIBCUBESCRIPT_EXPORT any_value global_var::call(
return ident::call(args, cs); return ident::call(args, cs);
} }
LIBCUBESCRIPT_EXPORT integer_type integer_var::value() const { LIBCUBESCRIPT_EXPORT any_value global_var::value() const {
return static_cast<ivar_impl const *>(this)->p_storage; return static_cast<var_impl const *>(p_impl)->p_storage;
} }
LIBCUBESCRIPT_EXPORT void integer_var::set_value( LIBCUBESCRIPT_EXPORT void integer_var::set_value(
@ -307,14 +299,12 @@ LIBCUBESCRIPT_EXPORT void integer_var::set_value(
auto oldv = value(); auto oldv = value();
set_raw_value(val); set_raw_value(val);
if (trigger) { if (trigger) {
any_value v; var_changed(state_p{cs}.ts(), this, oldv);
v.set_integer(oldv);
var_changed(state_p{cs}.ts(), this, v);
} }
} }
LIBCUBESCRIPT_EXPORT void integer_var::set_raw_value(integer_type val) { LIBCUBESCRIPT_EXPORT void integer_var::set_raw_value(integer_type val) {
static_cast<ivar_impl *>(this)->p_storage = val; static_cast<ivar_impl *>(this)->p_storage.set_integer(val);
} }
inline any_value call_var( inline any_value call_var(
@ -343,10 +333,6 @@ LIBCUBESCRIPT_EXPORT any_value integer_var::call(
return call_var(*this, state_p{cs}.ts().istate->cmd_ivar, args, cs); return call_var(*this, state_p{cs}.ts().istate->cmd_ivar, args, cs);
} }
LIBCUBESCRIPT_EXPORT float_type float_var::value() const {
return static_cast<fvar_impl const *>(this)->p_storage;
}
LIBCUBESCRIPT_EXPORT void float_var::set_value( LIBCUBESCRIPT_EXPORT void float_var::set_value(
state &cs, float_type val, bool do_write, bool trigger state &cs, float_type val, bool do_write, bool trigger
) { ) {
@ -362,14 +348,12 @@ LIBCUBESCRIPT_EXPORT void float_var::set_value(
auto oldv = value(); auto oldv = value();
set_raw_value(val); set_raw_value(val);
if (trigger) { if (trigger) {
any_value v; var_changed(state_p{cs}.ts(), this, oldv);
v.set_float(oldv);
var_changed(state_p{cs}.ts(), this, v);
} }
} }
LIBCUBESCRIPT_EXPORT void float_var::set_raw_value(float_type val) { LIBCUBESCRIPT_EXPORT void float_var::set_raw_value(float_type val) {
static_cast<fvar_impl *>(this)->p_storage = val; static_cast<fvar_impl *>(this)->p_storage.set_float(val);
} }
LIBCUBESCRIPT_EXPORT any_value float_var::call( LIBCUBESCRIPT_EXPORT any_value float_var::call(
@ -378,10 +362,6 @@ LIBCUBESCRIPT_EXPORT any_value float_var::call(
return call_var(*this, state_p{cs}.ts().istate->cmd_fvar, args, cs); return call_var(*this, state_p{cs}.ts().istate->cmd_fvar, args, cs);
} }
LIBCUBESCRIPT_EXPORT string_ref string_var::value() const {
return static_cast<svar_impl const *>(this)->p_storage;
}
LIBCUBESCRIPT_EXPORT void string_var::set_value( LIBCUBESCRIPT_EXPORT void string_var::set_value(
state &cs, string_ref val, bool do_write, bool trigger state &cs, string_ref val, bool do_write, bool trigger
) { ) {
@ -397,14 +377,12 @@ LIBCUBESCRIPT_EXPORT void string_var::set_value(
auto oldv = value(); auto oldv = value();
set_raw_value(std::move(val)); set_raw_value(std::move(val));
if (trigger) { if (trigger) {
any_value v; var_changed(state_p{cs}.ts(), this, oldv);
v.set_string(oldv);
var_changed(state_p{cs}.ts(), this, v);
} }
} }
LIBCUBESCRIPT_EXPORT void string_var::set_raw_value(string_ref val) { LIBCUBESCRIPT_EXPORT void string_var::set_raw_value(string_ref val) {
static_cast<svar_impl *>(this)->p_storage = val; static_cast<svar_impl *>(this)->p_storage.set_string(std::move(val));
} }
LIBCUBESCRIPT_EXPORT any_value string_var::call( LIBCUBESCRIPT_EXPORT any_value string_var::call(

View File

@ -76,38 +76,26 @@ bool ident_is_callable(ident const *id);
struct var_impl: ident_impl { struct var_impl: ident_impl {
var_impl(ident_type tp, string_ref name, int flags); var_impl(ident_type tp, string_ref name, int flags);
virtual void save_val() = 0; void save_val();
void changed(thread_state &ts); void changed(thread_state &ts);
any_value p_storage{};
any_value p_override{};
}; };
void var_changed(thread_state &ts, ident *id, any_value &oldval); void var_changed(thread_state &ts, ident *id, any_value &oldval);
struct ivar_impl: var_impl, integer_var { struct ivar_impl: var_impl, integer_var {
ivar_impl(string_ref n, integer_type v, int flags); ivar_impl(string_ref n, integer_type v, int flags);
void save_val();
integer_type p_storage;
integer_type p_override;
}; };
struct fvar_impl: var_impl, float_var { struct fvar_impl: var_impl, float_var {
fvar_impl(string_ref n, float_type v, int flags); fvar_impl(string_ref n, float_type v, int flags);
void save_val();
float_type p_storage;
float_type p_override;
}; };
struct svar_impl: var_impl, string_var { struct svar_impl: var_impl, string_var {
svar_impl(string_ref n, string_ref v, int flags); svar_impl(string_ref n, string_ref v, int flags);
void save_val();
string_ref p_storage;
string_ref p_override;
}; };
struct alias_impl: ident_impl, alias { struct alias_impl: ident_impl, alias {

View File

@ -127,7 +127,7 @@ state::state(alloc_func func, void *data) {
auto &iv = static_cast<integer_var &>(args[0].get_ident(cs)); auto &iv = static_cast<integer_var &>(args[0].get_ident(cs));
if (args[2].get_integer() <= 1) { if (args[2].get_integer() <= 1) {
std::printf("%s = ", iv.name().data()); std::printf("%s = ", iv.name().data());
std::printf(INTEGER_FORMAT, iv.value()); std::printf(INTEGER_FORMAT, iv.value().get_integer());
std::printf("\n"); std::printf("\n");
} else { } else {
iv.set_value(cs, args[1].get_integer()); iv.set_value(cs, args[1].get_integer());
@ -139,7 +139,7 @@ state::state(alloc_func func, void *data) {
) { ) {
auto &fv = static_cast<float_var &>(args[0].get_ident(cs)); auto &fv = static_cast<float_var &>(args[0].get_ident(cs));
if (args[2].get_integer() <= 1) { if (args[2].get_integer() <= 1) {
auto val = fv.value(); auto val = fv.value().get_float();
std::printf("%s = ", fv.name().data()); std::printf("%s = ", fv.name().data());
if (std::floor(val) == val) { if (std::floor(val) == val) {
std::printf(ROUND_FLOAT_FORMAT, val); std::printf(ROUND_FLOAT_FORMAT, val);
@ -157,7 +157,7 @@ state::state(alloc_func func, void *data) {
) { ) {
auto &sv = static_cast<string_var &>(args[0].get_ident(cs)); auto &sv = static_cast<string_var &>(args[0].get_ident(cs));
if (args[2].get_integer() <= 1) { if (args[2].get_integer() <= 1) {
auto val = sv.value(); auto val = sv.value().get_string(cs);
if (val.view().find('"') == std::string_view::npos) { if (val.view().find('"') == std::string_view::npos) {
std::printf("%s = \"%s\"\n", sv.name().data(), val.data()); std::printf("%s = \"%s\"\n", sv.name().data(), val.data());
} else { } else {
@ -350,10 +350,9 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
return; return;
} }
case ident_type::IVAR: { case ident_type::IVAR: {
any_value oldv;
ivar_impl &iv = static_cast<ivar_impl &>(id); ivar_impl &iv = static_cast<ivar_impl &>(id);
oldv.set_integer(iv.value()); any_value oldv = iv.value();
iv.set_raw_value(iv.p_override); iv.p_storage = std::move(iv.p_override);
var_changed(*p_tstate, &id, oldv); var_changed(*p_tstate, &id, oldv);
static_cast<ivar_impl *>( static_cast<ivar_impl *>(
static_cast<integer_var *>(&iv) static_cast<integer_var *>(&iv)
@ -361,10 +360,9 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
return; return;
} }
case ident_type::FVAR: { case ident_type::FVAR: {
any_value oldv;
fvar_impl &fv = static_cast<fvar_impl &>(id); fvar_impl &fv = static_cast<fvar_impl &>(id);
oldv.set_float(fv.value()); any_value oldv = fv.value();
fv.set_raw_value(fv.p_override); fv.p_storage = std::move(fv.p_override);
var_changed(*p_tstate, &id, oldv); var_changed(*p_tstate, &id, oldv);
static_cast<fvar_impl *>( static_cast<fvar_impl *>(
static_cast<float_var *>(&fv) static_cast<float_var *>(&fv)
@ -372,10 +370,9 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
return; return;
} }
case ident_type::SVAR: { case ident_type::SVAR: {
any_value oldv;
svar_impl &sv = static_cast<svar_impl &>(id); svar_impl &sv = static_cast<svar_impl &>(id);
oldv.set_string(sv.value()); any_value oldv = sv.value();
sv.set_raw_value(sv.p_override); sv.p_storage = std::move(sv.p_override);
var_changed(*p_tstate, &id, oldv); var_changed(*p_tstate, &id, oldv);
static_cast<svar_impl *>( static_cast<svar_impl *>(
static_cast<string_var *>(&sv) static_cast<string_var *>(&sv)
@ -532,21 +529,10 @@ LIBCUBESCRIPT_EXPORT any_value state::lookup_value(std::string_view name) {
} }
return ast->node->val_s.get_plain(); return ast->node->val_s.get_plain();
} }
case ident_type::SVAR: { case ident_type::SVAR:
any_value val{}; case ident_type::IVAR:
val.set_string(static_cast<string_var *>(id)->value()); case ident_type::FVAR:
return val; return static_cast<global_var *>(id)->value();
}
case ident_type::IVAR: {
any_value val{};
val.set_integer(static_cast<integer_var *>(id)->value());
return val;
}
case ident_type::FVAR: {
any_value val{};
val.set_float(static_cast<float_var *>(id)->value());
return val;
}
case ident_type::COMMAND: { case ident_type::COMMAND: {
any_value val{}; any_value val{};
/* make sure value stack gets restored */ /* make sure value stack gets restored */
@ -591,13 +577,9 @@ LIBCUBESCRIPT_EXPORT void state::touch_value(std::string_view name) {
any_value v; any_value v;
switch (idr.type()) { switch (idr.type()) {
case ident_type::IVAR: case ident_type::IVAR:
v.set_integer(static_cast<integer_var &>(idr).value());
break;
case ident_type::FVAR: case ident_type::FVAR:
v.set_float(static_cast<float_var &>(idr).value());
break;
case ident_type::SVAR: case ident_type::SVAR:
v.set_string(static_cast<string_var &>(idr).value()); v = static_cast<global_var &>(idr).value();
break; break;
default: default:
return; return;

View File

@ -167,7 +167,7 @@ bool exec_alias(
st.val_s = std::move(args[offset + i]); st.val_s = std::move(args[offset + i]);
uargs[i] = true; uargs[i] = true;
} }
auto oldargs = anargs->value(); auto oldargs = anargs->value().get_integer();
auto oldflags = ts.ident_flags; auto oldflags = ts.ident_flags;
ts.ident_flags = aast.flags; ts.ident_flags = aast.flags;
anargs->set_raw_value(integer_type(callargs)); anargs->set_raw_value(integer_type(callargs));
@ -718,67 +718,32 @@ std::uint32_t *vm_exec(
case BC_INST_SVAR | BC_RET_STRING: case BC_INST_SVAR | BC_RET_STRING:
case BC_INST_SVAR | BC_RET_NULL: case BC_INST_SVAR | BC_RET_NULL:
args.emplace_back().set_string(static_cast<string_var *>(
ts.istate->identmap[op >> 8]
)->value());
continue;
case BC_INST_SVAR | BC_RET_INT: case BC_INST_SVAR | BC_RET_INT:
args.emplace_back().set_integer(parse_int(
static_cast<string_var *>(
ts.istate->identmap[op >> 8]
)->value()
));
continue;
case BC_INST_SVAR | BC_RET_FLOAT: case BC_INST_SVAR | BC_RET_FLOAT:
args.emplace_back().set_float(parse_float( args.emplace_back() = static_cast<string_var *>(
static_cast<string_var *>( ts.istate->identmap[op >> 8]
ts.istate->identmap[op >> 8] )->value();
)->value() force_arg(cs, args.back(), op & BC_INST_RET_MASK);
));
continue; continue;
case BC_INST_IVAR | BC_RET_INT: case BC_INST_IVAR | BC_RET_INT:
case BC_INST_IVAR | BC_RET_NULL: case BC_INST_IVAR | BC_RET_NULL:
args.emplace_back().set_integer(static_cast<integer_var *>( case BC_INST_IVAR | BC_RET_STRING:
ts.istate->identmap[op >> 8]
)->value());
continue;
case BC_INST_IVAR | BC_RET_STRING: {
auto &v = args.emplace_back();
v.set_integer(static_cast<integer_var *>(
ts.istate->identmap[op >> 8]
)->value());
v.force_string(cs);
continue;
}
case BC_INST_IVAR | BC_RET_FLOAT: case BC_INST_IVAR | BC_RET_FLOAT:
args.emplace_back().set_float(float_type( args.emplace_back() = static_cast<integer_var *>(
static_cast<integer_var *>( ts.istate->identmap[op >> 8]
ts.istate->identmap[op >> 8] )->value();
)->value() force_arg(cs, args.back(), op & BC_INST_RET_MASK);
));
continue; continue;
case BC_INST_FVAR | BC_RET_FLOAT: case BC_INST_FVAR | BC_RET_FLOAT:
case BC_INST_FVAR | BC_RET_NULL: case BC_INST_FVAR | BC_RET_NULL:
args.emplace_back().set_float(static_cast<float_var *>( case BC_INST_FVAR | BC_RET_STRING:
ts.istate->identmap[op >> 8]
)->value());
continue;
case BC_INST_FVAR | BC_RET_STRING: {
auto &v = args.emplace_back();
v.set_float(static_cast<float_var *>(
ts.istate->identmap[op >> 8]
)->value());
v.force_string(cs);
continue;
}
case BC_INST_FVAR | BC_RET_INT: case BC_INST_FVAR | BC_RET_INT:
args.emplace_back().set_integer( args.emplace_back() = static_cast<float_var *>(
integer_type(std::floor(static_cast<float_var *>( ts.istate->identmap[op >> 8]
ts.istate->identmap[op >> 8] )->value();
)->value())) force_arg(cs, args.back(), op & BC_INST_RET_MASK);
);
continue; continue;
case BC_INST_ALIAS: { case BC_INST_ALIAS: {

View File

@ -50,9 +50,9 @@ inline void init_lineedit(cs::state &cs, std::string_view) {
linenoise::SetHintsCallback(ln_hint); linenoise::SetHintsCallback(ln_hint);
} }
inline std::optional<std::string> read_line(cs::state &, cs::string_var &pr) { inline std::optional<std::string> read_line(cs::state &s, cs::string_var &pr) {
std::string line; std::string line;
auto quit = linenoise::Readline(pr.value().data(), line); auto quit = linenoise::Readline(pr.value().get_string(s).data(), line);
if (quit) { if (quit) {
/* linenoise traps ctrl-c, detect it and let the user exit */ /* linenoise traps ctrl-c, detect it and let the user exit */
if (errno == EAGAIN) { if (errno == EAGAIN) {

View File

@ -320,7 +320,7 @@ int main(int argc, char **argv) {
auto &iv = static_cast<cs::integer_var &>(args[0].get_ident(css)); auto &iv = static_cast<cs::integer_var &>(args[0].get_ident(css));
auto nargs = args[4].get_integer(); auto nargs = args[4].get_integer();
if (nargs <= 1) { if (nargs <= 1) {
auto val = iv.value(); auto val = iv.value().get_integer();
if ((val >= 0) && (val < 0xFFFFFF)) { if ((val >= 0) && (val < 0xFFFFFF)) {
std::printf( std::printf(
"%s = %d (0x%.6X: %d, %d, %d)\n", "%s = %d (0x%.6X: %d, %d, %d)\n",