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
master
Daniel Kolesa 2021-04-25 00:44:36 +02:00
parent f19fd57549
commit 43e6dc9341
5 changed files with 38 additions and 184 deletions

View File

@ -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

View File

@ -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<alias *>(this);
}
LIBCUBESCRIPT_EXPORT alias const *ident::get_alias() const {
if (!is_alias()) {
return nullptr;
}
return static_cast<alias const *>(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<command_impl *>(this);
}
LIBCUBESCRIPT_EXPORT command const *ident::get_command() const {
if (!is_command()) {
return nullptr;
}
return static_cast<command_impl const *>(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<global_var *>(this);
}
LIBCUBESCRIPT_EXPORT global_var const *ident::get_var() const {
if (!is_var()) {
return nullptr;
}
return static_cast<global_var const *>(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<integer_var *>(this);
}
LIBCUBESCRIPT_EXPORT integer_var const *ident::get_ivar() const {
if (!is_ivar()) {
return nullptr;
}
return static_cast<integer_var const *>(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<float_var *>(this);
}
LIBCUBESCRIPT_EXPORT float_var const *ident::get_fvar() const {
if (!is_fvar()) {
return nullptr;
}
return static_cast<float_var const *>(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<string_var *>(this);
}
LIBCUBESCRIPT_EXPORT string_var const *ident::get_svar() const {
if (!is_svar()) {
return nullptr;
}
return static_cast<string_var const *>(this);
}
LIBCUBESCRIPT_EXPORT bool ident::is_overridden(state &cs) const {
switch (get_type()) {
case ident_type::IVAR:

View File

@ -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<integer_var &>(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<float_var &>(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<string_var &>(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<global_var &>(*id).is_read_only()) {
throw error{*this, "variable '%s' is read only", name.data()};
}
}
clear_override(*id);
}

View File

@ -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<alias *>(&cret);
auto *ssa = static_cast<alias *>(&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) {

View File

@ -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<cs::command *>(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<cs::integer_var &>(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)
);