diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 6caeb9e..fe54826 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -253,6 +253,8 @@ struct LIBCUBESCRIPT_EXPORT global_var: ident { var_type get_variable_type() const; + void save(state &cs); + protected: global_var() = default; }; diff --git a/src/cs_ident.cc b/src/cs_ident.cc index 5ae9c66..f79cbbf 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -82,6 +82,18 @@ command_impl::command_impl( p_cargs{args}, p_cb_cftv{std::move(f)}, p_numargs{nargs} {} +void ivar_impl::save_val() { + p_override = p_storage; +} + +void fvar_impl::save_val() { + p_override = p_storage; +} + +void svar_impl::save_val() { + p_override = std::move(p_storage); +} + void command_impl::call(state &cs, std::span args, any_value &ret) { auto &ts = *cs.thread_pointer(); auto idstsz = ts.idstack.size(); @@ -317,6 +329,23 @@ LIBCUBESCRIPT_EXPORT var_type global_var::get_variable_type() const { } } +LIBCUBESCRIPT_EXPORT void global_var::save(state &cs) { + auto &ts = *cs.thread_pointer(); + if ((ts.ident_flags & IDENT_FLAG_OVERRIDDEN) || is_overridable()) { + if (p_impl->p_flags & IDENT_FLAG_PERSIST) { + throw error{ + cs, "cannot override persistent variable '%s'", + get_name().data() + }; + } + if (!(p_impl->p_flags & IDENT_FLAG_OVERRIDDEN)) { + static_cast(p_impl)->save_val(); + } + } else { + p_impl->p_flags &= IDENT_FLAG_OVERRIDDEN; + } +} + LIBCUBESCRIPT_EXPORT integer_type integer_var::get_value() const { return static_cast(this)->p_storage; } diff --git a/src/cs_ident.hh b/src/cs_ident.hh index ad609a3..0009168 100644 --- a/src/cs_ident.hh +++ b/src/cs_ident.hh @@ -75,11 +75,15 @@ 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; }; 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; }; @@ -87,6 +91,8 @@ struct ivar_impl: var_impl, integer_var { 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; }; @@ -94,6 +100,8 @@ struct fvar_impl: var_impl, float_var { 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; }; diff --git a/tools/repl.cc b/tools/repl.cc index cba5828..3b9a879 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -341,6 +341,7 @@ int main(int argc, char **argv) { css, "variable '%s' is read only", iv->get_name().data() }; } + iv->save(css); if (nargs == 2) { iv->set_value(args[1].get_int()); } else if (nargs == 3) { @@ -370,6 +371,7 @@ int main(int argc, char **argv) { css, "variable '%s' is read only", fv->get_name().data() }; } else { + fv->save(css); fv->set_value(args[1].get_float()); } }); @@ -389,6 +391,7 @@ int main(int argc, char **argv) { css, "variable '%s' is read only", sv->get_name().data() }; } else { + sv->save(css); sv->set_value(args[1].get_str()); } });