throw CsErrorException where appropriate (robust error handling everywhere)

master
Daniel Kolesa 2016-09-15 21:15:54 +02:00
parent 377e9d7702
commit f12197bbe5
4 changed files with 30 additions and 67 deletions

View File

@ -482,7 +482,7 @@ struct OSTD_EXPORT CsState {
CsIdentRange get_idents(); CsIdentRange get_idents();
CsConstIdentRange get_idents() const; CsConstIdentRange get_idents() const;
bool reset_var(ostd::ConstCharRange name); void reset_var(ostd::ConstCharRange name);
void touch_var(ostd::ConstCharRange name); void touch_var(ostd::ConstCharRange name);
CsString run_str(CsBytecode *code); CsString run_str(CsBytecode *code);

View File

@ -69,7 +69,7 @@ bool CsStackState::gap() const {
return p_gap; return p_gap;
} }
CsStackState cs_save_stack(CsState &cs) { CsStackState CsErrorException::save_stack(CsState &cs) {
CsIvar *dalias = static_cast<CsIvar *>(cs.p_state->identmap[DbgaliasIdx]); CsIvar *dalias = static_cast<CsIvar *>(cs.p_state->identmap[DbgaliasIdx]);
if (!dalias->get_value()) { if (!dalias->get_value()) {
return CsStackState(cs, nullptr, !!cs.p_callstack); return CsStackState(cs, nullptr, !!cs.p_callstack);
@ -106,10 +106,6 @@ CsStackState cs_save_stack(CsState &cs) {
return CsStackState(cs, ret, total > dalias->get_value()); return CsStackState(cs, ret, total > dalias->get_value());
} }
CsStackState CsErrorException::save_stack(CsState &cs) {
return cs_save_stack(cs);
}
ostd::ConstCharRange CsErrorException::save_msg( ostd::ConstCharRange CsErrorException::save_msg(
CsState &cs, ostd::ConstCharRange msg CsState &cs, ostd::ConstCharRange msg
) { ) {

View File

@ -109,15 +109,6 @@ template<typename T>
constexpr ostd::Size CsTypeStorageSize = constexpr ostd::Size CsTypeStorageSize =
(sizeof(T) - 1) / sizeof(ostd::Uint32) + 1; (sizeof(T) - 1) / sizeof(ostd::Uint32) + 1;
CsStackState cs_save_stack(CsState &cs);
template<typename ...A>
void cs_debug_code(CsState &cs, ostd::ConstCharRange fmt, A &&...args) {
cs.get_err().writefln(fmt, ostd::forward<A>(args)...);
auto st = cs_save_stack(cs);
cscript::util::print_stack(cs.get_err().iter(), st);
}
struct GenState { struct GenState {
CsState &cs; CsState &cs;
CsVector<ostd::Uint32> code; CsVector<ostd::Uint32> code;

View File

@ -470,10 +470,9 @@ CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
CsIdent *id = get_ident(name); CsIdent *id = get_ident(name);
if (!id) { if (!id) {
if (cs_check_num(name)) { if (cs_check_num(name)) {
cs_debug_code( throw CsErrorException(
*this, "number %s is not a valid identifier name", name *this, "number %s is not a valid identifier name", name
); );
return p_state->identmap[DummyIdx];
} }
id = add_ident(create<CsAlias>(name, flags)); id = add_ident(create<CsAlias>(name, flags));
} }
@ -553,17 +552,15 @@ CsSvar *CsState::new_svar(
)->get_svar(); )->get_svar();
} }
bool CsState::reset_var(ostd::ConstCharRange name) { void CsState::reset_var(ostd::ConstCharRange name) {
CsIdent *id = get_ident(name); CsIdent *id = get_ident(name);
if (!id) { if (!id) {
return false; throw CsErrorException(*this, "variable %s does not exist", name);
} }
if (id->get_flags() & CsIdfReadOnly) { if (id->get_flags() & CsIdfReadOnly) {
cs_debug_code(*this, "variable %s is read only", id->get_name()); throw CsErrorException(*this, "variable %s is read only", name);
return false;
} }
clear_override(*id); clear_override(*id);
return true;
} }
void CsState::touch_var(ostd::ConstCharRange name) { void CsState::touch_var(ostd::ConstCharRange name) {
@ -596,14 +593,13 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue v) {
set_var_str_checked(static_cast<CsSvar *>(id), v.get_str()); set_var_str_checked(static_cast<CsSvar *>(id), v.get_str());
break; break;
default: default:
cs_debug_code( throw CsErrorException(
*this, "cannot redefine builtin %s with an alias", *this, "cannot redefine builtin %s with an alias",
id->get_name() id->get_name()
); );
break;
} }
} else if (cs_check_num(name)) { } else if (cs_check_num(name)) {
cs_debug_code(*this, "cannot alias number %s", name); throw CsErrorException(*this, "cannot alias number %s", name);
} else { } else {
add_ident(create<CsAlias>(name, ostd::move(v), identflags)); add_ident(create<CsAlias>(name, ostd::move(v), identflags));
} }
@ -726,13 +722,12 @@ int CsIdent::get_index() const {
} }
template<typename SF> template<typename SF>
static inline bool cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) { static inline void cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) {
if ((cs.identflags & CsIdfOverridden) || (vflags & CsIdfOverride)) { if ((cs.identflags & CsIdfOverridden) || (vflags & CsIdfOverride)) {
if (vflags & CsIdfPersist) { if (vflags & CsIdfPersist) {
cs_debug_code( throw CsErrorException(
cs, "cannot override persistent variable '%s'", v->get_name() cs, "cannot override persistent variable '%s'", v->get_name()
); );
return false;
} }
if (!(vflags & CsIdfOverridden)) { if (!(vflags & CsIdfOverridden)) {
sf(); sf();
@ -743,7 +738,6 @@ static inline bool cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) {
vflags &= ~CsIdfOverridden; vflags &= ~CsIdfOverridden;
} }
} }
return true;
} }
void CsState::set_var_int( void CsState::set_var_int(
@ -754,13 +748,10 @@ void CsState::set_var_int(
return; return;
} }
CsIvar *iv = static_cast<CsIvar *>(id); CsIvar *iv = static_cast<CsIvar *>(id);
bool success = cs_override_var( cs_override_var(
*this, iv, iv->p_flags, *this, iv, iv->p_flags,
[&iv]() { iv->p_overrideval = iv->get_value(); } [&iv]() { iv->p_overrideval = iv->get_value(); }
); );
if (!success) {
return;
}
if (doclamp) { if (doclamp) {
iv->set_value(ostd::clamp(v, iv->get_val_min(), iv->get_val_max())); iv->set_value(ostd::clamp(v, iv->get_val_min(), iv->get_val_max()));
} else { } else {
@ -779,13 +770,10 @@ void CsState::set_var_float(
return; return;
} }
CsFvar *fv = static_cast<CsFvar *>(id); CsFvar *fv = static_cast<CsFvar *>(id);
bool success = cs_override_var( cs_override_var(
*this, fv, fv->p_flags, *this, fv, fv->p_flags,
[&fv]() { fv->p_overrideval = fv->get_value(); } [&fv]() { fv->p_overrideval = fv->get_value(); }
); );
if (!success) {
return;
}
if (doclamp) { if (doclamp) {
fv->set_value(ostd::clamp(v, fv->get_val_min(), fv->get_val_max())); fv->set_value(ostd::clamp(v, fv->get_val_min(), fv->get_val_max()));
} else { } else {
@ -804,13 +792,10 @@ void CsState::set_var_str(
return; return;
} }
CsSvar *sv = static_cast<CsSvar *>(id); CsSvar *sv = static_cast<CsSvar *>(id);
bool success = cs_override_var( cs_override_var(
*this, sv, sv->p_flags, *this, sv, sv->p_flags,
[&sv]() { sv->p_overrideval = sv->get_value(); } [&sv]() { sv->p_overrideval = sv->get_value(); }
); );
if (!success) {
return;
}
sv->set_value(v); sv->set_value(v);
if (dofunc) { if (dofunc) {
sv->changed(*this); sv->changed(*this);
@ -893,7 +878,7 @@ CsInt cs_clamp_var(CsState &cs, CsIvar *iv, CsInt v) {
} else { } else {
return v; return v;
} }
cs_debug_code( throw CsErrorException(
cs, cs,
(iv->get_flags() & CsIdfHex) (iv->get_flags() & CsIdfHex)
? ( ? (
@ -904,21 +889,18 @@ CsInt cs_clamp_var(CsState &cs, CsIvar *iv, CsInt v) {
: "valid range for '%s' is %d..%d", : "valid range for '%s' is %d..%d",
iv->get_name(), iv->get_val_min(), iv->get_val_max() iv->get_name(), iv->get_val_min(), iv->get_val_max()
); );
return v;
} }
void CsState::set_var_int_checked(CsIvar *iv, CsInt v) { void CsState::set_var_int_checked(CsIvar *iv, CsInt v) {
if (iv->get_flags() & CsIdfReadOnly) { if (iv->get_flags() & CsIdfReadOnly) {
cs_debug_code(*this, "variable '%s' is read only", iv->get_name()); throw CsErrorException(
return; *this, "variable '%s' is read only", iv->get_name()
);
} }
bool success = cs_override_var( cs_override_var(
*this, iv, iv->p_flags, *this, iv, iv->p_flags,
[&iv]() { iv->p_overrideval = iv->get_value(); } [&iv]() { iv->p_overrideval = iv->get_value(); }
); );
if (!success) {
return;
}
if ((v < iv->get_val_min()) || (v > iv->get_val_max())) { if ((v < iv->get_val_min()) || (v > iv->get_val_max())) {
v = cs_clamp_var(*this, iv, v); v = cs_clamp_var(*this, iv, v);
} }
@ -945,7 +927,7 @@ CsFloat cs_clamp_fvar(CsState &cs, CsFvar *fv, CsFloat v) {
} else { } else {
return v; return v;
} }
cs_debug_code( throw CsErrorException(
cs, "valid range for '%s' is %s..%s", floatstr(fv->get_val_min()), cs, "valid range for '%s' is %s..%s", floatstr(fv->get_val_min()),
floatstr(fv->get_val_max()) floatstr(fv->get_val_max())
); );
@ -954,16 +936,14 @@ CsFloat cs_clamp_fvar(CsState &cs, CsFvar *fv, CsFloat v) {
void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) { void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) {
if (fv->get_flags() & CsIdfReadOnly) { if (fv->get_flags() & CsIdfReadOnly) {
cs_debug_code(*this, "variable '%s' is read only", fv->get_name()); throw CsErrorException(
return; *this, "variable '%s' is read only", fv->get_name()
);
} }
bool success = cs_override_var( cs_override_var(
*this, fv, fv->p_flags, *this, fv, fv->p_flags,
[&fv]() { fv->p_overrideval = fv->get_value(); } [&fv]() { fv->p_overrideval = fv->get_value(); }
); );
if (!success) {
return;
}
if ((v < fv->get_val_min()) || (v > fv->get_val_max())) { if ((v < fv->get_val_min()) || (v > fv->get_val_max())) {
v = cs_clamp_fvar(*this, fv, v); v = cs_clamp_fvar(*this, fv, v);
} }
@ -973,16 +953,14 @@ void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) {
void CsState::set_var_str_checked(CsSvar *sv, ostd::ConstCharRange v) { void CsState::set_var_str_checked(CsSvar *sv, ostd::ConstCharRange v) {
if (sv->get_flags() & CsIdfReadOnly) { if (sv->get_flags() & CsIdfReadOnly) {
cs_debug_code(*this, "variable '%s' is read only", sv->get_name()); throw CsErrorException(
return; *this, "variable '%s' is read only", sv->get_name()
);
} }
bool success = cs_override_var( cs_override_var(
*this, sv, sv->p_flags, *this, sv, sv->p_flags,
[&sv]() { sv->p_overrideval = sv->get_value(); } [&sv]() { sv->p_overrideval = sv->get_value(); }
); );
if (!success) {
return;
}
sv->set_value(v); sv->set_value(v);
sv->changed(*this); sv->changed(*this);
} }
@ -1124,9 +1102,7 @@ void cs_init_lib_base(CsState &gcs) {
} }
ret.set_int(rc); ret.set_int(rc);
CsAliasInternal::set_alias(cret, cs, result); CsAliasInternal::set_alias(cret, cs, result);
if (css->get_index() != DummyIdx) { CsAliasInternal::set_alias(css, cs, tback);
CsAliasInternal::set_alias(css, cs, tback);
}
}); });
gcs.new_command("?", "tTT", [](auto &, auto args, auto &res) { gcs.new_command("?", "tTT", [](auto &, auto args, auto &res) {
@ -1344,8 +1320,8 @@ end:
cs.run(args[2].get_code(), res); cs.run(args[2].get_code(), res);
}); });
gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &res) { gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &) {
res.set_int(cs.reset_var(args[0].get_strr())); cs.reset_var(args[0].get_strr());
}); });
gcs.new_command("alias", "sT", [](auto &cs, auto args, auto &) { gcs.new_command("alias", "sT", [](auto &cs, auto args, auto &) {