get rid of standard i/o inside vm

master
Daniel Kolesa 2021-03-18 00:03:30 +01:00
parent fb8668a508
commit 6ed9ae1235
6 changed files with 70 additions and 74 deletions

View File

@ -260,8 +260,6 @@ protected:
private:
cs_var_cb cb_var;
virtual cs_string to_printable() const = 0;
void changed(cs_state &cs) {
if (cb_var) {
cb_var(cs, *this);
@ -279,8 +277,6 @@ struct OSTD_EXPORT cs_ivar: cs_var {
cs_int get_value() const;
void set_value(cs_int val);
cs_string to_printable() const final;
private:
cs_ivar(
cs_strref n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
@ -299,8 +295,6 @@ struct OSTD_EXPORT cs_fvar: cs_var {
cs_float get_value() const;
void set_value(cs_float val);
cs_string to_printable() const final;
private:
cs_fvar(
cs_strref n, cs_float m, cs_float x, cs_float v,
@ -317,8 +311,6 @@ struct OSTD_EXPORT cs_svar: cs_var {
cs_strref get_value() const;
void set_value(cs_strref val);
cs_string to_printable() const final;
private:
cs_svar(cs_strref n, cs_strref v, cs_strref ov, cs_var_cb f, int flags);
@ -429,6 +421,9 @@ struct OSTD_EXPORT cs_state {
cs_hook_cb const &get_call_hook() const;
cs_hook_cb &get_call_hook();
cs_vprint_cb set_var_printer(cs_vprint_cb func);
cs_vprint_cb const &get_var_printer() const;
void init_libs(int libs = CsLibAll);
void clear_override(cs_ident &id);
@ -533,7 +528,7 @@ struct OSTD_EXPORT cs_state {
std::optional<cs_strref> get_alias_val(ostd::string_range name);
virtual void print_var(cs_var *v);
void print_var(cs_var const &v) const;
private:
OSTD_LOCAL cs_state(cs_shared_state *s);

View File

@ -10,6 +10,7 @@ namespace cscript {
struct cs_state;
struct cs_ident;
struct cs_value;
struct cs_var;
using cs_value_r = ostd::iterator_range<cs_value *>;
using cs_ident_r = ostd::iterator_range<cs_ident **>;
@ -31,6 +32,7 @@ namespace cscript {
* need to make sure, override this with your own type
*/
using cs_var_cb = std::function<void(cs_state &, cs_ident &)>;
using cs_vprint_cb = std::function<void(cs_state const &, cs_var const &)>;
using cs_command_cb = std::function<void(cs_state &, cs_value_r, cs_value &)>;
using cs_hook_cb = std::function<void(cs_state &)>;
using cs_alloc_cb = void *(*)(void *, void *, size_t, size_t);
@ -38,14 +40,6 @@ namespace cscript {
constexpr auto const IntFormat = "%d";
constexpr auto const FloatFormat = "%.7g";
constexpr auto const RoundFloatFormat = "%.1f";
constexpr auto const IvarFormat = "%s = %d";
constexpr auto const IvarHexFormat = "%s = 0x%X";
constexpr auto const IvarHexColorFormat = "%s = 0x%.6X (%d, %d, %d)";
constexpr auto const FvarFormat = "%s = %.7g";
constexpr auto const FvarRoundFormat = "%s = %.1f";
constexpr auto const SvarFormat = "%s = \"%s\"";
constexpr auto const SvarQuotedFormat = "%s = [%s]";
} /* namespace cscript */
#endif /* LIBCUBESCRIPT_CUBESCRIPT_CONF_HH */

View File

@ -697,7 +697,7 @@ static uint32_t *runcode(cs_state &cs, uint32_t *code, cs_value &result) {
args[numargs++] = std::move(result);
continue;
case CsCodePrint:
cs.print_var(static_cast<cs_var *>(cs.p_state->identmap[op >> 8]));
cs.print_var(*static_cast<cs_var *>(cs.p_state->identmap[op >> 8]));
continue;
case CsCodeLocal: {
@ -1545,7 +1545,7 @@ noid:
}
case CsIdIvar:
if (callargs <= 0) {
cs.print_var(static_cast<cs_var *>(id));
cs.print_var(*static_cast<cs_var *>(id));
} else {
cs.set_var_int_checked(
static_cast<cs_ivar *>(id),
@ -1557,7 +1557,7 @@ noid:
continue;
case CsIdFvar:
if (callargs <= 0) {
cs.print_var(static_cast<cs_var *>(id));
cs.print_var(*static_cast<cs_var *>(id));
} else {
cs.set_var_float_checked(
static_cast<cs_fvar *>(id),
@ -1569,7 +1569,7 @@ noid:
continue;
case CsIdSvar:
if (callargs <= 0) {
cs.print_var(static_cast<cs_var *>(id));
cs.print_var(*static_cast<cs_var *>(id));
} else {
cs.set_var_str_checked(
static_cast<cs_svar *>(id),
@ -1659,14 +1659,14 @@ void cs_state::run(cs_ident *id, cs_value_r args, cs_value &ret) {
break;
case cs_ident_type::Ivar:
if (args.empty()) {
print_var(static_cast<cs_var *>(id));
print_var(*static_cast<cs_var *>(id));
} else {
set_var_int_checked(static_cast<cs_ivar *>(id), args);
}
break;
case cs_ident_type::Fvar:
if (args.empty()) {
print_var(static_cast<cs_var *>(id));
print_var(*static_cast<cs_var *>(id));
} else {
set_var_float_checked(
static_cast<cs_fvar *>(id), args[0].force_float()
@ -1675,7 +1675,7 @@ void cs_state::run(cs_ident *id, cs_value_r args, cs_value &ret) {
break;
case cs_ident_type::Svar:
if (args.empty()) {
print_var(static_cast<cs_var *>(id));
print_var(*static_cast<cs_var *>(id));
} else {
set_var_str_checked(
static_cast<cs_svar *>(id), args[0].force_str()

View File

@ -116,6 +116,7 @@ struct cs_shared_state {
cs_map<ostd::string_range, cs_ident *> idents;
cs_vector<cs_ident *> identmap;
cs_alloc_cb allocf;
cs_vprint_cb varprintf;
cs_strman *strman;
void *aptr;

View File

@ -227,26 +227,6 @@ void cs_ivar::set_value(cs_int val) {
p_storage = val;
}
cs_string cs_ivar::to_printable() const {
cs_int i = p_storage;
auto app = ostd::appender<cs_string>();
try {
if (!(get_flags() & CS_IDF_HEX) || (i < 0)) {
format(app, IvarFormat, get_name(), i);
} else if (p_maxval == 0xFFFFFF) {
format(
app, IvarHexColorFormat, get_name(),
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
);
} else {
format(app, IvarHexFormat, get_name(), i);
}
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
return std::move(app.get());
}
cs_float cs_fvar::get_val_min() const {
return p_minval;
}
@ -261,19 +241,6 @@ void cs_fvar::set_value(cs_float val) {
p_storage = val;
}
cs_string cs_fvar::to_printable() const {
cs_float f = p_storage;
auto app = ostd::appender<cs_string>();
try {
format(
app, (f == cs_int(f)) ? FvarRoundFormat : FvarFormat, get_name(), f
);
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
return std::move(app.get());
}
cs_strref cs_svar::get_value() const {
return p_storage;
}
@ -281,21 +248,6 @@ void cs_svar::set_value(cs_strref val) {
p_storage = val;
}
cs_string cs_svar::to_printable() const {
ostd::string_range s = p_storage;
auto app = ostd::appender<cs_string>();
try {
if (ostd::find(s, '"').empty()) {
format(app, SvarFormat, get_name(), s);
} else {
format(app, SvarQuotedFormat, get_name(), s);
}
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
return std::move(app.get());
}
ostd::string_range cs_command::get_args() const {
return p_cargs;
}
@ -322,6 +274,7 @@ cs_state::cs_state(cs_alloc_cb func, void *data):
p_state->allocf = func;
p_state->aptr = data;
p_state->strman = p_state->create<cs_strman>(p_state);
p_state->varprintf = [](auto &, auto &) {};
for (int i = 0; i < MaxArguments; ++i) {
char buf[32];
@ -465,6 +418,16 @@ OSTD_EXPORT cs_hook_cb &cs_state::get_call_hook() {
return p_callhook;
}
OSTD_EXPORT cs_vprint_cb cs_state::set_var_printer(cs_vprint_cb func) {
auto fn = std::move(p_state->varprintf);
p_state->varprintf = std::move(func);
return fn;
}
OSTD_EXPORT cs_vprint_cb const &cs_state::get_var_printer() const {
return p_state->varprintf;
}
void *cs_state::alloc(void *ptr, size_t os, size_t ns) {
return p_state->alloc(ptr, os, ns);
}
@ -663,8 +626,8 @@ OSTD_EXPORT void cs_state::set_alias(ostd::string_range name, cs_value v) {
}
}
OSTD_EXPORT void cs_state::print_var(cs_var *v) {
ostd::writeln(v->to_printable());
OSTD_EXPORT void cs_state::print_var(cs_var const &v) const {
p_state->varprintf(*this, v);
}
void cs_alias::get_cval(cs_value &v) const {

View File

@ -187,6 +187,48 @@ static void do_sigint(int n) {
});
}
/* an example of what var printer would look like in real usage */
static void repl_print_var(cs_state const &cs, cs_var const &var) {
switch (var.get_type()) {
case cs_ident_type::Ivar: {
auto &iv = static_cast<cs_ivar const &>(var);
auto val = iv.get_value();
if (!(iv.get_flags() & CS_IDF_HEX) || (val < 0)) {
ostd::writefln("%s = %d", iv.get_name(), val);
} else if (iv.get_val_max() == 0xFFFFFF) {
ostd::writefln(
"%s = 0x%.6X (%d, %d, %d)", iv.get_name(),
val, (val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF
);
} else {
ostd::writefln("%s = 0x%X", iv.get_name(), val);
}
break;
}
case cs_ident_type::Fvar: {
auto &fv = static_cast<cs_fvar const &>(var);
auto val = fv.get_value();
ostd::writefln(
(floor(val) == val) ? "%s = %.1f" : "%s = %.7g",
fv.get_name(), val
);
break;
}
case cs_ident_type::Svar: {
auto &sv = static_cast<cs_svar const &>(var);
auto val = ostd::string_range{sv.get_value()};
if (ostd::find(val, '"').empty()) {
ostd::writefln("%s = \"%s\"", sv.get_name(), val);
} else {
ostd::writefln("%s = [%s]", sv.get_name(), val);
}
break;
}
default:
break;
}
}
static bool do_call(cs_state &cs, ostd::string_range line, bool file = false) {
cs_value ret{cs};
scs = &cs;
@ -272,6 +314,7 @@ static void do_tty(cs_state &cs) {
int main(int argc, char **argv) {
cs_state gcs;
gcs.set_var_printer(repl_print_var);
gcs.init_libs();
gcs.new_command("exec", "s", [](auto &cs, auto args, auto &) {