rea-add proper handling of variable overrides
parent
6777eb73d5
commit
3d91cf2ee7
|
@ -345,15 +345,22 @@ struct LIBCUBESCRIPT_EXPORT state {
|
|||
|
||||
void init_libs(int libs = LIB_ALL);
|
||||
|
||||
void clear_override(ident &id);
|
||||
void clear_overrides();
|
||||
|
||||
integer_var *new_ivar(
|
||||
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
|
||||
);
|
||||
float_var *new_fvar(
|
||||
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
|
||||
);
|
||||
string_var *new_svar(
|
||||
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
|
||||
);
|
||||
void reset_var(std::string_view name);
|
||||
|
||||
template<typename F>
|
||||
command *new_command(
|
||||
|
|
|
@ -288,39 +288,119 @@ LIBCUBESCRIPT_EXPORT std::span<ident const *> state::get_idents() const {
|
|||
return std::span<ident const *>{ptr, p_tstate->istate->identmap.size()};
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
|
||||
if (!id.is_overridden(*this)) {
|
||||
return;
|
||||
}
|
||||
switch (id.get_type()) {
|
||||
case ident_type::ALIAS: {
|
||||
auto &ast = p_tstate->get_astack(static_cast<alias *>(&id));
|
||||
ast.node->val_s.set_str("");
|
||||
ast.node->code = bcode_ref{};
|
||||
ast.flags &= ~IDENT_FLAG_OVERRIDDEN;
|
||||
return;
|
||||
}
|
||||
case ident_type::IVAR: {
|
||||
ivar_impl &iv = static_cast<ivar_impl &>(id);
|
||||
iv.set_value(iv.p_override);
|
||||
//iv.changed(*this);
|
||||
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);
|
||||
fv.set_value(fv.p_override);
|
||||
//fv.changed(*this);
|
||||
static_cast<fvar_impl *>(
|
||||
static_cast<float_var *>(&fv)
|
||||
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
|
||||
return;
|
||||
}
|
||||
case ident_type::SVAR: {
|
||||
svar_impl &sv = static_cast<svar_impl &>(id);
|
||||
sv.set_value(sv.p_override);
|
||||
//sv.changed(*this);
|
||||
static_cast<svar_impl *>(
|
||||
static_cast<string_var *>(&sv)
|
||||
)->p_flags &= ~IDENT_FLAG_OVERRIDDEN;
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void state::clear_overrides() {
|
||||
for (auto &p: p_tstate->istate->idents) {
|
||||
clear_override(*(p.second));
|
||||
}
|
||||
}
|
||||
|
||||
inline int var_flags(bool read_only, var_type vtp) {
|
||||
int ret = 0;
|
||||
if (read_only) {
|
||||
ret |= IDENT_FLAG_READONLY;
|
||||
}
|
||||
switch (vtp) {
|
||||
case var_type::PERSISTENT:
|
||||
ret |= IDENT_FLAG_PERSIST;
|
||||
break;
|
||||
case var_type::OVERRIDABLE:
|
||||
ret |= IDENT_FLAG_OVERRIDE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT integer_var *state::new_ivar(
|
||||
std::string_view n, integer_type v, bool read_only
|
||||
std::string_view n, integer_type v, bool read_only, var_type vtp
|
||||
) {
|
||||
auto *iv = p_tstate->istate->create<ivar_impl>(
|
||||
string_ref{p_tstate->istate, n}, v,
|
||||
read_only ? IDENT_FLAG_READONLY : 0
|
||||
var_flags(read_only, vtp)
|
||||
);
|
||||
p_tstate->istate->add_ident(iv, iv);
|
||||
return iv;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT float_var *state::new_fvar(
|
||||
std::string_view n, float_type v, bool read_only
|
||||
std::string_view n, float_type v, bool read_only, var_type vtp
|
||||
) {
|
||||
auto *fv = p_tstate->istate->create<fvar_impl>(
|
||||
string_ref{p_tstate->istate, n}, v,
|
||||
read_only ? IDENT_FLAG_READONLY : 0
|
||||
var_flags(read_only, vtp)
|
||||
);
|
||||
p_tstate->istate->add_ident(fv, fv);
|
||||
return fv;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT string_var *state::new_svar(
|
||||
std::string_view n, std::string_view v, bool read_only
|
||||
std::string_view n, std::string_view v, bool read_only, var_type vtp
|
||||
) {
|
||||
auto *sv = p_tstate->istate->create<svar_impl>(
|
||||
string_ref{p_tstate->istate, n}, string_ref{p_tstate->istate, v},
|
||||
read_only ? IDENT_FLAG_READONLY : 0
|
||||
var_flags(read_only, vtp)
|
||||
);
|
||||
p_tstate->istate->add_ident(sv, sv);
|
||||
return sv;
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void state::reset_var(std::string_view name) {
|
||||
ident *id = get_ident(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()};
|
||||
}
|
||||
clear_override(*id);
|
||||
}
|
||||
|
||||
LIBCUBESCRIPT_EXPORT void state::set_alias(
|
||||
std::string_view name, any_value v
|
||||
) {
|
||||
|
|
|
@ -312,6 +312,10 @@ end:
|
|||
}
|
||||
});
|
||||
|
||||
gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &) {
|
||||
cs.reset_var(args[0].get_str());
|
||||
});
|
||||
|
||||
gcs.new_command("alias", "st", [](auto &cs, auto args, auto &) {
|
||||
cs.set_alias(args[0].get_str(), args[1]);
|
||||
});
|
||||
|
|
|
@ -320,7 +320,7 @@ int main(int argc, char **argv) {
|
|||
cs::state gcs;
|
||||
gcs.init_libs();
|
||||
|
||||
gcs.new_command("//ivar", "$iiiN", [](auto &, auto args, auto &) {
|
||||
gcs.new_command("//ivar", "$iiiN", [](auto &css, auto args, auto &) {
|
||||
auto *iv = args[0].get_ident()->get_ivar();
|
||||
auto nargs = args[4].get_int();
|
||||
if (nargs <= 1) {
|
||||
|
@ -334,7 +334,14 @@ int main(int argc, char **argv) {
|
|||
} else {
|
||||
std::printf("%s = %d\n", iv->get_name().data(), val);
|
||||
}
|
||||
} else if (nargs == 2) {
|
||||
return;
|
||||
}
|
||||
if (iv->is_read_only()) {
|
||||
throw cs::error{
|
||||
css, "variable '%s' is read only", iv->get_name().data()
|
||||
};
|
||||
}
|
||||
if (nargs == 2) {
|
||||
iv->set_value(args[1].get_int());
|
||||
} else if (nargs == 3) {
|
||||
iv->set_value(
|
||||
|
@ -348,7 +355,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
});
|
||||
|
||||
gcs.new_command("//fvar", "$fN", [](auto &, auto args, auto &) {
|
||||
gcs.new_command("//fvar", "$fN", [](auto &css, auto args, auto &) {
|
||||
auto *fv = args[0].get_ident()->get_fvar();
|
||||
auto nargs = args[2].get_int();
|
||||
if (nargs <= 1) {
|
||||
|
@ -358,12 +365,16 @@ int main(int argc, char **argv) {
|
|||
} else {
|
||||
std::printf("%s = %.7g\n", fv->get_name().data(), val);
|
||||
}
|
||||
} else if (fv->is_read_only()) {
|
||||
throw cs::error{
|
||||
css, "variable '%s' is read only", fv->get_name().data()
|
||||
};
|
||||
} else {
|
||||
fv->set_value(args[1].get_float());
|
||||
}
|
||||
});
|
||||
|
||||
gcs.new_command("//svar", "$sN", [](auto &, auto args, auto &) {
|
||||
gcs.new_command("//svar", "$sN", [](auto &css, auto args, auto &) {
|
||||
auto sv = args[0].get_ident()->get_svar();
|
||||
auto nargs = args[2].get_int();
|
||||
if (nargs <= 1) {
|
||||
|
@ -373,6 +384,10 @@ int main(int argc, char **argv) {
|
|||
} else {
|
||||
std::printf("%s = [%s]\n", sv->get_name().data(), val.data());
|
||||
}
|
||||
} else if (sv->is_read_only()) {
|
||||
throw cs::error{
|
||||
css, "variable '%s' is read only", sv->get_name().data()
|
||||
};
|
||||
} else {
|
||||
sv->set_value(args[1].get_str());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue