Browse Source

move standard library init outside state, make it never error

master
Daniel Kolesa 3 weeks ago
parent
commit
b26bae3ec5
8 changed files with 194 additions and 169 deletions
  1. +8
    -10
      include/cubescript/cubescript/state.hh
  2. +7
    -21
      src/cs_state.cc
  3. +11
    -0
      src/cs_state.hh
  4. +45
    -33
      src/lib_base.cc
  5. +39
    -27
      src/lib_list.cc
  6. +56
    -54
      src/lib_math.cc
  7. +27
    -23
      src/lib_str.cc
  8. +1
    -1
      tools/repl.cc

+ 8
- 10
include/cubescript/cubescript/state.hh View File

@ -16,18 +16,11 @@ struct state;
using alloc_func = void *(*)(void *, void *, size_t, size_t);
using hook_func = internal::callable<void, struct state &>;
using hook_func = internal::callable<void, state &>;
using command_func = internal::callable<
void, state &, std::span<any_value>, 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 */

+ 7
- 21
src/cs_state.cc View File

@ -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<command_impl *>(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 */

+ 11
- 0
src/cs_state.hh View File

@ -124,6 +124,17 @@ inline void std_allocator<T>::deallocate(T *p, std::size_t n) {
istate->alloc(p, n, 0);
}
template<typename F>
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>(f));
} catch (error const &) {
return;
}
}
} /* namespace cubescript */
#endif

+ 45
- 33
src/lib_base.cc View File

@ -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);


+ 39
- 27
src/lib_list.cc View File

@ -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<integer_type>(
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<float_type>(
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<std::string_view>(
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<integer_type>(
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<float_type>(
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<std::string_view>(
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<false, false>(cs, args, res, std::less<int>());
});
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<false, false>(cs, args, res, std::greater_equal<int>());
});
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<true, true>(cs, args, res, std::less<int>());
});
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()


+ 56
- 54
src/lib_math.cc View File

@ -6,6 +6,8 @@
#include <cubescript/cubescript.hh>
#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<any_value> 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<integer_type>(args, res, 0, std::plus<integer_type>(), math_noop<integer_type>());
});
cs.new_command("*", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "*", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
args, res, 1, std::multiplies<integer_type>(), math_noop<integer_type>()
);
});
cs.new_command("-", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "-", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
args, res, 0, std::minus<integer_type>(), std::negate<integer_type>()
);
});
cs.new_command("^", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "^", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
args, res, 0, std::bit_xor<integer_type>(), [](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<integer_type>(
args, res, 0, std::bit_xor<integer_type>(), [](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<integer_type>(
args, res, 0, std::bit_and<integer_type>(), math_noop<integer_type>()
);
});
cs.new_command("|", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "|", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
args, res, 0, std::bit_or<integer_type>(), math_noop<integer_type>()
);
});
/* 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<integer_type>(
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<integer_type>()
);
});
cs.new_command(">>", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, ">>", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
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<float_type>(
args, res, 0, std::plus<float_type>(), math_noop<float_type>()
);
});
cs.new_command("*f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "*f", "f1V", [](auto &, auto args, auto &res) {
math_op<float_type>(
args, res, 1, std::multiplies<float_type>(), math_noop<float_type>()
);
});
cs.new_command("-f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "-f", "f1V", [](auto &, auto args, auto &res) {
math_op<float_type>(
args, res, 0, std::minus<float_type>(), std::negate<float_type>()
);
});
cs.new_command("div", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "div", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
args, res, 0, [](integer_type val1, integer_type val2) {
if (val2) {
@ -287,7 +289,7 @@ void init_lib_math(state &cs) {
}, math_noop<integer_type>()
);
});
cs.new_command("mod", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "mod", "i1V", [](auto &, auto args, auto &res) {
math_op<integer_type>(
args, res, 0, [](integer_type val1, integer_type val2) {
if (val2) {
@ -297,7 +299,7 @@ void init_lib_math(state &cs) {
}, math_noop<integer_type>()
);
});
cs.new_command("divf", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "divf", "f1V", [](auto &, auto args, auto &res) {
math_op<float_type>(
args, res, 0, [](float_type val1, float_type val2) {
if (val2) {
@ -307,7 +309,7 @@ void init_lib_math(state &cs) {
}, math_noop<float_type>()
);
});
cs.new_command("modf", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "modf", "f1V", [](auto &, auto args, auto &res) {
math_op<float_type>(
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<float_type>(
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<integer_type>(args, res, std::equal_to<integer_type>());
});
cs.new_command("!=", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "!=", "i1V", [](auto &, auto args, auto &res) {
cmp_op<integer_type>(args, res, std::not_equal_to<integer_type>());
});
cs.new_command("<", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "<", "i1V", [](auto &, auto args, auto &res) {
cmp_op<integer_type>(args, res, std::less<integer_type>());
});
cs.new_command(">", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, ">", "i1V", [](auto &, auto args, auto &res) {
cmp_op<integer_type>(args, res, std::greater<integer_type>());
});
cs.new_command("<=", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "<=", "i1V", [](auto &, auto args, auto &res) {
cmp_op<integer_type>(args, res, std::less_equal<integer_type>());
});
cs.new_command(">=", "i1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, ">=", "i1V", [](auto &, auto args, auto &res) {
cmp_op<integer_type>(args, res, std::greater_equal<integer_type>());
});
cs.new_command("=f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "=f", "f1V", [](auto &, auto args, auto &res) {
cmp_op<float_type>(args, res, std::equal_to<float_type>());
});
cs.new_command("!=f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "!=f", "f1V", [](auto &, auto args, auto &res) {
cmp_op<float_type>(args, res, std::not_equal_to<float_type>());
});
cs.new_command("<f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "<f", "f1V", [](auto &, auto args, auto &res) {
cmp_op<float_type>(args, res, std::less<float_type>());
});
cs.new_command(">f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, ">f", "f1V", [](auto &, auto args, auto &res) {
cmp_op<float_type>(args, res, std::greater<float_type>());
});
cs.new_command("<=f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, "<=f", "f1V", [](auto &, auto args, auto &res) {
cmp_op<float_type>(args, res, std::less_equal<float_type>());
});
cs.new_command(">=f", "f1V", [](auto &, auto args, auto &res) {
new_cmd_quiet(cs, ">=f", "f1V", [](auto &, auto args, auto &res) {
cmp_op<float_type>(args, res, std::greater_equal<float_type>());
});
}


+ 27
- 23
src/lib_str.cc View File

@ -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<char const *>(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<long long>(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<std::string_view>());
});
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<std::string_view>());
});
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<std::string_view>());
});
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<std::string_view>());
});
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<std::string_view>());
});
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<std::string_view>());
});
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<std::string_view>());
});
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(),


+ 1
- 1
tools/repl.cc View File

@ -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


Loading…
Cancel
Save