From b26bae3ec5b3732c0c665ba8c0ddb1e3f0af9901 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Sun, 11 Apr 2021 19:36:20 +0200 Subject: [PATCH] move standard library init outside state, make it never error --- include/cubescript/cubescript/state.hh | 18 ++-- src/cs_state.cc | 28 ++----- src/cs_state.hh | 11 +++ src/lib_base.cc | 78 ++++++++++-------- src/lib_list.cc | 66 +++++++++------ src/lib_math.cc | 110 +++++++++++++------------ src/lib_str.cc | 50 +++++------ tools/repl.cc | 2 +- 8 files changed, 194 insertions(+), 169 deletions(-) diff --git a/include/cubescript/cubescript/state.hh b/include/cubescript/cubescript/state.hh index 4ade466..7d017a5 100644 --- a/include/cubescript/cubescript/state.hh +++ b/include/cubescript/cubescript/state.hh @@ -16,18 +16,11 @@ struct state; using alloc_func = void *(*)(void *, void *, size_t, size_t); -using hook_func = internal::callable; +using hook_func = internal::callable; using command_func = internal::callable< void, state &, std::span, any_value & >; -enum { - LIB_MATH = 1 << 0, - LIB_STRING = 1 << 1, - LIB_LIST = 1 << 2, - LIB_ALL = 0b111 -}; - enum class loop_state { NORMAL = 0, BREAK, CONTINUE }; @@ -56,8 +49,6 @@ struct LIBCUBESCRIPT_EXPORT state { hook_func const &get_call_hook() const; hook_func &get_call_hook(); - void init_libs(int libs = LIB_ALL); - void clear_override(ident &id); void clear_overrides(); @@ -136,6 +127,13 @@ private: struct thread_state *p_tstate = nullptr; }; +LIBCUBESCRIPT_EXPORT void std_init_base(state &cs); +LIBCUBESCRIPT_EXPORT void std_init_math(state &cs); +LIBCUBESCRIPT_EXPORT void std_init_string(state &cs); +LIBCUBESCRIPT_EXPORT void std_init_list(state &cs); + +LIBCUBESCRIPT_EXPORT void std_init_all(state &cs); + } /* namespace cubescript */ #endif /* LIBCUBESCRIPT_CUBESCRIPT_STATE_HH */ diff --git a/src/cs_state.cc b/src/cs_state.cc index de613a6..33ff83a 100644 --- a/src/cs_state.cc +++ b/src/cs_state.cc @@ -78,11 +78,6 @@ ident *internal_state::get_ident(std::string_view name) const { return id->second; } -void init_lib_base(state &cs); -void init_lib_math(state &cs); -void init_lib_string(state &cs); -void init_lib_list(state &cs); - /* public interfaces */ state::state(): state{default_alloc, nullptr} {} @@ -262,12 +257,8 @@ state::state(alloc_func func, void *data) { } }); static_cast(p)->p_type = ID_CONTINUE; - - init_lib_base(*this); } - - LIBCUBESCRIPT_EXPORT state::~state() { if (!p_tstate || !p_tstate->owner) { return; @@ -647,18 +638,6 @@ do_add: return *cmd; } -LIBCUBESCRIPT_EXPORT void state::init_libs(int libs) { - if (libs & LIB_MATH) { - init_lib_math(*this); - } - if (libs & LIB_STRING) { - init_lib_string(*this); - } - if (libs & LIB_LIST) { - init_lib_list(*this); - } -} - LIBCUBESCRIPT_EXPORT any_value state::run(bcode_ref const &code) { any_value ret{}; vm_exec(*p_tstate, bcode_p{code}.get()->get_raw(), ret); @@ -847,4 +826,11 @@ LIBCUBESCRIPT_EXPORT std::size_t state::set_max_run_depth(std::size_t v) { return old; } +LIBCUBESCRIPT_EXPORT void std_init_all(state &cs) { + std_init_base(cs); + std_init_math(cs); + std_init_string(cs); + std_init_list(cs); +} + } /* namespace cubescript */ diff --git a/src/cs_state.hh b/src/cs_state.hh index df45ded..99457b3 100644 --- a/src/cs_state.hh +++ b/src/cs_state.hh @@ -124,6 +124,17 @@ inline void std_allocator::deallocate(T *p, std::size_t n) { istate->alloc(p, n, 0); } +template +inline void new_cmd_quiet( + state &cs, std::string_view name, std::string_view args, F &&f +) { + try { + cs.new_command(name, args, std::forward(f)); + } catch (error const &) { + return; + } +} + } /* namespace cubescript */ #endif diff --git a/src/lib_base.cc b/src/lib_base.cc index 18fdb39..ba5b084 100644 --- a/src/lib_base.cc +++ b/src/lib_base.cc @@ -65,12 +65,12 @@ end: } } -void init_lib_base(state &gcs) { - gcs.new_command("error", "s", [](auto &cs, auto args, auto &) { +LIBCUBESCRIPT_EXPORT void std_init_base(state &gcs) { + new_cmd_quiet(gcs, "error", "s", [](auto &cs, auto args, auto &) { throw error{cs, args[0].get_string(cs)}; }); - gcs.new_command("pcall", "err", [](auto &cs, auto args, auto &ret) { + new_cmd_quiet(gcs, "pcall", "err", [](auto &cs, auto args, auto &ret) { alias *cret = args[1].get_ident()->get_alias(); alias *css = args[2].get_ident()->get_alias(); if (!cret || !css) { @@ -96,15 +96,15 @@ void init_lib_base(state &gcs) { ts.get_astack(css).set_alias(css, ts, tback); }); - gcs.new_command("?", "ttt", [](auto &, auto args, auto &res) { + new_cmd_quiet(gcs, "?", "ttt", [](auto &, auto args, auto &res) { if (args[0].get_bool()) { - res = args[1]; + res = std::move(args[1]); } else { - res = args[2]; + res = std::move(args[2]); } }); - gcs.new_command("cond", "ee2V", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "cond", "ee2V", [](auto &cs, auto args, auto &res) { for (size_t i = 0; i < args.size(); i += 2) { if ((i + 1) < args.size()) { if (cs.run(args[i].get_code()).get_bool()) { @@ -118,7 +118,7 @@ void init_lib_base(state &gcs) { } }); - gcs.new_command("case", "ite2V", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "case", "ite2V", [](auto &cs, auto args, auto &res) { integer_type val = args[0].get_integer(); for (size_t i = 1; (i + 1) < args.size(); i += 2) { if ( @@ -131,7 +131,7 @@ void init_lib_base(state &gcs) { } }); - gcs.new_command("casef", "fte2V", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "casef", "fte2V", [](auto &cs, auto args, auto &res) { float_type val = args[0].get_float(); for (size_t i = 1; (i + 1) < args.size(); i += 2) { if ( @@ -144,7 +144,7 @@ void init_lib_base(state &gcs) { } }); - gcs.new_command("cases", "ste2V", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "cases", "ste2V", [](auto &cs, auto args, auto &res) { string_ref val = args[0].get_string(cs); for (size_t i = 1; (i + 1) < args.size(); i += 2) { if ( @@ -157,7 +157,7 @@ void init_lib_base(state &gcs) { } }); - gcs.new_command("pushif", "rte", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "pushif", "rte", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { if (st.get_alias()->is_arg()) { return; @@ -169,28 +169,28 @@ void init_lib_base(state &gcs) { } }); - gcs.new_command("loop", "rie", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loop", "rie", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), 0, args[1].get_integer(), 1, bcode_ref{}, args[2].get_code() ); }); - gcs.new_command("loop+", "riie", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loop+", "riie", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), args[1].get_integer(), args[2].get_integer(), 1, bcode_ref{}, args[3].get_code() ); }); - gcs.new_command("loop*", "riie", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loop*", "riie", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), 0, args[1].get_integer(), args[2].get_integer(), bcode_ref{}, args[3].get_code() ); }); - gcs.new_command("loop+*", "riiie", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loop+*", "riiie", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), args[1].get_integer(), args[3].get_integer(), args[2].get_integer(), @@ -198,28 +198,30 @@ void init_lib_base(state &gcs) { ); }); - gcs.new_command("loopwhile", "riee", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loopwhile", "riee", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), 0, args[1].get_integer(), 1, args[2].get_code(), args[3].get_code() ); }); - gcs.new_command("loopwhile+", "riiee", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loopwhile+", "riiee", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), args[1].get_integer(), args[2].get_integer(), 1, args[3].get_code(), args[4].get_code() ); }); - gcs.new_command("loopwhile*", "riiee", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loopwhile*", "riiee", [](auto &cs, auto args, auto &) { do_loop( cs, *args[0].get_ident(), 0, args[2].get_integer(), args[1].get_integer(), args[3].get_code(), args[4].get_code() ); }); - gcs.new_command("loopwhile+*", "riiiee", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "loopwhile+*", "riiiee", []( + auto &cs, auto args, auto & + ) { do_loop( cs, *args[0].get_ident(), args[1].get_integer(), args[3].get_integer(), args[2].get_integer(), args[4].get_code(), @@ -227,7 +229,7 @@ void init_lib_base(state &gcs) { ); }); - gcs.new_command("while", "ee", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "while", "ee", [](auto &cs, auto args, auto &) { auto cond = args[0].get_code(); auto body = args[1].get_code(); while (cs.run(cond).get_bool()) { @@ -242,28 +244,36 @@ end: return; }); - gcs.new_command("loopconcat", "rie", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "loopconcat", "rie", []( + auto &cs, auto args, auto &res + ) { do_loop_conc( cs, res, *args[0].get_ident(), 0, args[1].get_integer(), 1, args[2].get_code(), true ); }); - gcs.new_command("loopconcat+", "riie", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "loopconcat+", "riie", []( + auto &cs, auto args, auto &res + ) { do_loop_conc( cs, res, *args[0].get_ident(), args[1].get_integer(), args[2].get_integer(), 1, args[3].get_code(), true ); }); - gcs.new_command("loopconcat*", "riie", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "loopconcat*", "riie", []( + auto &cs, auto args, auto &res + ) { do_loop_conc( cs, res, *args[0].get_ident(), 0, args[2].get_integer(), args[1].get_integer(), args[3].get_code(), true ); }); - gcs.new_command("loopconcat+*", "riiie", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "loopconcat+*", "riiie", []( + auto &cs, auto args, auto &res + ) { do_loop_conc( cs, res, *args[0].get_ident(), args[1].get_integer(), args[3].get_integer(), args[2].get_integer(), @@ -271,14 +281,16 @@ end: ); }); - gcs.new_command("loopconcatword", "rie", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "loopconcatword", "rie", []( + auto &cs, auto args, auto &res + ) { do_loop_conc( cs, res, *args[0].get_ident(), 0, args[1].get_integer(), 1, args[2].get_code(), false ); }); - gcs.new_command("loopconcatword+", "riie", []( + new_cmd_quiet(gcs, "loopconcatword+", "riie", []( auto &cs, auto args, auto &res ) { do_loop_conc( @@ -287,7 +299,7 @@ end: ); }); - gcs.new_command("loopconcatword*", "riie", []( + new_cmd_quiet(gcs, "loopconcatword*", "riie", []( auto &cs, auto args, auto &res ) { do_loop_conc( @@ -296,7 +308,7 @@ end: ); }); - gcs.new_command("loopconcatword+*", "riiie", []( + new_cmd_quiet(gcs, "loopconcatword+*", "riiie", []( auto &cs, auto args, auto &res ) { do_loop_conc( @@ -306,7 +318,7 @@ end: ); }); - gcs.new_command("push", "rte", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "push", "rte", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { if (st.get_alias()->is_arg()) { return; @@ -316,19 +328,19 @@ end: } }); - gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "resetvar", "s", [](auto &cs, auto args, auto &) { cs.reset_var(args[0].get_string(cs)); }); - gcs.new_command("alias", "st", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "alias", "st", [](auto &cs, auto args, auto &) { cs.set_alias(args[0].get_string(cs), args[1]); }); - gcs.new_command("identexists", "s", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "identexists", "s", [](auto &cs, auto args, auto &res) { res.set_integer(cs.have_ident(args[0].get_string(cs))); }); - gcs.new_command("getalias", "s", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "getalias", "s", [](auto &cs, auto args, auto &res) { auto *id = cs.get_alias(args[0].get_string(cs)); if (id) { res = id->get_value(cs); diff --git a/src/lib_list.cc b/src/lib_list.cc index 69edea3..3c3d4d7 100644 --- a/src/lib_list.cc +++ b/src/lib_list.cc @@ -141,14 +141,14 @@ static inline void list_merge( static void init_lib_list_sort(state &cs); -void init_lib_list(state &gcs) { - gcs.new_command("listlen", "s", [](auto &cs, auto args, auto &res) { +LIBCUBESCRIPT_EXPORT void std_init_list(state &gcs) { + new_cmd_quiet(gcs, "listlen", "s", [](auto &cs, auto args, auto &res) { res.set_integer( integer_type(list_parser{cs, args[0].get_string(cs)}.count()) ); }); - gcs.new_command("at", "si1V", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "at", "si1V", [](auto &cs, auto args, auto &res) { if (args.empty()) { return; } @@ -173,7 +173,7 @@ void init_lib_list(state &gcs) { res.set_string(p.get_item()); }); - gcs.new_command("sublist", "siiN", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "sublist", "siiN", [](auto &cs, auto args, auto &res) { integer_type skip = args[1].get_integer(), count = args[2].get_integer(), numargs = args[3].get_integer(); @@ -205,7 +205,7 @@ void init_lib_list(state &gcs) { res.set_string(std::string_view{list, qend}, cs); }); - gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listfind", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { any_value idv{}; auto body = args[2].get_code(); @@ -223,7 +223,7 @@ void init_lib_list(state &gcs) { res.set_integer(-1); }); - gcs.new_command("listassoc", "rse", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listassoc", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { any_value idv{}; auto body = args[2].get_code(); @@ -245,21 +245,21 @@ void init_lib_list(state &gcs) { } }); - gcs.new_command("listfind=", "i", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listfind=", "i", [](auto &cs, auto args, auto &res) { list_find( cs, args, res, [](list_parser const &p, integer_type val) { return parse_int(p.get_raw_item()) == val; } ); }); - gcs.new_command("listfind=f", "f", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listfind=f", "f", [](auto &cs, auto args, auto &res) { list_find( cs, args, res, [](list_parser const &p, float_type val) { return parse_float(p.get_raw_item()) == val; } ); }); - gcs.new_command("listfind=s", "s", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listfind=s", "s", [](auto &cs, auto args, auto &res) { list_find( cs, args, res, [](list_parser const &p, std::string_view val) { return p.get_raw_item() == val; @@ -267,21 +267,21 @@ void init_lib_list(state &gcs) { ); }); - gcs.new_command("listassoc=", "i", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listassoc=", "i", [](auto &cs, auto args, auto &res) { list_assoc( cs, args, res, [](list_parser const &p, integer_type val) { return parse_int(p.get_raw_item()) == val; } ); }); - gcs.new_command("listassoc=f", "f", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listassoc=f", "f", [](auto &cs, auto args, auto &res) { list_assoc( cs, args, res, [](list_parser const &p, float_type val) { return parse_float(p.get_raw_item()) == val; } ); }); - gcs.new_command("listassoc=s", "s", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listassoc=s", "s", [](auto &cs, auto args, auto &res) { list_assoc( cs, args, res, [](list_parser const &p, std::string_view val) { return p.get_raw_item() == val; @@ -289,7 +289,7 @@ void init_lib_list(state &gcs) { ); }); - gcs.new_command("looplist", "rse", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "looplist", "rse", [](auto &cs, auto args, auto &) { if (alias_local st{cs, args[0].get_ident()}; st) { any_value idv{}; auto body = args[2].get_code(); @@ -307,7 +307,7 @@ void init_lib_list(state &gcs) { } }); - gcs.new_command("looplist2", "rrse", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "looplist2", "rrse", [](auto &cs, auto args, auto &) { alias_local st1{cs, args[0].get_ident()}; alias_local st2{cs, args[1].get_ident()}; if (!st1 || !st2) { @@ -334,7 +334,7 @@ void init_lib_list(state &gcs) { } }); - gcs.new_command("looplist3", "rrrse", [](auto &cs, auto args, auto &) { + new_cmd_quiet(gcs, "looplist3", "rrrse", [](auto &cs, auto args, auto &) { alias_local st1{cs, args[0].get_ident()}; alias_local st2{cs, args[1].get_ident()}; alias_local st3{cs, args[2].get_ident()}; @@ -368,14 +368,16 @@ void init_lib_list(state &gcs) { } }); - gcs.new_command("looplistconcat", "rse", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "looplistconcat", "rse", []( + auto &cs, auto args, auto &res + ) { loop_list_conc( cs, res, args[0].get_ident(), args[1].get_string(cs), args[2].get_code(), true ); }); - gcs.new_command("looplistconcatword", "rse", []( + new_cmd_quiet(gcs, "looplistconcatword", "rse", []( auto &cs, auto args, auto &res ) { loop_list_conc( @@ -384,7 +386,9 @@ void init_lib_list(state &gcs) { ); }); - gcs.new_command("listfilter", "rse", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listfilter", "rse", []( + auto &cs, auto args, auto &res + ) { if (alias_local st{cs, args[0].get_ident()}; st) { any_value idv{}; auto body = args[2].get_code(); @@ -404,7 +408,7 @@ void init_lib_list(state &gcs) { } }); - gcs.new_command("listcount", "rse", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listcount", "rse", [](auto &cs, auto args, auto &res) { if (alias_local st{cs, args[0].get_ident()}; st) { any_value idv{}; auto body = args[2].get_code(); @@ -420,7 +424,7 @@ void init_lib_list(state &gcs) { } }); - gcs.new_command("prettylist", "ss", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "prettylist", "ss", [](auto &cs, auto args, auto &res) { charbuf buf{cs}; std::string_view s = args[0].get_string(cs); std::string_view conj = args[1].get_string(cs); @@ -448,23 +452,27 @@ void init_lib_list(state &gcs) { res.set_string(buf.str(), cs); }); - gcs.new_command("indexof", "ss", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "indexof", "ss", [](auto &cs, auto args, auto &res) { res.set_integer( list_includes(cs, args[0].get_string(cs), args[1].get_string(cs)) ); }); - gcs.new_command("listdel", "ss", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listdel", "ss", [](auto &cs, auto args, auto &res) { list_merge(cs, args, res, std::less()); }); - gcs.new_command("listintersect", "ss", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listintersect", "ss", []( + auto &cs, auto args, auto &res + ) { list_merge(cs, args, res, std::greater_equal()); }); - gcs.new_command("listunion", "ss", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listunion", "ss", [](auto &cs, auto args, auto &res) { list_merge(cs, args, res, std::less()); }); - gcs.new_command("listsplice", "ssii", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "listsplice", "ssii", []( + auto &cs, auto args, auto &res + ) { integer_type offset = std::max(args[2].get_integer(), integer_type(0)); integer_type len = std::max(args[3].get_integer(), integer_type(0)); std::string_view s = args[0].get_string(cs); @@ -615,13 +623,17 @@ static void list_sort( } static void init_lib_list_sort(state &gcs) { - gcs.new_command("sortlist", "srree", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "sortlist", "srree", []( + auto &cs, auto args, auto &res + ) { list_sort( cs, res, args[0].get_string(cs), args[1].get_ident(), args[2].get_ident(), args[3].get_code(), args[4].get_code() ); }); - gcs.new_command("uniquelist", "srre", [](auto &cs, auto args, auto &res) { + new_cmd_quiet(gcs, "uniquelist", "srre", []( + auto &cs, auto args, auto &res + ) { list_sort( cs, res, args[0].get_string(cs), args[1].get_ident(), args[2].get_ident(), bcode_ref{}, args[3].get_code() diff --git a/src/lib_math.cc b/src/lib_math.cc index 50c0563..040ab59 100644 --- a/src/lib_math.cc +++ b/src/lib_math.cc @@ -6,6 +6,8 @@ #include +#include "cs_state.hh" + namespace cubescript { static constexpr float_type PI = float_type(3.14159265358979323846); @@ -73,69 +75,69 @@ static inline void cmp_op(std::span args, any_value &res, F cmp) { res.set_integer(integer_type(val)); } -void init_lib_math(state &cs) { - cs.new_command("sin", "f", [](auto &, auto args, auto &res) { +LIBCUBESCRIPT_EXPORT void std_init_math(state &cs) { + new_cmd_quiet(cs, "sin", "f", [](auto &, auto args, auto &res) { res.set_float(std::sin(args[0].get_float() * RAD)); }); - cs.new_command("cos", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "cos", "f", [](auto &, auto args, auto &res) { res.set_float(std::cos(args[0].get_float() * RAD)); }); - cs.new_command("tan", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "tan", "f", [](auto &, auto args, auto &res) { res.set_float(std::tan(args[0].get_float() * RAD)); }); - cs.new_command("asin", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "asin", "f", [](auto &, auto args, auto &res) { res.set_float(std::asin(args[0].get_float()) / RAD); }); - cs.new_command("acos", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "acos", "f", [](auto &, auto args, auto &res) { res.set_float(std::acos(args[0].get_float()) / RAD); }); - cs.new_command("atan", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "atan", "f", [](auto &, auto args, auto &res) { res.set_float(std::atan(args[0].get_float()) / RAD); }); - cs.new_command("atan2", "ff", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "atan2", "ff", [](auto &, auto args, auto &res) { res.set_float(std::atan2(args[0].get_float(), args[1].get_float()) / RAD); }); - cs.new_command("sqrt", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "sqrt", "f", [](auto &, auto args, auto &res) { res.set_float(std::sqrt(args[0].get_float())); }); - cs.new_command("loge", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "loge", "f", [](auto &, auto args, auto &res) { res.set_float(std::log(args[0].get_float())); }); - cs.new_command("log2", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "log2", "f", [](auto &, auto args, auto &res) { res.set_float(std::log(args[0].get_float()) / LN2); }); - cs.new_command("log10", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "log10", "f", [](auto &, auto args, auto &res) { res.set_float(std::log10(args[0].get_float())); }); - cs.new_command("exp", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "exp", "f", [](auto &, auto args, auto &res) { res.set_float(std::exp(args[0].get_float())); }); - cs.new_command("min", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "min", "i1V", [](auto &, auto args, auto &res) { integer_type v = (!args.empty() ? args[0].get_integer() : 0); for (size_t i = 1; i < args.size(); ++i) { v = std::min(v, args[i].get_integer()); } res.set_integer(v); }); - cs.new_command("max", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "max", "i1V", [](auto &, auto args, auto &res) { integer_type v = (!args.empty() ? args[0].get_integer() : 0); for (size_t i = 1; i < args.size(); ++i) { v = std::max(v, args[i].get_integer()); } res.set_integer(v); }); - cs.new_command("minf", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "minf", "f1V", [](auto &, auto args, auto &res) { float_type v = (!args.empty() ? args[0].get_float() : 0); for (size_t i = 1; i < args.size(); ++i) { v = std::min(v, args[i].get_float()); } res.set_float(v); }); - cs.new_command("maxf", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "maxf", "f1V", [](auto &, auto args, auto &res) { float_type v = (!args.empty() ? args[0].get_float() : 0); for (size_t i = 1; i < args.size(); ++i) { v = std::max(v, args[i].get_float()); @@ -143,21 +145,21 @@ void init_lib_math(state &cs) { res.set_float(v); }); - cs.new_command("abs", "i", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "abs", "i", [](auto &, auto args, auto &res) { res.set_integer(std::abs(args[0].get_integer())); }); - cs.new_command("absf", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "absf", "f", [](auto &, auto args, auto &res) { res.set_float(std::abs(args[0].get_float())); }); - cs.new_command("floor", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "floor", "f", [](auto &, auto args, auto &res) { res.set_float(std::floor(args[0].get_float())); }); - cs.new_command("ceil", "f", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "ceil", "f", [](auto &, auto args, auto &res) { res.set_float(std::ceil(args[0].get_float())); }); - cs.new_command("round", "ff", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "round", "ff", [](auto &, auto args, auto &res) { float_type step = args[1].get_float(); float_type r = args[0].get_float(); if (step > 0) { @@ -169,43 +171,43 @@ void init_lib_math(state &cs) { res.set_float(r); }); - cs.new_command("+", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "+", "i1V", [](auto &, auto args, auto &res) { math_op(args, res, 0, std::plus(), math_noop()); }); - cs.new_command("*", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "*", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 1, std::multiplies(), math_noop() ); }); - cs.new_command("-", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "-", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::minus(), std::negate() ); }); - cs.new_command("^", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "^", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::bit_xor(), [](integer_type val) { return ~val; } ); }); - cs.new_command("~", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "~", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::bit_xor(), [](integer_type val) { return ~val; } ); }); - cs.new_command("&", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "&", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::bit_and(), math_noop() ); }); - cs.new_command("|", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "|", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::bit_or(), math_noop() ); }); /* special combined cases */ - cs.new_command("^~", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "^~", "i1V", [](auto &, auto args, auto &res) { integer_type val; if (args.size() >= 2) { val = args[0].get_integer() ^ ~args[1].get_integer(); @@ -217,7 +219,7 @@ void init_lib_math(state &cs) { } res.set_integer(val); }); - cs.new_command("&~", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "&~", "i1V", [](auto &, auto args, auto &res) { integer_type val; if (args.size() >= 2) { val = args[0].get_integer() & ~args[1].get_integer(); @@ -229,7 +231,7 @@ void init_lib_math(state &cs) { } res.set_integer(val); }); - cs.new_command("|~", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "|~", "i1V", [](auto &, auto args, auto &res) { integer_type val; if (args.size() >= 2) { val = args[0].get_integer() | ~args[1].get_integer(); @@ -242,7 +244,7 @@ void init_lib_math(state &cs) { res.set_integer(val); }); - cs.new_command("<<", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "<<", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](integer_type val1, integer_type val2) { return (val2 < integer_type(sizeof(integer_type) * CHAR_BIT)) @@ -251,7 +253,7 @@ void init_lib_math(state &cs) { }, math_noop() ); }); - cs.new_command(">>", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, ">>", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](integer_type val1, integer_type val2) { return val1 >> std::clamp( @@ -261,23 +263,23 @@ void init_lib_math(state &cs) { ); }); - cs.new_command("+f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "+f", "f1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::plus(), math_noop() ); }); - cs.new_command("*f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "*f", "f1V", [](auto &, auto args, auto &res) { math_op( args, res, 1, std::multiplies(), math_noop() ); }); - cs.new_command("-f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "-f", "f1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, std::minus(), std::negate() ); }); - cs.new_command("div", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "div", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](integer_type val1, integer_type val2) { if (val2) { @@ -287,7 +289,7 @@ void init_lib_math(state &cs) { }, math_noop() ); }); - cs.new_command("mod", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "mod", "i1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](integer_type val1, integer_type val2) { if (val2) { @@ -297,7 +299,7 @@ void init_lib_math(state &cs) { }, math_noop() ); }); - cs.new_command("divf", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "divf", "f1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](float_type val1, float_type val2) { if (val2) { @@ -307,7 +309,7 @@ void init_lib_math(state &cs) { }, math_noop() ); }); - cs.new_command("modf", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "modf", "f1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](float_type val1, float_type val2) { if (val2) { @@ -318,7 +320,7 @@ void init_lib_math(state &cs) { ); }); - cs.new_command("pow", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "pow", "f1V", [](auto &, auto args, auto &res) { math_op( args, res, 0, [](float_type val1, float_type val2) { return float_type(pow(val1, val2)); @@ -326,41 +328,41 @@ void init_lib_math(state &cs) { ); }); - cs.new_command("=", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "=", "i1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::equal_to()); }); - cs.new_command("!=", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "!=", "i1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::not_equal_to()); }); - cs.new_command("<", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "<", "i1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::less()); }); - cs.new_command(">", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, ">", "i1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::greater()); }); - cs.new_command("<=", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "<=", "i1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::less_equal()); }); - cs.new_command(">=", "i1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, ">=", "i1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::greater_equal()); }); - cs.new_command("=f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "=f", "f1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::equal_to()); }); - cs.new_command("!=f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "!=f", "f1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::not_equal_to()); }); - cs.new_command("(args, res, std::less()); }); - cs.new_command(">f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, ">f", "f1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::greater()); }); - cs.new_command("<=f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, "<=f", "f1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::less_equal()); }); - cs.new_command(">=f", "f1V", [](auto &, auto args, auto &res) { + new_cmd_quiet(cs, ">=f", "f1V", [](auto &, auto args, auto &res) { cmp_op(args, res, std::greater_equal()); }); } diff --git a/src/lib_str.cc b/src/lib_str.cc index de3d5d3..4cd6185 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -28,8 +28,8 @@ static inline void str_cmp_by( res.set_integer(integer_type(val)); } -void init_lib_string(state &cs) { - cs.new_command("strstr", "ss", [](auto &ccs, auto args, auto &res) { +LIBCUBESCRIPT_EXPORT void std_init_string(state &cs) { + new_cmd_quiet(cs, "strstr", "ss", [](auto &ccs, auto args, auto &res) { std::string_view a = args[0].get_string(ccs); std::string_view b = args[1].get_string(ccs); auto pos = a.find(b); @@ -40,11 +40,11 @@ void init_lib_string(state &cs) { } }); - cs.new_command("strlen", "s", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strlen", "s", [](auto &ccs, auto args, auto &res) { res.set_integer(integer_type(args[0].get_string(ccs).size())); }); - cs.new_command("strcode", "si", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strcode", "si", [](auto &ccs, auto args, auto &res) { std::string_view str = args[0].get_string(ccs); integer_type i = args[1].get_integer(); if (i >= integer_type(str.size())) { @@ -54,12 +54,12 @@ void init_lib_string(state &cs) { } }); - cs.new_command("codestr", "i", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "codestr", "i", [](auto &ccs, auto args, auto &res) { char const p[2] = { char(args[0].get_integer()), '\0' }; res.set_string(std::string_view{static_cast(p)}, ccs); }); - cs.new_command("strlower", "s", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strlower", "s", [](auto &ccs, auto args, auto &res) { auto inps = args[0].get_string(ccs); auto *ics = state_p{ccs}.ts().istate; auto *buf = ics->strman->alloc_buf(inps.size()); @@ -69,7 +69,7 @@ void init_lib_string(state &cs) { res.set_string(ics->strman->steal(buf)); }); - cs.new_command("strupper", "s", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strupper", "s", [](auto &ccs, auto args, auto &res) { auto inps = args[0].get_string(ccs); auto *ics = state_p{ccs}.ts().istate; auto *buf = ics->strman->alloc_buf(inps.size()); @@ -79,27 +79,27 @@ void init_lib_string(state &cs) { res.set_string(ics->strman->steal(buf)); }); - cs.new_command("escape", "s", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "escape", "s", [](auto &ccs, auto args, auto &res) { charbuf s{ccs}; escape_string(std::back_inserter(s), args[0].get_string(ccs)); res.set_string(s.str(), ccs); }); - cs.new_command("unescape", "s", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "unescape", "s", [](auto &ccs, auto args, auto &res) { charbuf s{ccs}; unescape_string(std::back_inserter(s), args[0].get_string(ccs)); res.set_string(s.str(), ccs); }); - cs.new_command("concat", "V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "concat", "V", [](auto &ccs, auto args, auto &res) { res.set_string(concat_values(ccs, args, " ")); }); - cs.new_command("concatword", "V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "concatword", "V", [](auto &ccs, auto args, auto &res) { res.set_string(concat_values(ccs, args)); }); - cs.new_command("format", "V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "format", "V", [](auto &ccs, auto args, auto &res) { if (args.empty()) { return; } @@ -127,7 +127,7 @@ void init_lib_string(state &cs) { res.set_string(s.str(), ccs); }); - cs.new_command("tohex", "ii", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "tohex", "ii", [](auto &ccs, auto args, auto &res) { char buf[32]; /* use long long as the largest signed integer type */ auto val = static_cast(args[0].get_integer()); @@ -152,7 +152,7 @@ void init_lib_string(state &cs) { throw internal_error{"format error"}; }); - cs.new_command("substr", "siiN", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "substr", "siiN", [](auto &ccs, auto args, auto &res) { std::string_view s = args[0].get_string(ccs); auto start = args[1].get_integer(), count = args[2].get_integer(); auto numargs = args[3].get_integer(); @@ -166,29 +166,31 @@ void init_lib_string(state &cs) { }, ccs); }); - cs.new_command("strcmp", "s1V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strcmp", "s1V", [](auto &ccs, auto args, auto &res) { str_cmp_by(ccs, args, res, std::equal_to()); }); - cs.new_command("=s", "s1V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "=s", "s1V", [](auto &ccs, auto args, auto &res) { str_cmp_by(ccs, args, res, std::equal_to()); }); - cs.new_command("!=s", "s1V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "!=s", "s1V", [](auto &ccs, auto args, auto &res) { str_cmp_by(ccs, args, res, std::not_equal_to()); }); - cs.new_command("()); }); - cs.new_command(">s", "s1V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, ">s", "s1V", [](auto &ccs, auto args, auto &res) { str_cmp_by(ccs, args, res, std::greater()); }); - cs.new_command("<=s", "s1V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "<=s", "s1V", [](auto &ccs, auto args, auto &res) { str_cmp_by(ccs, args, res, std::less_equal()); }); - cs.new_command(">=s", "s1V", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, ">=s", "s1V", [](auto &ccs, auto args, auto &res) { str_cmp_by(ccs, args, res, std::greater_equal()); }); - cs.new_command("strreplace", "ssss", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strreplace", "ssss", []( + auto &ccs, auto args, auto &res + ) { std::string_view s = args[0].get_string(ccs); std::string_view oldval = args[1].get_string(ccs), newval = args[2].get_string(ccs), @@ -217,7 +219,9 @@ void init_lib_string(state &cs) { } }); - cs.new_command("strsplice", "ssii", [](auto &ccs, auto args, auto &res) { + new_cmd_quiet(cs, "strsplice", "ssii", []( + auto &ccs, auto args, auto &res + ) { std::string_view s = args[0].get_string(ccs); std::string_view vals = args[1].get_string(ccs); integer_type skip = args[2].get_integer(), diff --git a/tools/repl.cc b/tools/repl.cc index 52a7b98..b0da128 100644 --- a/tools/repl.cc +++ b/tools/repl.cc @@ -318,7 +318,7 @@ static void do_tty(cs::state &cs) { int main(int argc, char **argv) { cs::state gcs; - gcs.init_libs(); + cs::std_init_all(gcs); /* this is how you can override a setter for variables; fvar and svar * work equivalently - in this case we want to allow multiple values