From 43e6dc9341ea8bc10e53482e85f5644473b87e90 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Sun, 25 Apr 2021 00:44:36 +0200 Subject: [PATCH] remove get_ utilities from ident this is not a good api (it prevents extensibility, requires handling errors twice to be safe - once on user side, once internally - and so on); just cast it --- include/cubescript/cubescript/ident.hh | 69 --------------------- src/cs_ident.cc | 84 -------------------------- src/cs_state.cc | 33 +++++----- src/lib_base.cc | 18 +++--- tools/repl.cc | 18 +++--- 5 files changed, 38 insertions(+), 184 deletions(-) diff --git a/include/cubescript/cubescript/ident.hh b/include/cubescript/cubescript/ident.hh index c30d458..d83bbb7 100644 --- a/include/cubescript/cubescript/ident.hh +++ b/include/cubescript/cubescript/ident.hh @@ -31,13 +31,6 @@ enum class ident_type { SPECIAL /**< @brief Other (internal unexposed type). */ }; -struct global_var; -struct integer_var; -struct float_var; -struct string_var; -struct alias; -struct command; - /** @brief The ident structure. * * Every object within the Cubescript language is represented with an ident. @@ -80,26 +73,12 @@ struct LIBCUBESCRIPT_EXPORT ident { */ bool is_alias() const; - /** @brief Try to convert this to cubescript::alias. - * - * @return A pointer to the alias if it is one, or `nullptr`. - */ - alias *get_alias(); - alias const *get_alias() const; - /** @brief Check if the ident is a cubescript::command. * * Effectively like `get_type() == ident_type::COMMAND`. */ bool is_command() const; - /** @brief Try to convert this to cubescript::command. - * - * @return A pointer to the command if it is one, or `nullptr`. - */ - command *get_command(); - command const *get_command() const; - /** @brief Check if the ident is a special ident. * * Effectively like `get_type() == ident_type::SPECIAL`. @@ -113,72 +92,24 @@ struct LIBCUBESCRIPT_EXPORT ident { */ bool is_var() const; - /** @brief Try to convert this to cubescript::global_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - global_var *get_var(); - - /** @brief Try to convert this to cubescript::global_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - global_var const *get_var() const; - /** @brief Check if the ident is a cubescript::integer_var. * * Effectively like `get_type() == ident_type::IVAR`. */ bool is_ivar() const; - /** @brief Try to convert this to cubescript::integer_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - integer_var *get_ivar(); - - /** @brief Try to convert this to cubescript::integer_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - integer_var const *get_ivar() const; - /** @brief Check if the ident is a cubescript::float_var. * * Effectively like `get_type() == ident_type::FVAR`. */ bool is_fvar() const; - /** @brief Try to convert this to cubescript::float_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - float_var *get_fvar(); - - /** @brief Try to convert this to cubescript::float_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - float_var const *get_fvar() const; - /** @brief Check if the ident is a cubescript::string_var. * * Effectively like `get_type() == ident_type::SVAR`. */ bool is_svar() const; - /** @brief Try to convert this to cubescript::string_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - string_var *get_svar(); - - /** @brief Try to convert this to cubescript::string_var. - * - * @return A pointer to the var if it is one, or `nullptr`. - */ - string_var const *get_svar() const; - /** @brief Get if the ident is overridden. * * This can be true for aliases or builtins. When an alias or a builtin diff --git a/src/cs_ident.cc b/src/cs_ident.cc index d4de5c4..b50db78 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -182,38 +182,10 @@ LIBCUBESCRIPT_EXPORT bool ident::is_alias() const { return get_type() == ident_type::ALIAS; } -LIBCUBESCRIPT_EXPORT alias *ident::get_alias() { - if (!is_alias()) { - return nullptr; - } - return static_cast(this); -} - -LIBCUBESCRIPT_EXPORT alias const *ident::get_alias() const { - if (!is_alias()) { - return nullptr; - } - return static_cast(this); -} - LIBCUBESCRIPT_EXPORT bool ident::is_command() const { return get_type() == ident_type::COMMAND; } -LIBCUBESCRIPT_EXPORT command *ident::get_command() { - if (!is_command()) { - return nullptr; - } - return static_cast(this); -} - -LIBCUBESCRIPT_EXPORT command const *ident::get_command() const { - if (!is_command()) { - return nullptr; - } - return static_cast(this); -} - LIBCUBESCRIPT_EXPORT bool ident::is_special() const { return get_type() == ident_type::SPECIAL; } @@ -230,74 +202,18 @@ LIBCUBESCRIPT_EXPORT bool ident::is_var() const { return false; } -LIBCUBESCRIPT_EXPORT global_var *ident::get_var() { - if (!is_var()) { - return nullptr; - } - return static_cast(this); -} - -LIBCUBESCRIPT_EXPORT global_var const *ident::get_var() const { - if (!is_var()) { - return nullptr; - } - return static_cast(this); -} - LIBCUBESCRIPT_EXPORT bool ident::is_ivar() const { return get_type() == ident_type::IVAR; } -LIBCUBESCRIPT_EXPORT integer_var *ident::get_ivar() { - if (!is_ivar()) { - return nullptr; - } - return static_cast(this); -} - -LIBCUBESCRIPT_EXPORT integer_var const *ident::get_ivar() const { - if (!is_ivar()) { - return nullptr; - } - return static_cast(this); -} - LIBCUBESCRIPT_EXPORT bool ident::is_fvar() const { return get_type() == ident_type::FVAR; } -LIBCUBESCRIPT_EXPORT float_var *ident::get_fvar() { - if (!is_fvar()) { - return nullptr; - } - return static_cast(this); -} - -LIBCUBESCRIPT_EXPORT float_var const *ident::get_fvar() const { - if (!is_fvar()) { - return nullptr; - } - return static_cast(this); -} - LIBCUBESCRIPT_EXPORT bool ident::is_svar() const { return get_type() == ident_type::SVAR; } -LIBCUBESCRIPT_EXPORT string_var *ident::get_svar() { - if (!is_svar()) { - return nullptr; - } - return static_cast(this); -} - -LIBCUBESCRIPT_EXPORT string_var const *ident::get_svar() const { - if (!is_svar()) { - return nullptr; - } - return static_cast(this); -} - LIBCUBESCRIPT_EXPORT bool ident::is_overridden(state &cs) const { switch (get_type()) { case ident_type::IVAR: diff --git a/src/cs_state.cc b/src/cs_state.cc index 4c66b39..13d07f5 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -124,23 +124,23 @@ state::state(alloc_func func, void *data) { statep->cmd_ivar = &new_command("//ivar_builtin", "$iN", []( auto &cs, auto args, auto & ) { - auto *iv = args[0].get_ident(cs).get_ivar(); + auto &iv = static_cast(args[0].get_ident(cs)); if (args[2].get_integer() <= 1) { - std::printf("%s = ", iv->get_name().data()); - std::printf(INTEGER_FORMAT, iv->get_value()); + std::printf("%s = ", iv.get_name().data()); + std::printf(INTEGER_FORMAT, iv.get_value()); std::printf("\n"); } else { - iv->set_value(cs, args[1].get_integer()); + iv.set_value(cs, args[1].get_integer()); } }); statep->cmd_fvar = &new_command("//fvar_builtin", "$fN", []( auto &cs, auto args, auto & ) { - auto *fv = args[0].get_ident(cs).get_fvar(); + auto &fv = static_cast(args[0].get_ident(cs)); if (args[2].get_integer() <= 1) { - auto val = fv->get_value(); - std::printf("%s = ", fv->get_name().data()); + auto val = fv.get_value(); + std::printf("%s = ", fv.get_name().data()); if (std::floor(val) == val) { std::printf(ROUND_FLOAT_FORMAT, val); } else { @@ -148,23 +148,23 @@ state::state(alloc_func func, void *data) { } std::printf("\n"); } else { - fv->set_value(cs, args[1].get_float()); + fv.set_value(cs, args[1].get_float()); } }); statep->cmd_svar = &new_command("//svar_builtin", "$sN", []( auto &cs, auto args, auto & ) { - auto *sv = args[0].get_ident(cs).get_svar(); + auto &sv = static_cast(args[0].get_ident(cs)); if (args[2].get_integer() <= 1) { - auto val = sv->get_value(); + auto val = sv.get_value(); if (val.view().find('"') == std::string_view::npos) { - std::printf("%s = \"%s\"\n", sv->get_name().data(), val.data()); + std::printf("%s = \"%s\"\n", sv.get_name().data(), val.data()); } else { - std::printf("%s = [%s]\n", sv->get_name().data(), val.data()); + std::printf("%s = [%s]\n", sv.get_name().data(), val.data()); } } else { - sv->set_value(cs, args[1].get_string(cs)); + sv.set_value(cs, args[1].get_string(cs)); } }); @@ -483,9 +483,10 @@ LIBCUBESCRIPT_EXPORT void state::reset_var(std::string_view name) { if (!id) { throw error{*this, "variable '%s' does not exist", name.data()}; } - auto *var = id->get_var(); - if (var && var->is_read_only()) { - throw error{*this, "variable '%s' is read only", name.data()}; + if (id->is_var()) { + if (static_cast(*id).is_read_only()) { + throw error{*this, "variable '%s' is read only", name.data()}; + } } clear_override(*id); } diff --git a/src/lib_base.cc b/src/lib_base.cc index b308952..34303c6 100644 --- a/src/lib_base.cc +++ b/src/lib_base.cc @@ -69,11 +69,13 @@ LIBCUBESCRIPT_EXPORT void std_init_base(state &gcs) { }); new_cmd_quiet(gcs, "pcall", "err", [](auto &cs, auto args, auto &ret) { - alias *cret = args[1].get_ident(cs).get_alias(); - alias *css = args[2].get_ident(cs).get_alias(); - if (!cret || !css) { - ret.set_integer(0); - return; + auto &cret = args[1].get_ident(cs); + auto &css = args[2].get_ident(cs); + if (!cret.is_alias()) { + throw error{cs, "'%s' is not an alias", cret.get_name().data()}; + } + if (!css.is_alias()) { + throw error{cs, "'%s' is not an alias", css.get_name().data()}; } any_value result{}, tback{}; bool rc = true; @@ -90,8 +92,10 @@ LIBCUBESCRIPT_EXPORT void std_init_base(state &gcs) { } ret.set_integer(rc); auto &ts = state_p{cs}.ts(); - ts.get_astack(cret).set_alias(cret, ts, result); - ts.get_astack(css).set_alias(css, ts, tback); + auto *reta = static_cast(&cret); + auto *ssa = static_cast(&css); + ts.get_astack(reta).set_alias(reta, ts, result); + ts.get_astack(ssa).set_alias(ssa, ts, tback); }); new_cmd_quiet(gcs, "?", "ttt", [](auto &, auto args, auto &res) { diff --git a/tools/repl.cc b/tools/repl.cc index ce6473e..99e9a8e 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -159,7 +159,9 @@ inline cs::command *get_hint_cmd(cs::state &cs, std::string_view buf) { } if (!buf.empty()) { auto cmd = cs.get_ident(buf); - return cmd ? cmd->get_command() : nullptr; + if (cmd && cmd->is_command()) { + return static_cast(cmd); + } } return nullptr; } @@ -325,30 +327,30 @@ 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", "$iiiN", [](auto &css, auto args, auto &) { - auto *iv = args[0].get_ident(css).get_ivar(); + auto &iv = static_cast(args[0].get_ident(css)); auto nargs = args[4].get_integer(); if (nargs <= 1) { - auto val = iv->get_value(); + auto val = iv.get_value(); if ((val >= 0) && (val < 0xFFFFFF)) { std::printf( "%s = %d (0x%.6X: %d, %d, %d)\n", - iv->get_name().data(), val, val, + iv.get_name().data(), val, val, (val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF ); } else { - std::printf("%s = %d\n", iv->get_name().data(), val); + std::printf("%s = %d\n", iv.get_name().data(), val); } return; } if (nargs == 2) { - iv->set_value(css, args[1].get_integer()); + iv.set_value(css, args[1].get_integer()); } else if (nargs == 3) { - iv->set_value( + iv.set_value( css, (args[1].get_integer() << 8) | (args[2].get_integer() << 16) ); } else { - iv->set_value( + iv.set_value( css, args[1].get_integer() | (args[2].get_integer() << 8) | (args[3].get_integer() << 16) );