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);
/** @brief Get the value of the variable. */
any_value value() const;
protected:
global_var() = default;
};
@ -194,9 +197,6 @@ protected:
* A specialization of cubescript::global_var for integer values.
*/
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.
*
* 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.
*/
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.
*
* 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.
*/
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.
*
* 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();
integer_var *dalias = ts.istate->ivar_dbgalias;
auto dval = std::clamp(
dalias->value(), integer_type(0), integer_type(1000)
dalias->value().get_integer(), integer_type(0), integer_type(1000)
);
if (!dval) {
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;
}
var_impl::var_impl(
ident_type tp, string_ref name, int fl
):
var_impl::var_impl(ident_type tp, string_ref name, int fl):
ident_impl{tp, name, 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):
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):
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(
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);
switch (id->type()) {
case ident_type::IVAR:
val[2].set_integer(static_cast<integer_var *>(id)->value());
break;
case ident_type::FVAR:
val[2].set_float(static_cast<float_var *>(id)->value());
break;
case ident_type::SVAR:
val[2].set_string(static_cast<string_var *>(id)->value());
val[2] = static_cast<global_var *>(id)->value();
break;
default:
return;
@ -110,15 +110,7 @@ void var_changed(thread_state &ts, ident *id, any_value &oldval) {
}, val[0]);
}
void ivar_impl::save_val() {
p_override = p_storage;
}
void fvar_impl::save_val() {
p_override = p_storage;
}
void svar_impl::save_val() {
void var_impl::save_val() {
p_override = std::move(p_storage);
}
@ -288,8 +280,8 @@ LIBCUBESCRIPT_EXPORT any_value global_var::call(
return ident::call(args, cs);
}
LIBCUBESCRIPT_EXPORT integer_type integer_var::value() const {
return static_cast<ivar_impl const *>(this)->p_storage;
LIBCUBESCRIPT_EXPORT any_value global_var::value() const {
return static_cast<var_impl const *>(p_impl)->p_storage;
}
LIBCUBESCRIPT_EXPORT void integer_var::set_value(
@ -307,14 +299,12 @@ LIBCUBESCRIPT_EXPORT void integer_var::set_value(
auto oldv = value();
set_raw_value(val);
if (trigger) {
any_value v;
v.set_integer(oldv);
var_changed(state_p{cs}.ts(), this, v);
var_changed(state_p{cs}.ts(), this, oldv);
}
}
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(
@ -343,10 +333,6 @@ LIBCUBESCRIPT_EXPORT any_value integer_var::call(
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(
state &cs, float_type val, bool do_write, bool trigger
) {
@ -362,14 +348,12 @@ LIBCUBESCRIPT_EXPORT void float_var::set_value(
auto oldv = value();
set_raw_value(val);
if (trigger) {
any_value v;
v.set_float(oldv);
var_changed(state_p{cs}.ts(), this, v);
var_changed(state_p{cs}.ts(), this, oldv);
}
}
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(
@ -378,10 +362,6 @@ LIBCUBESCRIPT_EXPORT any_value float_var::call(
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(
state &cs, string_ref val, bool do_write, bool trigger
) {
@ -397,14 +377,12 @@ LIBCUBESCRIPT_EXPORT void string_var::set_value(
auto oldv = value();
set_raw_value(std::move(val));
if (trigger) {
any_value v;
v.set_string(oldv);
var_changed(state_p{cs}.ts(), this, v);
var_changed(state_p{cs}.ts(), this, oldv);
}
}
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(

View File

@ -76,38 +76,26 @@ bool ident_is_callable(ident const *id);
struct var_impl: ident_impl {
var_impl(ident_type tp, string_ref name, int flags);
virtual void save_val() = 0;
void save_val();
void changed(thread_state &ts);
any_value p_storage{};
any_value p_override{};
};
void var_changed(thread_state &ts, ident *id, any_value &oldval);
struct ivar_impl: var_impl, integer_var {
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 {
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 {
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 {

View File

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

View File

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

View File

@ -50,9 +50,9 @@ inline void init_lineedit(cs::state &cs, std::string_view) {
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;
auto quit = linenoise::Readline(pr.value().data(), line);
auto quit = linenoise::Readline(pr.value().get_string(s).data(), line);
if (quit) {
/* linenoise traps ctrl-c, detect it and let the user exit */
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 nargs = args[4].get_integer();
if (nargs <= 1) {
auto val = iv.value();
auto val = iv.value().get_integer();
if ((val >= 0) && (val < 0xFFFFFF)) {
std::printf(
"%s = %d (0x%.6X: %d, %d, %d)\n",