diff --git a/include/cubescript/cubescript/ident.hh b/include/cubescript/cubescript/ident.hh index dda2c07..d61aa10 100644 --- a/include/cubescript/cubescript/ident.hh +++ b/include/cubescript/cubescript/ident.hh @@ -185,6 +185,9 @@ struct LIBCUBESCRIPT_EXPORT global_var: ident { */ any_value call(span_type 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 diff --git a/src/cs_error.cc b/src/cs_error.cc index 295bef2..4b644c2 100644 --- a/src/cs_error.cc +++ b/src/cs_error.cc @@ -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}; diff --git a/src/cs_ident.cc b/src/cs_ident.cc index a2d3550..f010e78 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -18,23 +18,27 @@ bool ident_is_callable(ident const *id) { return !!static_cast(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(id)->value()); - break; case ident_type::FVAR: - val[2].set_float(static_cast(id)->value()); - break; case ident_type::SVAR: - val[2].set_string(static_cast(id)->value()); + val[2] = static_cast(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(this)->p_storage; +LIBCUBESCRIPT_EXPORT any_value global_var::value() const { + return static_cast(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(this)->p_storage = val; + static_cast(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(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(this)->p_storage = val; + static_cast(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(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(this)->p_storage = val; + static_cast(this)->p_storage.set_string(std::move(val)); } LIBCUBESCRIPT_EXPORT any_value string_var::call( diff --git a/src/cs_ident.hh b/src/cs_ident.hh index fd6cd82..6ec750f 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -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 { diff --git a/src/cs_state.cc b/src/cs_state.cc index a4a5ef4..0c304ca 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -127,7 +127,7 @@ state::state(alloc_func func, void *data) { auto &iv = static_cast(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(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(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(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( static_cast(&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(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( static_cast(&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(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( static_cast(&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(id)->value()); - return val; - } - case ident_type::IVAR: { - any_value val{}; - val.set_integer(static_cast(id)->value()); - return val; - } - case ident_type::FVAR: { - any_value val{}; - val.set_float(static_cast(id)->value()); - return val; - } + case ident_type::SVAR: + case ident_type::IVAR: + case ident_type::FVAR: + return static_cast(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(idr).value()); - break; case ident_type::FVAR: - v.set_float(static_cast(idr).value()); - break; case ident_type::SVAR: - v.set_string(static_cast(idr).value()); + v = static_cast(idr).value(); break; default: return; diff --git a/src/cs_vm.cc b/src/cs_vm.cc index efe1e09..362710f 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -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( - ts.istate->identmap[op >> 8] - )->value()); - continue; case BC_INST_SVAR | BC_RET_INT: - args.emplace_back().set_integer(parse_int( - static_cast( - ts.istate->identmap[op >> 8] - )->value() - )); - continue; case BC_INST_SVAR | BC_RET_FLOAT: - args.emplace_back().set_float(parse_float( - static_cast( - ts.istate->identmap[op >> 8] - )->value() - )); + args.emplace_back() = static_cast( + 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( - ts.istate->identmap[op >> 8] - )->value()); - continue; - case BC_INST_IVAR | BC_RET_STRING: { - auto &v = args.emplace_back(); - v.set_integer(static_cast( - 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( - ts.istate->identmap[op >> 8] - )->value() - )); + args.emplace_back() = static_cast( + 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( - ts.istate->identmap[op >> 8] - )->value()); - continue; - case BC_INST_FVAR | BC_RET_STRING: { - auto &v = args.emplace_back(); - v.set_float(static_cast( - 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( - ts.istate->identmap[op >> 8] - )->value())) - ); + args.emplace_back() = static_cast( + ts.istate->identmap[op >> 8] + )->value(); + force_arg(cs, args.back(), op & BC_INST_RET_MASK); continue; case BC_INST_ALIAS: { diff --git a/tools/edit_linenoise.hh b/tools/edit_linenoise.hh index 5decf4c..641c2c6 100644 --- a/tools/edit_linenoise.hh +++ b/tools/edit_linenoise.hh @@ -50,9 +50,9 @@ inline void init_lineedit(cs::state &cs, std::string_view) { linenoise::SetHintsCallback(ln_hint); } -inline std::optional read_line(cs::state &, cs::string_var &pr) { +inline std::optional 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) { diff --git a/tools/repl.cc b/tools/repl.cc index 7d7b612..11e0bb7 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -320,7 +320,7 @@ int main(int argc, char **argv) { auto &iv = static_cast(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",