From 6218adb78a7856a40a86f1586eba05b6a370235f Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 6 May 2021 23:13:48 +0200 Subject: [PATCH] remove public type specializations for vars --- include/cubescript/cubescript/ident.hh | 36 +++------------- include/cubescript/cubescript/state.hh | 6 +-- src/cs_error.cc | 2 +- src/cs_ident.cc | 18 -------- src/cs_ident.hh | 14 +----- src/cs_state.cc | 59 ++++++++++---------------- src/cs_state.hh | 4 +- src/cs_vm.cc | 2 +- tools/edit_linenoise.hh | 2 +- tools/repl.cc | 2 +- 10 files changed, 38 insertions(+), 107 deletions(-) diff --git a/include/cubescript/cubescript/ident.hh b/include/cubescript/cubescript/ident.hh index fd86614..29fef0a 100644 --- a/include/cubescript/cubescript/ident.hh +++ b/include/cubescript/cubescript/ident.hh @@ -139,10 +139,13 @@ enum class var_type { OVERRIDABLE /**< @brief Overridable variable. */ }; -/** @brief A global variable. +/** @brief A builtin variable. * - * This represents one of cubescript::integer_var, cubescript::float_var or - * cubescript::string_var as a single interface, with shared operations. + * This represents a strictly typed variable (integer, float or string, + * depending on the value it is created with) that is not subject to + * usual rules like aliases (e.g. scoping). It can have additional + * inherent properties such as being read-only or peresistent, and + * can be monitored via a trigger callback. */ struct LIBCUBESCRIPT_EXPORT builtin_var: ident { /** @brief Get whether the variable is read only. @@ -214,33 +217,6 @@ protected: builtin_var() = default; }; -/** @brief An integer variable. - * - * A specialization of cubescript::builtin_var for integer values. - */ -struct LIBCUBESCRIPT_EXPORT integer_var: builtin_var { -protected: - integer_var() = default; -}; - -/** @brief A float variable. - * - * A specialization of cubescript::builtin_var for float values. - */ -struct LIBCUBESCRIPT_EXPORT float_var: builtin_var { -protected: - float_var() = default; -}; - -/** @brief A string variable. - * - * A specialization of cubescript::builtin_var for string values. - */ -struct LIBCUBESCRIPT_EXPORT string_var: builtin_var { -protected: - string_var() = default; -}; - /** @brief An alias. * * An alias is an ident that is created inside the language, for example diff --git a/include/cubescript/cubescript/state.hh b/include/cubescript/cubescript/state.hh index 56996c8..e8868b2 100644 --- a/include/cubescript/cubescript/state.hh +++ b/include/cubescript/cubescript/state.hh @@ -175,7 +175,7 @@ struct LIBCUBESCRIPT_EXPORT state { * @param v the default value * @throw cubescript::error in case of redefinition or invalid name */ - integer_var &new_var( + builtin_var &new_var( std::string_view n, integer_type v, bool read_only = false, var_type vtp = var_type::DEFAULT ); @@ -186,7 +186,7 @@ struct LIBCUBESCRIPT_EXPORT state { * @param v the default value * @throw cubescript::error in case of redefinition or invalid name */ - float_var &new_var( + builtin_var &new_var( std::string_view n, float_type v, bool read_only = false, var_type vtp = var_type::DEFAULT ); @@ -197,7 +197,7 @@ struct LIBCUBESCRIPT_EXPORT state { * @param v the default value * @throw cubescript::error in case of redefinition or invalid name */ - string_var &new_var( + builtin_var &new_var( std::string_view n, std::string_view v, bool read_only = false, var_type vtp = var_type::DEFAULT ); diff --git a/src/cs_error.cc b/src/cs_error.cc index 4b644c2..2dd0a49 100644 --- a/src/cs_error.cc +++ b/src/cs_error.cc @@ -85,7 +85,7 @@ LIBCUBESCRIPT_EXPORT char *error::request_buf( LIBCUBESCRIPT_EXPORT stack_state error::save_stack(state &cs) { auto &ts = state_p{cs}.ts(); - integer_var *dalias = ts.istate->ivar_dbgalias; + builtin_var *dalias = ts.istate->ivar_dbgalias; auto dval = std::clamp( dalias->value().get_integer(), integer_type(0), integer_type(1000) ); diff --git a/src/cs_ident.cc b/src/cs_ident.cc index f88f058..c79a2df 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -22,24 +22,6 @@ 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.set_integer(v); -} - -fvar_impl::fvar_impl(string_ref name, float_type v, int fl): - 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.set_string(v); -} - alias_impl::alias_impl( state &, string_ref name, string_ref a, int fl ): diff --git a/src/cs_ident.hh b/src/cs_ident.hh index 6ec750f..9458651 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -73,7 +73,7 @@ struct ident_impl { bool ident_is_callable(ident const *id); -struct var_impl: ident_impl { +struct var_impl: ident_impl, builtin_var { var_impl(ident_type tp, string_ref name, int flags); void save_val(); @@ -86,18 +86,6 @@ struct var_impl: ident_impl { 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); -}; - -struct fvar_impl: var_impl, float_var { - fvar_impl(string_ref n, float_type v, int flags); -}; - -struct svar_impl: var_impl, string_var { - svar_impl(string_ref n, string_ref v, int flags); -}; - struct alias_impl: ident_impl, alias { alias_impl(state &cs, string_ref n, string_ref a, int flags); alias_impl(state &cs, string_ref n, std::string_view a, int flags); diff --git a/src/cs_state.cc b/src/cs_state.cc index bb286c4..3ae54b1 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -124,7 +124,7 @@ state::state(alloc_func func, void *data) { statep->cmd_ivar = &new_command("//ivar_builtin", "$i#", []( auto &cs, auto args, auto & ) { - auto &iv = static_cast(args[0].get_ident(cs)); + 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().get_integer()); @@ -137,7 +137,7 @@ state::state(alloc_func func, void *data) { statep->cmd_fvar = &new_command("//fvar_builtin", "$f#", []( auto &cs, auto args, auto & ) { - auto &fv = static_cast(args[0].get_ident(cs)); + auto &fv = static_cast(args[0].get_ident(cs)); if (args[2].get_integer() <= 1) { auto val = fv.value().get_float(); std::printf("%s = ", fv.name().data()); @@ -155,7 +155,7 @@ state::state(alloc_func func, void *data) { statep->cmd_svar = &new_command("//svar_builtin", "$s#", []( auto &cs, auto args, auto & ) { - auto &sv = static_cast(args[0].get_ident(cs)); + auto &sv = static_cast(args[0].get_ident(cs)); if (args[2].get_integer() <= 1) { auto val = sv.value().get_string(cs); if (val.view().find('"') == std::string_view::npos) { @@ -349,33 +349,15 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) { ast.flags &= ~IDENT_FLAG_OVERRIDDEN; return; } - case ident_type::IVAR: { - ivar_impl &iv = static_cast(id); - any_value oldv = iv.value(); - iv.p_storage = std::move(iv.p_override); - var_changed(*p_tstate, &id, oldv); - static_cast( - static_cast(&iv) - )->p_flags &= ~IDENT_FLAG_OVERRIDDEN; - return; - } - case ident_type::FVAR: { - fvar_impl &fv = static_cast(id); - any_value oldv = fv.value(); - fv.p_storage = std::move(fv.p_override); - var_changed(*p_tstate, &id, oldv); - static_cast( - static_cast(&fv) - )->p_flags &= ~IDENT_FLAG_OVERRIDDEN; - return; - } + case ident_type::IVAR: + case ident_type::FVAR: case ident_type::SVAR: { - svar_impl &sv = static_cast(id); - any_value oldv = sv.value(); - sv.p_storage = std::move(sv.p_override); + auto &v = static_cast(id); + any_value oldv = v.value(); + v.p_storage = std::move(v.p_override); var_changed(*p_tstate, &id, oldv); - static_cast( - static_cast(&sv) + static_cast( + static_cast(&v) )->p_flags &= ~IDENT_FLAG_OVERRIDDEN; return; } @@ -423,12 +405,13 @@ static void var_name_check( } } -LIBCUBESCRIPT_EXPORT integer_var &state::new_var( +LIBCUBESCRIPT_EXPORT builtin_var &state::new_var( std::string_view n, integer_type v, bool read_only, var_type vtp ) { - auto *iv = p_tstate->istate->create( - string_ref{*this, n}, v, var_flags(read_only, vtp) + auto *iv = p_tstate->istate->create( + ident_type::IVAR, string_ref{*this, n},var_flags(read_only, vtp) ); + iv->p_storage.set_integer(v); try { var_name_check(*this, p_tstate->istate->get_ident(n), n); } catch (...) { @@ -439,12 +422,13 @@ LIBCUBESCRIPT_EXPORT integer_var &state::new_var( return *iv; } -LIBCUBESCRIPT_EXPORT float_var &state::new_var( +LIBCUBESCRIPT_EXPORT builtin_var &state::new_var( std::string_view n, float_type v, bool read_only, var_type vtp ) { - auto *fv = p_tstate->istate->create( - string_ref{*this, n}, v, var_flags(read_only, vtp) + auto *fv = p_tstate->istate->create( + ident_type::FVAR, string_ref{*this, n}, var_flags(read_only, vtp) ); + fv->p_storage.set_float(v); try { var_name_check(*this, p_tstate->istate->get_ident(n), n); } catch (...) { @@ -455,12 +439,13 @@ LIBCUBESCRIPT_EXPORT float_var &state::new_var( return *fv; } -LIBCUBESCRIPT_EXPORT string_var &state::new_var( +LIBCUBESCRIPT_EXPORT builtin_var &state::new_var( std::string_view n, std::string_view v, bool read_only, var_type vtp ) { - auto *sv = p_tstate->istate->create( - string_ref{*this, n}, string_ref{*this, v}, var_flags(read_only, vtp) + auto *sv = p_tstate->istate->create( + ident_type::SVAR, string_ref{*this, n}, var_flags(read_only, vtp) ); + sv->p_storage.set_string(v, *this); try { var_name_check(*this, p_tstate->istate->get_ident(n), n); } catch (...) { diff --git a/src/cs_state.hh b/src/cs_state.hh index 128aadb..e721239 100644 --- a/src/cs_state.hh +++ b/src/cs_state.hh @@ -55,8 +55,8 @@ struct internal_state { ident *id_dummy; - integer_var *ivar_numargs; - integer_var *ivar_dbgalias; + builtin_var *ivar_numargs; + builtin_var *ivar_dbgalias; command *cmd_ivar; command *cmd_fvar; diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 8ee683e..6d1839d 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -155,7 +155,7 @@ bool exec_alias( } /* excess arguments get ignored (make error maybe?) */ callargs = std::min(callargs, MAX_ARGUMENTS); - integer_var *anargs = ts.istate->ivar_numargs; + builtin_var *anargs = ts.istate->ivar_numargs; argset uargs{}; std::size_t noff = ts.idstack.size(); for(std::size_t i = 0; i < callargs; i++) { diff --git a/tools/edit_linenoise.hh b/tools/edit_linenoise.hh index 641c2c6..0dd6c5e 100644 --- a/tools/edit_linenoise.hh +++ b/tools/edit_linenoise.hh @@ -50,7 +50,7 @@ inline void init_lineedit(cs::state &cs, std::string_view) { linenoise::SetHintsCallback(ln_hint); } -inline std::optional read_line(cs::state &s, cs::string_var &pr) { +inline std::optional read_line(cs::state &s, cs::builtin_var &pr) { std::string line; auto quit = linenoise::Readline(pr.value().get_string(s).data(), line); if (quit) { diff --git a/tools/repl.cc b/tools/repl.cc index f601486..5fd4886 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -317,7 +317,7 @@ int main(int argc, char **argv) { * to be set, but you may also not be using standard i/o and so on */ gcs.new_command("//ivar", "$iii#", [](auto &css, auto args, auto &) { - auto &iv = static_cast(args[0].get_ident(css)); + auto &iv = static_cast(args[0].get_ident(css)); auto nargs = args[4].get_integer(); if (nargs <= 1) { auto val = iv.value().get_integer();