remove public type specializations for vars

master
Daniel Kolesa 2021-05-06 23:13:48 +02:00
parent 6fede13b97
commit 6218adb78a
10 changed files with 38 additions and 107 deletions

View File

@ -139,10 +139,13 @@ enum class var_type {
OVERRIDABLE /**< @brief Overridable variable. */ OVERRIDABLE /**< @brief Overridable variable. */
}; };
/** @brief A global variable. /** @brief A builtin variable.
* *
* This represents one of cubescript::integer_var, cubescript::float_var or * This represents a strictly typed variable (integer, float or string,
* cubescript::string_var as a single interface, with shared operations. * 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 { struct LIBCUBESCRIPT_EXPORT builtin_var: ident {
/** @brief Get whether the variable is read only. /** @brief Get whether the variable is read only.
@ -214,33 +217,6 @@ protected:
builtin_var() = default; 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. /** @brief An alias.
* *
* An alias is an ident that is created inside the language, for example * An alias is an ident that is created inside the language, for example

View File

@ -175,7 +175,7 @@ struct LIBCUBESCRIPT_EXPORT state {
* @param v the default value * @param v the default value
* @throw cubescript::error in case of redefinition or invalid name * @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, std::string_view n, integer_type v, bool read_only = false,
var_type vtp = var_type::DEFAULT var_type vtp = var_type::DEFAULT
); );
@ -186,7 +186,7 @@ struct LIBCUBESCRIPT_EXPORT state {
* @param v the default value * @param v the default value
* @throw cubescript::error in case of redefinition or invalid name * @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, std::string_view n, float_type v, bool read_only = false,
var_type vtp = var_type::DEFAULT var_type vtp = var_type::DEFAULT
); );
@ -197,7 +197,7 @@ struct LIBCUBESCRIPT_EXPORT state {
* @param v the default value * @param v the default value
* @throw cubescript::error in case of redefinition or invalid name * @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, std::string_view n, std::string_view v, bool read_only = false,
var_type vtp = var_type::DEFAULT var_type vtp = var_type::DEFAULT
); );

View File

@ -85,7 +85,7 @@ LIBCUBESCRIPT_EXPORT char *error::request_buf(
LIBCUBESCRIPT_EXPORT stack_state error::save_stack(state &cs) { LIBCUBESCRIPT_EXPORT stack_state error::save_stack(state &cs) {
auto &ts = state_p{cs}.ts(); auto &ts = state_p{cs}.ts();
integer_var *dalias = ts.istate->ivar_dbgalias; builtin_var *dalias = ts.istate->ivar_dbgalias;
auto dval = std::clamp( auto dval = std::clamp(
dalias->value().get_integer(), integer_type(0), integer_type(1000) dalias->value().get_integer(), integer_type(0), integer_type(1000)
); );

View File

@ -22,24 +22,6 @@ var_impl::var_impl(ident_type tp, string_ref name, int fl):
ident_impl{tp, name, 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( alias_impl::alias_impl(
state &, string_ref name, string_ref a, int fl state &, string_ref name, string_ref a, int fl
): ):

View File

@ -73,7 +73,7 @@ struct ident_impl {
bool ident_is_callable(ident const *id); 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); var_impl(ident_type tp, string_ref name, int flags);
void save_val(); void save_val();
@ -86,18 +86,6 @@ struct var_impl: ident_impl {
void var_changed(thread_state &ts, ident *id, any_value &oldval); 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 { 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, string_ref a, int flags);
alias_impl(state &cs, string_ref n, std::string_view a, int flags); alias_impl(state &cs, string_ref n, std::string_view a, int flags);

View File

@ -124,7 +124,7 @@ state::state(alloc_func func, void *data) {
statep->cmd_ivar = &new_command("//ivar_builtin", "$i#", []( statep->cmd_ivar = &new_command("//ivar_builtin", "$i#", [](
auto &cs, auto args, auto & auto &cs, auto args, auto &
) { ) {
auto &iv = static_cast<integer_var &>(args[0].get_ident(cs)); auto &iv = static_cast<builtin_var &>(args[0].get_ident(cs));
if (args[2].get_integer() <= 1) { if (args[2].get_integer() <= 1) {
std::printf("%s = ", iv.name().data()); std::printf("%s = ", iv.name().data());
std::printf(INTEGER_FORMAT, iv.value().get_integer()); 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#", []( statep->cmd_fvar = &new_command("//fvar_builtin", "$f#", [](
auto &cs, auto args, auto & auto &cs, auto args, auto &
) { ) {
auto &fv = static_cast<float_var &>(args[0].get_ident(cs)); auto &fv = static_cast<builtin_var &>(args[0].get_ident(cs));
if (args[2].get_integer() <= 1) { if (args[2].get_integer() <= 1) {
auto val = fv.value().get_float(); auto val = fv.value().get_float();
std::printf("%s = ", fv.name().data()); 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#", []( statep->cmd_svar = &new_command("//svar_builtin", "$s#", [](
auto &cs, auto args, auto & auto &cs, auto args, auto &
) { ) {
auto &sv = static_cast<string_var &>(args[0].get_ident(cs)); auto &sv = static_cast<builtin_var &>(args[0].get_ident(cs));
if (args[2].get_integer() <= 1) { if (args[2].get_integer() <= 1) {
auto val = sv.value().get_string(cs); auto val = sv.value().get_string(cs);
if (val.view().find('"') == std::string_view::npos) { 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; ast.flags &= ~IDENT_FLAG_OVERRIDDEN;
return; return;
} }
case ident_type::IVAR: { case ident_type::IVAR:
ivar_impl &iv = static_cast<ivar_impl &>(id); case ident_type::FVAR:
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)
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
return;
}
case ident_type::FVAR: {
fvar_impl &fv = static_cast<fvar_impl &>(id);
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)
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
return;
}
case ident_type::SVAR: { case ident_type::SVAR: {
svar_impl &sv = static_cast<svar_impl &>(id); auto &v = static_cast<var_impl &>(id);
any_value oldv = sv.value(); any_value oldv = v.value();
sv.p_storage = std::move(sv.p_override); v.p_storage = std::move(v.p_override);
var_changed(*p_tstate, &id, oldv); var_changed(*p_tstate, &id, oldv);
static_cast<svar_impl *>( static_cast<var_impl *>(
static_cast<string_var *>(&sv) static_cast<builtin_var *>(&v)
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN; )->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
return; 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 std::string_view n, integer_type v, bool read_only, var_type vtp
) { ) {
auto *iv = p_tstate->istate->create<ivar_impl>( auto *iv = p_tstate->istate->create<var_impl>(
string_ref{*this, n}, v, var_flags(read_only, vtp) ident_type::IVAR, string_ref{*this, n},var_flags(read_only, vtp)
); );
iv->p_storage.set_integer(v);
try { try {
var_name_check(*this, p_tstate->istate->get_ident(n), n); var_name_check(*this, p_tstate->istate->get_ident(n), n);
} catch (...) { } catch (...) {
@ -439,12 +422,13 @@ LIBCUBESCRIPT_EXPORT integer_var &state::new_var(
return *iv; 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 std::string_view n, float_type v, bool read_only, var_type vtp
) { ) {
auto *fv = p_tstate->istate->create<fvar_impl>( auto *fv = p_tstate->istate->create<var_impl>(
string_ref{*this, n}, v, var_flags(read_only, vtp) ident_type::FVAR, string_ref{*this, n}, var_flags(read_only, vtp)
); );
fv->p_storage.set_float(v);
try { try {
var_name_check(*this, p_tstate->istate->get_ident(n), n); var_name_check(*this, p_tstate->istate->get_ident(n), n);
} catch (...) { } catch (...) {
@ -455,12 +439,13 @@ LIBCUBESCRIPT_EXPORT float_var &state::new_var(
return *fv; 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 std::string_view n, std::string_view v, bool read_only, var_type vtp
) { ) {
auto *sv = p_tstate->istate->create<svar_impl>( auto *sv = p_tstate->istate->create<var_impl>(
string_ref{*this, n}, string_ref{*this, v}, var_flags(read_only, vtp) ident_type::SVAR, string_ref{*this, n}, var_flags(read_only, vtp)
); );
sv->p_storage.set_string(v, *this);
try { try {
var_name_check(*this, p_tstate->istate->get_ident(n), n); var_name_check(*this, p_tstate->istate->get_ident(n), n);
} catch (...) { } catch (...) {

View File

@ -55,8 +55,8 @@ struct internal_state {
ident *id_dummy; ident *id_dummy;
integer_var *ivar_numargs; builtin_var *ivar_numargs;
integer_var *ivar_dbgalias; builtin_var *ivar_dbgalias;
command *cmd_ivar; command *cmd_ivar;
command *cmd_fvar; command *cmd_fvar;

View File

@ -155,7 +155,7 @@ bool exec_alias(
} }
/* excess arguments get ignored (make error maybe?) */ /* excess arguments get ignored (make error maybe?) */
callargs = std::min(callargs, MAX_ARGUMENTS); callargs = std::min(callargs, MAX_ARGUMENTS);
integer_var *anargs = ts.istate->ivar_numargs; builtin_var *anargs = ts.istate->ivar_numargs;
argset uargs{}; argset uargs{};
std::size_t noff = ts.idstack.size(); std::size_t noff = ts.idstack.size();
for(std::size_t i = 0; i < callargs; i++) { for(std::size_t i = 0; i < callargs; i++) {

View File

@ -50,7 +50,7 @@ inline void init_lineedit(cs::state &cs, std::string_view) {
linenoise::SetHintsCallback(ln_hint); linenoise::SetHintsCallback(ln_hint);
} }
inline std::optional<std::string> read_line(cs::state &s, cs::string_var &pr) { inline std::optional<std::string> read_line(cs::state &s, cs::builtin_var &pr) {
std::string line; std::string line;
auto quit = linenoise::Readline(pr.value().get_string(s).data(), line); auto quit = linenoise::Readline(pr.value().get_string(s).data(), line);
if (quit) { if (quit) {

View File

@ -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 * 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 &) { gcs.new_command("//ivar", "$iii#", [](auto &css, auto args, auto &) {
auto &iv = static_cast<cs::integer_var &>(args[0].get_ident(css)); auto &iv = static_cast<cs::builtin_var &>(args[0].get_ident(css));
auto nargs = args[4].get_integer(); auto nargs = args[4].get_integer();
if (nargs <= 1) { if (nargs <= 1) {
auto val = iv.value().get_integer(); auto val = iv.value().get_integer();