2016-09-07 22:57:28 +02:00
|
|
|
#include "cubescript/cubescript.hh"
|
2016-08-12 18:38:43 +02:00
|
|
|
#include "cs_vm.hh"
|
2015-08-08 18:13:19 +02:00
|
|
|
|
2015-08-08 17:13:46 +02:00
|
|
|
namespace cscript {
|
|
|
|
|
2016-08-21 02:34:03 +02:00
|
|
|
CsString intstr(CsInt v) {
|
2016-09-09 17:43:23 +02:00
|
|
|
auto app = ostd::appender<CsString>();
|
|
|
|
cscript::util::format_int(app, v);
|
|
|
|
return ostd::move(app.get());
|
2015-08-11 23:01:56 +02:00
|
|
|
}
|
|
|
|
|
2016-08-21 02:34:03 +02:00
|
|
|
CsString floatstr(CsFloat v) {
|
2016-09-09 17:43:23 +02:00
|
|
|
auto app = ostd::appender<CsString>();
|
|
|
|
cscript::util::format_float(app, v);
|
|
|
|
return ostd::move(app.get());
|
2015-08-11 23:01:56 +02:00
|
|
|
}
|
|
|
|
|
2016-08-12 18:38:43 +02:00
|
|
|
bool cs_check_num(ostd::ConstCharRange s) {
|
2016-08-17 18:53:38 +02:00
|
|
|
if (isdigit(s[0])) {
|
2015-08-07 00:16:02 +02:00
|
|
|
return true;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-07 00:16:02 +02:00
|
|
|
switch (s[0]) {
|
2016-08-17 18:53:38 +02:00
|
|
|
case '+':
|
|
|
|
case '-':
|
|
|
|
return isdigit(s[1]) || ((s[1] == '.') && isdigit(s[2]));
|
|
|
|
case '.':
|
|
|
|
return isdigit(s[1]) != 0;
|
|
|
|
default:
|
|
|
|
return false;
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent::CsIdent(CsIdentType tp, ostd::ConstCharRange nm, int fl):
|
2016-08-18 03:53:51 +02:00
|
|
|
p_name(nm), p_type(int(tp)), p_flags(fl)
|
2016-08-18 03:00:32 +02:00
|
|
|
{}
|
2016-08-10 19:33:43 +02:00
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsVar::CsVar(CsIdentType tp, ostd::ConstCharRange name, CsVarCb f, int fl):
|
|
|
|
CsIdent(tp, name, fl), cb_var(ostd::move(f))
|
2016-08-18 03:00:32 +02:00
|
|
|
{}
|
2016-08-17 23:29:31 +02:00
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIvar::CsIvar(
|
|
|
|
ostd::ConstCharRange name, CsInt m, CsInt x, CsInt v, CsVarCb f, int fl
|
2016-08-18 03:00:32 +02:00
|
|
|
):
|
2016-09-07 20:20:36 +02:00
|
|
|
CsVar(CsIdentType::Ivar, name, ostd::move(f), fl | ((m > x) ? CsIdfReadOnly : 0)),
|
2016-08-22 19:43:58 +02:00
|
|
|
p_storage(v), p_minval(m), p_maxval(x), p_overrideval(0)
|
2016-08-18 03:00:32 +02:00
|
|
|
{}
|
2015-08-11 23:16:20 +02:00
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFvar::CsFvar(
|
|
|
|
ostd::ConstCharRange name, CsFloat m, CsFloat x, CsFloat v, CsVarCb f, int fl
|
2016-08-18 03:00:32 +02:00
|
|
|
):
|
2016-09-07 20:20:36 +02:00
|
|
|
CsVar(CsIdentType::Fvar, name, ostd::move(f), fl | ((m > x) ? CsIdfReadOnly : 0)),
|
2016-08-22 19:43:58 +02:00
|
|
|
p_storage(v), p_minval(m), p_maxval(x), p_overrideval(0)
|
2016-08-18 03:00:32 +02:00
|
|
|
{}
|
2015-08-11 23:16:20 +02:00
|
|
|
|
2016-08-31 22:46:25 +02:00
|
|
|
CsSvar::CsSvar(ostd::ConstCharRange name, CsString v, CsVarCb f, int fl):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsVar(CsIdentType::Svar, name, ostd::move(f), fl),
|
2016-08-31 22:46:25 +02:00
|
|
|
p_storage(ostd::move(v)), p_overrideval()
|
2016-08-18 03:00:32 +02:00
|
|
|
{}
|
2015-08-11 23:16:20 +02:00
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, char *a, int fl):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsIdent(CsIdentType::Alias, name, fl),
|
2016-08-21 01:51:45 +02:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-18 00:18:36 +02:00
|
|
|
{
|
2016-08-31 20:18:53 +02:00
|
|
|
p_val.set_mstr(a);
|
2015-08-11 23:16:20 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, CsInt a, int fl):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsIdent(CsIdentType::Alias, name, fl),
|
2016-08-21 01:51:45 +02:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-18 00:18:36 +02:00
|
|
|
{
|
2016-08-31 20:18:53 +02:00
|
|
|
p_val.set_int(a);
|
2015-08-11 23:16:20 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, CsFloat a, int fl):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsIdent(CsIdentType::Alias, name, fl),
|
2016-08-21 01:51:45 +02:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-18 00:18:36 +02:00
|
|
|
{
|
2016-08-31 20:18:53 +02:00
|
|
|
p_val.set_float(a);
|
2015-08-11 23:16:20 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, int fl):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsIdent(CsIdentType::Alias, name, fl),
|
2016-08-21 01:51:45 +02:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-18 00:18:36 +02:00
|
|
|
{
|
2016-08-31 20:18:53 +02:00
|
|
|
p_val.set_null();
|
2016-08-17 23:04:43 +02:00
|
|
|
}
|
2016-09-06 22:57:10 +02:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, CsValue v, int fl):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsIdent(CsIdentType::Alias, name, fl),
|
2016-09-06 22:57:10 +02:00
|
|
|
p_acode(nullptr), p_astack(nullptr), p_val(ostd::move(v))
|
|
|
|
{}
|
2015-08-11 23:16:20 +02:00
|
|
|
|
2016-09-02 18:20:53 +02:00
|
|
|
CsCommand::CsCommand(
|
2016-09-02 19:01:25 +02:00
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange args,
|
|
|
|
int nargs, CsCommandCb f
|
2016-08-17 18:53:38 +02:00
|
|
|
):
|
2016-09-07 19:42:12 +02:00
|
|
|
CsIdent(CsIdentType::Command, name, 0),
|
2016-09-02 21:30:00 +02:00
|
|
|
p_cargs(args), p_cb_cftv(ostd::move(f)), p_numargs(nargs)
|
2016-09-02 19:01:25 +02:00
|
|
|
{}
|
2015-08-11 23:16:20 +02:00
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_alias() const {
|
2016-09-07 19:42:12 +02:00
|
|
|
return get_type() == CsIdentType::Alias;
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias *CsIdent::get_alias() {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsAlias *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias const *CsIdent::get_alias() const {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsAlias const *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_command() const {
|
2016-09-07 19:42:12 +02:00
|
|
|
return get_type() == CsIdentType::Command;
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 18:20:53 +02:00
|
|
|
CsCommand *CsIdent::get_command() {
|
|
|
|
if (!is_command()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return static_cast<CsCommand *>(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
CsCommand const *CsIdent::get_command() const {
|
|
|
|
if (!is_command()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return static_cast<CsCommand const *>(this);
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_special() const {
|
2016-09-07 19:42:12 +02:00
|
|
|
return get_type() == CsIdentType::Special;
|
2016-08-18 03:53:51 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_var() const {
|
|
|
|
CsIdentType tp = get_type();
|
2016-09-07 19:42:12 +02:00
|
|
|
return (tp >= CsIdentType::Ivar) && (tp <= CsIdentType::Svar);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsVar *CsIdent::get_var() {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_var()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsVar *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsVar const *CsIdent::get_var() const {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_var()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsVar const *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_ivar() const {
|
2016-09-07 19:42:12 +02:00
|
|
|
return get_type() == CsIdentType::Ivar;
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIvar *CsIdent::get_ivar() {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_ivar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsIvar *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIvar const *CsIdent::get_ivar() const {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_ivar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsIvar const *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_fvar() const {
|
2016-09-07 19:42:12 +02:00
|
|
|
return get_type() == CsIdentType::Fvar;
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFvar *CsIdent::get_fvar() {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_fvar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsFvar *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFvar const *CsIdent::get_fvar() const {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_fvar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsFvar const *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
bool CsIdent::is_svar() const {
|
2016-09-07 19:42:12 +02:00
|
|
|
return get_type() == CsIdentType::Svar;
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsSvar *CsIdent::get_svar() {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_svar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsSvar *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsSvar const *CsIdent::get_svar() const {
|
2016-08-18 00:54:57 +02:00
|
|
|
if (!is_svar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsSvar const *>(this);
|
2016-08-18 00:54:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsInt CsIvar::get_val_min() const {
|
2016-08-18 04:14:55 +02:00
|
|
|
return p_minval;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsInt CsIvar::get_val_max() const {
|
2016-08-18 04:14:55 +02:00
|
|
|
return p_maxval;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsInt CsIvar::get_value() const {
|
2016-08-22 19:43:58 +02:00
|
|
|
return p_storage;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsIvar::set_value(CsInt val) {
|
2016-08-22 19:43:58 +02:00
|
|
|
p_storage = val;
|
2016-08-18 04:14:55 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFloat CsFvar::get_val_min() const {
|
2016-08-18 04:14:55 +02:00
|
|
|
return p_minval;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFloat CsFvar::get_val_max() const {
|
2016-08-18 04:14:55 +02:00
|
|
|
return p_maxval;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFloat CsFvar::get_value() const {
|
2016-08-22 19:43:58 +02:00
|
|
|
return p_storage;
|
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsFvar::set_value(CsFloat val) {
|
2016-08-22 19:43:58 +02:00
|
|
|
p_storage = val;
|
2016-08-18 04:14:55 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
ostd::ConstCharRange CsSvar::get_value() const {
|
2016-08-22 19:43:58 +02:00
|
|
|
return p_storage.iter();
|
|
|
|
}
|
2016-08-31 22:46:25 +02:00
|
|
|
void CsSvar::set_value(CsString val) {
|
|
|
|
p_storage = ostd::move(val);
|
2016-08-18 04:14:55 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 22:49:05 +02:00
|
|
|
ostd::ConstCharRange CsCommand::get_args() const {
|
|
|
|
return p_cargs;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CsCommand::get_num_args() const {
|
|
|
|
return p_numargs;
|
|
|
|
}
|
|
|
|
|
2016-08-06 17:34:10 +02:00
|
|
|
void cs_init_lib_base(CsState &cs);
|
|
|
|
|
2016-09-14 21:33:32 +02:00
|
|
|
CsState::CsState(CsAllocCb func, void *data):
|
|
|
|
p_state(nullptr),
|
|
|
|
p_allocf(func), p_aptr(data), p_callhook(),
|
2016-09-15 21:27:14 +02:00
|
|
|
p_out(&ostd::out)
|
2016-09-09 00:41:42 +02:00
|
|
|
{
|
2016-09-14 21:33:32 +02:00
|
|
|
p_state = create<CsSharedState>();
|
2016-02-07 00:17:28 +01:00
|
|
|
for (int i = 0; i < MaxArguments; ++i) {
|
2015-08-05 23:58:45 +02:00
|
|
|
char buf[32];
|
|
|
|
snprintf(buf, sizeof(buf), "arg%d", i + 1);
|
2016-09-07 20:20:36 +02:00
|
|
|
new_ident(static_cast<char const *>(buf), CsIdfArg);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = new_ident("//dummy");
|
2016-08-24 19:54:24 +02:00
|
|
|
assert(id->get_index() == DummyIdx);
|
|
|
|
|
2016-09-02 19:01:25 +02:00
|
|
|
id = new_ivar("numargs", MaxArguments, 0, 0);
|
2016-08-24 19:54:24 +02:00
|
|
|
assert(id->get_index() == NumargsIdx);
|
|
|
|
|
2016-09-02 19:01:25 +02:00
|
|
|
id = new_ivar("dbgalias", 0, 1000, 4);
|
2016-08-24 19:54:24 +02:00
|
|
|
assert(id->get_index() == DbgaliasIdx);
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("do", "e", [](auto &cs, auto args, auto &res) {
|
2016-09-11 23:13:39 +02:00
|
|
|
cs.run(args[0].get_code(), res);
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdDo;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("doargs", "e", [](auto &cs, auto args, auto &res) {
|
2016-09-11 23:13:39 +02:00
|
|
|
cs_do_args(cs, [&cs, &res, &args]() {
|
|
|
|
cs.run(args[0].get_code(), res);
|
|
|
|
});
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdDoArgs;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("if", "tee", [](auto &cs, auto args, auto &res) {
|
2016-09-11 23:13:39 +02:00
|
|
|
cs.run((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdIf;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("result", "T", [](auto &, auto args, auto &res) {
|
2016-09-06 22:23:03 +02:00
|
|
|
res = ostd::move(args[0]);
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdResult;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("!", "t", [](auto &, auto args, auto &res) {
|
2016-09-02 19:01:25 +02:00
|
|
|
res.set_int(!args[0].get_bool());
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdNot;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("&&", "E1V", [](auto &cs, auto args, auto &res) {
|
2016-09-02 19:01:25 +02:00
|
|
|
if (args.empty()) {
|
|
|
|
res.set_int(1);
|
|
|
|
} else {
|
|
|
|
for (ostd::Size i = 0; i < args.size(); ++i) {
|
|
|
|
CsBytecode *code = args[i].get_code();
|
|
|
|
if (code) {
|
2016-09-11 23:13:39 +02:00
|
|
|
cs.run(code, res);
|
2016-09-02 19:01:25 +02:00
|
|
|
} else {
|
2016-09-06 22:23:03 +02:00
|
|
|
res = ostd::move(args[i]);
|
2016-09-02 19:01:25 +02:00
|
|
|
}
|
|
|
|
if (!res.get_bool()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdAnd;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
new_command("||", "E1V", [](auto &cs, auto args, auto &res) {
|
2016-09-02 19:01:25 +02:00
|
|
|
if (args.empty()) {
|
|
|
|
res.set_int(0);
|
|
|
|
} else {
|
|
|
|
for (ostd::Size i = 0; i < args.size(); ++i) {
|
|
|
|
CsBytecode *code = args[i].get_code();
|
|
|
|
if (code) {
|
2016-09-11 23:13:39 +02:00
|
|
|
cs.run(code, res);
|
2016-09-02 19:01:25 +02:00
|
|
|
} else {
|
2016-09-06 22:23:03 +02:00
|
|
|
res = ostd::move(args[i]);
|
2016-09-02 19:01:25 +02:00
|
|
|
}
|
|
|
|
if (res.get_bool()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
})->p_type = CsIdOr;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-07 20:20:36 +02:00
|
|
|
new_command("local", nullptr, nullptr)->p_type = CsIdLocal;
|
2016-09-02 19:01:25 +02:00
|
|
|
|
2016-09-15 02:12:22 +02:00
|
|
|
new_command("break", "", [](auto &cs, auto, auto &) {
|
|
|
|
if (cs.is_in_loop()) {
|
|
|
|
throw CsBreakException();
|
|
|
|
} else {
|
|
|
|
throw CsErrorException(cs, "no loop to break");
|
|
|
|
}
|
|
|
|
})->p_type = CsIdBreak;
|
|
|
|
|
|
|
|
new_command("continue", "", [](auto &cs, auto, auto &) {
|
|
|
|
if (cs.is_in_loop()) {
|
|
|
|
throw CsContinueException();
|
|
|
|
} else {
|
|
|
|
throw CsErrorException(cs, "no loop to continue");
|
|
|
|
}
|
|
|
|
})->p_type = CsIdContinue;
|
|
|
|
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_init_lib_base(*this);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CsState::~CsState() {
|
2016-09-12 20:04:59 +02:00
|
|
|
if (!p_state) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (auto &p: p_state->idents.iter()) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *i = p.second;
|
|
|
|
CsAlias *a = i->get_alias();
|
2016-08-18 03:53:51 +02:00
|
|
|
if (a) {
|
2016-08-31 20:18:53 +02:00
|
|
|
a->get_value().force_null();
|
2016-09-02 22:42:10 +02:00
|
|
|
CsAliasInternal::clean_code(a);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-09-13 23:46:51 +02:00
|
|
|
destroy(i);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-09-13 23:46:51 +02:00
|
|
|
destroy(p_state);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 20:22:19 +02:00
|
|
|
CsStream const &CsState::get_out() const {
|
|
|
|
return *p_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsStream &CsState::get_out() {
|
|
|
|
return *p_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CsState::set_out(CsStream &s) {
|
|
|
|
p_out = &s;
|
|
|
|
}
|
|
|
|
|
2016-09-05 21:34:48 +02:00
|
|
|
CsHookCb CsState::set_call_hook(CsHookCb func) {
|
|
|
|
auto hk = ostd::move(p_callhook);
|
|
|
|
p_callhook = ostd::move(func);
|
|
|
|
return hk;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsHookCb const &CsState::get_call_hook() const {
|
|
|
|
return p_callhook;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsHookCb &CsState::get_call_hook() {
|
|
|
|
return p_callhook;
|
|
|
|
}
|
|
|
|
|
2016-09-14 21:33:32 +02:00
|
|
|
void *CsState::alloc(void *ptr, ostd::Size os, ostd::Size ns) {
|
|
|
|
if (p_allocf) {
|
|
|
|
return p_allocf(p_aptr, ptr, os, ns);
|
|
|
|
}
|
2016-09-07 18:58:56 +02:00
|
|
|
if (!ns) {
|
2016-09-14 21:33:32 +02:00
|
|
|
delete[] static_cast<unsigned char *>(ptr);
|
2016-09-14 21:46:47 +02:00
|
|
|
return nullptr;
|
2016-09-09 00:41:42 +02:00
|
|
|
}
|
2016-09-13 23:46:51 +02:00
|
|
|
return new unsigned char[ns];
|
2016-09-09 00:41:42 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsState::clear_override(CsIdent &id) {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (!(id.get_flags() & CsIdfOverridden)) {
|
2016-08-17 18:53:38 +02:00
|
|
|
return;
|
|
|
|
}
|
2016-08-18 03:53:51 +02:00
|
|
|
switch (id.get_type()) {
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Alias: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias &a = static_cast<CsAlias &>(id);
|
2016-09-02 22:42:10 +02:00
|
|
|
CsAliasInternal::clean_code(&a);
|
2016-08-31 20:18:53 +02:00
|
|
|
a.get_value().set_str("");
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Ivar: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIvar &iv = static_cast<CsIvar &>(id);
|
2016-08-22 19:43:58 +02:00
|
|
|
iv.set_value(iv.p_overrideval);
|
2016-09-11 23:13:39 +02:00
|
|
|
iv.changed(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Fvar: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFvar &fv = static_cast<CsFvar &>(id);
|
2016-08-22 19:43:58 +02:00
|
|
|
fv.set_value(fv.p_overrideval);
|
2016-09-11 23:13:39 +02:00
|
|
|
fv.changed(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Svar: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsSvar &sv = static_cast<CsSvar &>(id);
|
2016-08-22 19:43:58 +02:00
|
|
|
sv.set_value(sv.p_overrideval);
|
2016-09-11 23:13:39 +02:00
|
|
|
sv.changed(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
2016-08-18 03:53:51 +02:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
id.p_flags &= ~CsIdfOverridden;
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsState::clear_overrides() {
|
2016-09-12 20:04:59 +02:00
|
|
|
for (auto &p: p_state->idents.iter()) {
|
2016-08-17 22:21:16 +02:00
|
|
|
clear_override(*(p.second));
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *CsState::add_ident(CsIdent *id) {
|
2016-08-18 03:53:51 +02:00
|
|
|
if (!id) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-09-12 20:04:59 +02:00
|
|
|
p_state->idents[id->get_name()] = id;
|
|
|
|
id->p_index = p_state->identmap.size();
|
|
|
|
return p_state->identmap.push(id);
|
2016-08-18 03:53:51 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
|
|
|
|
CsIdent *id = get_ident(name);
|
2015-08-07 00:16:02 +02:00
|
|
|
if (!id) {
|
2015-08-11 22:41:12 +02:00
|
|
|
if (cs_check_num(name)) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
2016-08-17 18:53:38 +02:00
|
|
|
*this, "number %s is not a valid identifier name", name
|
|
|
|
);
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
2016-09-13 23:46:51 +02:00
|
|
|
id = add_ident(create<CsAlias>(name, flags));
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *CsState::force_ident(CsValue &v) {
|
2015-08-13 22:48:03 +02:00
|
|
|
switch (v.get_type()) {
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Ident:
|
2016-08-30 22:29:09 +02:00
|
|
|
return v.get_ident();
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Macro:
|
|
|
|
case CsValueType::Cstring:
|
|
|
|
case CsValueType::String: {
|
2016-08-30 22:55:35 +02:00
|
|
|
CsIdent *id = new_ident(v.get_strr());
|
2016-08-17 18:53:38 +02:00
|
|
|
v.set_ident(id);
|
|
|
|
return id;
|
|
|
|
}
|
2016-08-30 23:30:40 +02:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
2016-09-12 20:04:59 +02:00
|
|
|
v.set_ident(p_state->identmap[DummyIdx]);
|
|
|
|
return p_state->identmap[DummyIdx];
|
|
|
|
}
|
|
|
|
|
|
|
|
CsIdent *CsState::get_ident(ostd::ConstCharRange name) {
|
|
|
|
CsIdent **id = p_state->idents.at(name);
|
|
|
|
if (!id) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return *id;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsAlias *CsState::get_alias(ostd::ConstCharRange name) {
|
|
|
|
CsIdent **id = p_state->idents.at(name);
|
|
|
|
if (!id || !(*id)->is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return static_cast<CsAlias *>(*id);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CsState::have_ident(ostd::ConstCharRange name) {
|
|
|
|
return p_state->idents.at(name) != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsIdentRange CsState::get_idents() {
|
|
|
|
return CsIdentRange(p_state->identmap.data(), p_state->identmap.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
CsConstIdentRange CsState::get_idents() const {
|
|
|
|
return CsConstIdentRange(
|
|
|
|
const_cast<CsIdent const **>(p_state->identmap.data()),
|
|
|
|
p_state->identmap.size()
|
|
|
|
);
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 19:01:25 +02:00
|
|
|
CsIvar *CsState::new_ivar(
|
|
|
|
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, CsVarCb f, int flags
|
|
|
|
) {
|
2016-09-13 23:46:51 +02:00
|
|
|
return add_ident(
|
|
|
|
create<CsIvar>(n, m, x, v, ostd::move(f), flags)
|
|
|
|
)->get_ivar();
|
2016-09-02 19:01:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CsFvar *CsState::new_fvar(
|
|
|
|
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v, CsVarCb f, int flags
|
|
|
|
) {
|
2016-09-13 23:46:51 +02:00
|
|
|
return add_ident(
|
|
|
|
create<CsFvar>(n, m, x, v, ostd::move(f), flags)
|
|
|
|
)->get_fvar();
|
2016-09-02 19:01:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
CsSvar *CsState::new_svar(
|
|
|
|
ostd::ConstCharRange n, CsString v, CsVarCb f, int flags
|
|
|
|
) {
|
|
|
|
return add_ident(
|
2016-09-13 23:46:51 +02:00
|
|
|
create<CsSvar>(n, ostd::move(v), ostd::move(f), flags)
|
2016-09-02 19:01:25 +02:00
|
|
|
)->get_svar();
|
|
|
|
}
|
|
|
|
|
2016-09-15 21:15:54 +02:00
|
|
|
void CsState::reset_var(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(*this, "variable %s does not exist", name);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
if (id->get_flags() & CsIdfReadOnly) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(*this, "variable %s is read only", name);
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
|
|
|
clear_override(*id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CsState::touch_var(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (id && id->is_var()) {
|
2016-09-11 23:13:39 +02:00
|
|
|
static_cast<CsVar *>(id)->changed(*this);
|
2015-08-07 00:16:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-06 22:57:10 +02:00
|
|
|
void CsState::set_alias(ostd::ConstCharRange name, CsValue v) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2015-08-07 00:38:22 +02:00
|
|
|
if (id) {
|
2016-08-18 03:53:51 +02:00
|
|
|
switch (id->get_type()) {
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Alias: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias *a = static_cast<CsAlias *>(id);
|
2016-08-18 03:53:51 +02:00
|
|
|
if (a->get_index() < MaxArguments) {
|
2016-09-02 22:42:10 +02:00
|
|
|
CsAliasInternal::set_arg(a, *this, v);
|
2016-08-17 18:53:38 +02:00
|
|
|
} else {
|
2016-09-02 22:42:10 +02:00
|
|
|
CsAliasInternal::set_alias(a, *this, v);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
|
|
|
return;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Ivar:
|
2016-08-29 19:17:11 +02:00
|
|
|
set_var_int_checked(static_cast<CsIvar *>(id), v.get_int());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Fvar:
|
2016-08-29 19:17:11 +02:00
|
|
|
set_var_float_checked(static_cast<CsFvar *>(id), v.get_float());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Svar:
|
2016-08-29 19:17:11 +02:00
|
|
|
set_var_str_checked(static_cast<CsSvar *>(id), v.get_str());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
|
|
|
default:
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, "cannot redefine builtin %s with an alias",
|
|
|
|
id->get_name()
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2015-08-07 00:38:22 +02:00
|
|
|
}
|
2015-08-11 22:41:12 +02:00
|
|
|
} else if (cs_check_num(name)) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(*this, "cannot alias number %s", name);
|
2015-08-07 00:38:22 +02:00
|
|
|
} else {
|
2016-09-13 23:46:51 +02:00
|
|
|
add_ident(create<CsAlias>(name, ostd::move(v), identflags));
|
2015-08-07 00:38:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-02 20:22:19 +02:00
|
|
|
void CsState::print_var(CsIvar *iv) {
|
|
|
|
CsInt i = iv->get_value();
|
2015-08-07 22:38:57 +02:00
|
|
|
if (i < 0) {
|
2016-09-02 20:22:19 +02:00
|
|
|
get_out().writefln("%s = %d", iv->get_name(), i);
|
2015-08-07 22:38:57 +02:00
|
|
|
return;
|
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
if (iv->get_flags() & CsIdfHex) {
|
2016-08-18 04:14:55 +02:00
|
|
|
if (iv->get_val_max() == 0xFFFFFF) {
|
2016-09-02 20:22:19 +02:00
|
|
|
get_out().writefln(
|
2016-08-18 03:53:51 +02:00
|
|
|
"%s = 0x%.6X (%d, %d, %d)", iv->get_name(),
|
2016-08-17 18:53:38 +02:00
|
|
|
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
|
|
|
|
);
|
|
|
|
} else {
|
2016-09-02 20:22:19 +02:00
|
|
|
get_out().writefln("%s = 0x%X", iv->get_name(), i);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
|
|
|
} else {
|
2016-09-02 20:22:19 +02:00
|
|
|
get_out().writefln("%s = %d", iv->get_name(), i);
|
2015-08-07 22:38:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-02 20:22:19 +02:00
|
|
|
void CsState::print_var(CsFvar *fv) {
|
|
|
|
get_out().writefln("%s = %s", fv->get_name(), floatstr(fv->get_value()));
|
2015-08-07 22:38:57 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 20:22:19 +02:00
|
|
|
void CsState::print_var(CsSvar *sv) {
|
|
|
|
ostd::ConstCharRange sval = sv->get_value();
|
|
|
|
if (ostd::find(sval, '"').empty()) {
|
|
|
|
get_out().writefln("%s = \"%s\"", sv->get_name(), sval);
|
2016-08-17 18:53:38 +02:00
|
|
|
} else {
|
2016-09-02 20:22:19 +02:00
|
|
|
get_out().writefln("%s = [%s]", sv->get_name(), sval);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-07 22:38:57 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsState::print_var(CsVar *v) {
|
2016-08-17 23:29:31 +02:00
|
|
|
switch (v->get_type()) {
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Ivar: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIvar *iv = static_cast<CsIvar *>(v);
|
2016-09-02 20:22:19 +02:00
|
|
|
print_var(iv);
|
2016-08-17 23:29:31 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Fvar: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFvar *fv = static_cast<CsFvar *>(v);
|
2016-09-02 20:22:19 +02:00
|
|
|
print_var(fv);
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsIdentType::Svar: {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsSvar *sv = static_cast<CsSvar *>(v);
|
2016-09-02 20:22:19 +02:00
|
|
|
print_var(sv);
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-08-17 23:29:31 +02:00
|
|
|
}
|
|
|
|
default:
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2015-08-07 22:38:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsAlias::get_cstr(CsValue &v) const {
|
2016-08-31 20:18:53 +02:00
|
|
|
switch (p_val.get_type()) {
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Macro:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_macro(p_val.get_strr());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::String:
|
|
|
|
case CsValueType::Cstring:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_cstr(p_val.get_strr());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Int:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_str(ostd::move(intstr(p_val.get_int())));
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Float:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_str(ostd::move(floatstr(p_val.get_float())));
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
v.set_cstr("");
|
|
|
|
break;
|
2015-08-11 22:41:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsAlias::get_cval(CsValue &v) const {
|
2016-08-31 20:18:53 +02:00
|
|
|
switch (p_val.get_type()) {
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Macro:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_macro(p_val.get_strr());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::String:
|
|
|
|
case CsValueType::Cstring:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_cstr(p_val.get_strr());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Int:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_int(p_val.get_int());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
2016-09-07 19:42:12 +02:00
|
|
|
case CsValueType::Float:
|
2016-08-31 20:18:53 +02:00
|
|
|
v.set_float(p_val.get_float());
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
v.set_null();
|
|
|
|
break;
|
2015-08-11 22:41:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdentType CsIdent::get_type() const {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (p_type > CsIdAlias) {
|
2016-09-07 19:42:12 +02:00
|
|
|
return CsIdentType::Special;
|
2016-08-10 19:33:43 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return CsIdentType(p_type);
|
2016-08-18 03:53:51 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
ostd::ConstCharRange CsIdent::get_name() const {
|
2016-08-18 03:53:51 +02:00
|
|
|
return p_name;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
int CsIdent::get_flags() const {
|
2016-08-18 03:53:51 +02:00
|
|
|
return p_flags;
|
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
int CsIdent::get_index() const {
|
2016-08-18 03:53:51 +02:00
|
|
|
return p_index;
|
2016-08-10 19:33:43 +02:00
|
|
|
}
|
|
|
|
|
2016-08-22 19:43:58 +02:00
|
|
|
template<typename SF>
|
2016-09-15 21:15:54 +02:00
|
|
|
static inline void cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) {
|
2016-09-07 20:20:36 +02:00
|
|
|
if ((cs.identflags & CsIdfOverridden) || (vflags & CsIdfOverride)) {
|
|
|
|
if (vflags & CsIdfPersist) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
2016-08-18 03:53:51 +02:00
|
|
|
cs, "cannot override persistent variable '%s'", v->get_name()
|
2016-08-17 23:29:31 +02:00
|
|
|
);
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
if (!(vflags & CsIdfOverridden)) {
|
2015-08-07 03:11:53 +02:00
|
|
|
sf();
|
2016-09-07 20:20:36 +02:00
|
|
|
vflags |= CsIdfOverridden;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-07 03:11:53 +02:00
|
|
|
} else {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (vflags & CsIdfOverridden) {
|
|
|
|
vflags &= ~CsIdfOverridden;
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-17 18:53:38 +02:00
|
|
|
void CsState::set_var_int(
|
|
|
|
ostd::ConstCharRange name, CsInt v, bool dofunc, bool doclamp
|
|
|
|
) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIvar *iv = static_cast<CsIvar *>(id);
|
2016-09-15 21:15:54 +02:00
|
|
|
cs_override_var(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, iv, iv->p_flags,
|
2016-08-22 19:43:58 +02:00
|
|
|
[&iv]() { iv->p_overrideval = iv->get_value(); }
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
|
|
|
if (doclamp) {
|
2016-08-22 19:43:58 +02:00
|
|
|
iv->set_value(ostd::clamp(v, iv->get_val_min(), iv->get_val_max()));
|
2016-08-17 18:53:38 +02:00
|
|
|
} else {
|
2016-08-22 19:43:58 +02:00
|
|
|
iv->set_value(v);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
|
|
|
if (dofunc) {
|
2016-09-11 23:13:39 +02:00
|
|
|
iv->changed(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-17 18:53:38 +02:00
|
|
|
void CsState::set_var_float(
|
|
|
|
ostd::ConstCharRange name, CsFloat v, bool dofunc, bool doclamp
|
|
|
|
) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFvar *fv = static_cast<CsFvar *>(id);
|
2016-09-15 21:15:54 +02:00
|
|
|
cs_override_var(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, fv, fv->p_flags,
|
2016-08-22 19:43:58 +02:00
|
|
|
[&fv]() { fv->p_overrideval = fv->get_value(); }
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
|
|
|
if (doclamp) {
|
2016-08-22 19:43:58 +02:00
|
|
|
fv->set_value(ostd::clamp(v, fv->get_val_min(), fv->get_val_max()));
|
2016-08-17 18:53:38 +02:00
|
|
|
} else {
|
2016-08-22 19:43:58 +02:00
|
|
|
fv->set_value(v);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
|
|
|
if (dofunc) {
|
2016-09-11 23:13:39 +02:00
|
|
|
fv->changed(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-17 18:53:38 +02:00
|
|
|
void CsState::set_var_str(
|
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange v, bool dofunc
|
|
|
|
) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_svar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
CsSvar *sv = static_cast<CsSvar *>(id);
|
2016-09-15 21:15:54 +02:00
|
|
|
cs_override_var(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, sv, sv->p_flags,
|
2016-08-22 19:43:58 +02:00
|
|
|
[&sv]() { sv->p_overrideval = sv->get_value(); }
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2016-08-22 19:43:58 +02:00
|
|
|
sv->set_value(v);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (dofunc) {
|
2016-09-11 23:13:39 +02:00
|
|
|
sv->changed(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-14 18:35:38 +02:00
|
|
|
ostd::Maybe<CsInt> CsState::get_var_int(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsIvar *>(id)->get_value();
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-14 18:35:38 +02:00
|
|
|
ostd::Maybe<CsFloat> CsState::get_var_float(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsFvar *>(id)->get_value();
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-21 02:34:03 +02:00
|
|
|
ostd::Maybe<CsString> CsState::get_var_str(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_svar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return CsString(static_cast<CsSvar *>(id)->get_value());
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-14 18:35:38 +02:00
|
|
|
ostd::Maybe<CsInt> CsState::get_var_min_int(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsIvar *>(id)->get_val_min();
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-14 18:35:38 +02:00
|
|
|
ostd::Maybe<CsInt> CsState::get_var_max_int(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsIvar *>(id)->get_val_max();
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-14 18:35:38 +02:00
|
|
|
ostd::Maybe<CsFloat> CsState::get_var_min_float(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsFvar *>(id)->get_val_min();
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-14 18:35:38 +02:00
|
|
|
ostd::Maybe<CsFloat> CsState::get_var_max_float(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-29 19:17:11 +02:00
|
|
|
return static_cast<CsFvar *>(id)->get_val_max();
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-21 02:34:03 +02:00
|
|
|
ostd::Maybe<CsString>
|
2016-08-17 23:04:43 +02:00
|
|
|
CsState::get_alias_val(ostd::ConstCharRange name) {
|
2016-08-29 19:17:11 +02:00
|
|
|
CsAlias *a = get_alias(name);
|
2016-08-17 23:29:31 +02:00
|
|
|
if (!a) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-09-10 19:54:55 +02:00
|
|
|
if ((a->get_index() < MaxArguments) && !cs_is_arg_used(*this, a)) {
|
2015-08-07 03:11:53 +02:00
|
|
|
return ostd::nothing;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-31 20:18:53 +02:00
|
|
|
return ostd::move(a->get_value().get_str());
|
2015-08-07 03:11:53 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsInt cs_clamp_var(CsState &cs, CsIvar *iv, CsInt v) {
|
2016-08-18 04:14:55 +02:00
|
|
|
if (v < iv->get_val_min()) {
|
|
|
|
v = iv->get_val_min();
|
|
|
|
} else if (v > iv->get_val_max()) {
|
|
|
|
v = iv->get_val_max();
|
2016-08-17 18:53:38 +02:00
|
|
|
} else {
|
2015-08-07 03:44:51 +02:00
|
|
|
return v;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
2016-08-17 18:53:38 +02:00
|
|
|
cs,
|
2016-09-07 20:20:36 +02:00
|
|
|
(iv->get_flags() & CsIdfHex)
|
2016-08-17 18:53:38 +02:00
|
|
|
? (
|
2016-08-18 04:14:55 +02:00
|
|
|
(iv->get_val_min() <= 255)
|
2016-08-17 18:53:38 +02:00
|
|
|
? "valid range for '%s' is %d..0x%X"
|
|
|
|
: "valid range for '%s' is 0x%X..0x%X"
|
|
|
|
)
|
|
|
|
: "valid range for '%s' is %d..%d",
|
2016-08-18 04:14:55 +02:00
|
|
|
iv->get_name(), iv->get_val_min(), iv->get_val_max()
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsState::set_var_int_checked(CsIvar *iv, CsInt v) {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (iv->get_flags() & CsIdfReadOnly) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
|
|
|
*this, "variable '%s' is read only", iv->get_name()
|
|
|
|
);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-09-15 21:15:54 +02:00
|
|
|
cs_override_var(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, iv, iv->p_flags,
|
2016-08-22 19:43:58 +02:00
|
|
|
[&iv]() { iv->p_overrideval = iv->get_value(); }
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2016-08-18 04:14:55 +02:00
|
|
|
if ((v < iv->get_val_min()) || (v > iv->get_val_max())) {
|
2016-08-17 23:29:31 +02:00
|
|
|
v = cs_clamp_var(*this, iv, v);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-22 19:43:58 +02:00
|
|
|
iv->set_value(v);
|
2016-09-11 23:13:39 +02:00
|
|
|
iv->changed(*this);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsState::set_var_int_checked(CsIvar *iv, CsValueRange args) {
|
2016-08-14 18:35:38 +02:00
|
|
|
CsInt v = args[0].force_int();
|
2016-09-07 20:20:36 +02:00
|
|
|
if ((iv->get_flags() & CsIdfHex) && (args.size() > 1)) {
|
2015-08-07 03:44:51 +02:00
|
|
|
v = (v << 16) | (args[1].force_int() << 8);
|
2016-08-17 18:53:38 +02:00
|
|
|
if (args.size() > 2) {
|
2015-08-07 03:44:51 +02:00
|
|
|
v |= args[2].force_int();
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-08-17 23:29:31 +02:00
|
|
|
set_var_int_checked(iv, v);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
CsFloat cs_clamp_fvar(CsState &cs, CsFvar *fv, CsFloat v) {
|
2016-08-18 04:14:55 +02:00
|
|
|
if (v < fv->get_val_min()) {
|
|
|
|
v = fv->get_val_min();
|
|
|
|
} else if (v > fv->get_val_max()) {
|
|
|
|
v = fv->get_val_max();
|
2016-08-17 18:53:38 +02:00
|
|
|
} else {
|
2015-08-07 03:44:51 +02:00
|
|
|
return v;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
2016-08-18 04:14:55 +02:00
|
|
|
cs, "valid range for '%s' is %s..%s", floatstr(fv->get_val_min()),
|
|
|
|
floatstr(fv->get_val_max())
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2015-08-07 03:44:51 +02:00
|
|
|
return v;
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (fv->get_flags() & CsIdfReadOnly) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
|
|
|
*this, "variable '%s' is read only", fv->get_name()
|
|
|
|
);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-09-15 21:15:54 +02:00
|
|
|
cs_override_var(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, fv, fv->p_flags,
|
2016-08-22 19:43:58 +02:00
|
|
|
[&fv]() { fv->p_overrideval = fv->get_value(); }
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2016-08-18 04:14:55 +02:00
|
|
|
if ((v < fv->get_val_min()) || (v > fv->get_val_max())) {
|
2016-08-17 23:29:31 +02:00
|
|
|
v = cs_clamp_fvar(*this, fv, v);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-22 19:43:58 +02:00
|
|
|
fv->set_value(v);
|
2016-09-11 23:13:39 +02:00
|
|
|
fv->changed(*this);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-08-29 19:17:11 +02:00
|
|
|
void CsState::set_var_str_checked(CsSvar *sv, ostd::ConstCharRange v) {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (sv->get_flags() & CsIdfReadOnly) {
|
2016-09-15 21:15:54 +02:00
|
|
|
throw CsErrorException(
|
|
|
|
*this, "variable '%s' is read only", sv->get_name()
|
|
|
|
);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
2016-09-15 21:15:54 +02:00
|
|
|
cs_override_var(
|
2016-08-18 03:53:51 +02:00
|
|
|
*this, sv, sv->p_flags,
|
2016-08-22 19:43:58 +02:00
|
|
|
[&sv]() { sv->p_overrideval = sv->get_value(); }
|
2016-08-17 18:53:38 +02:00
|
|
|
);
|
2016-08-22 19:43:58 +02:00
|
|
|
sv->set_value(v);
|
2016-09-11 23:13:39 +02:00
|
|
|
sv->changed(*this);
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
|
2016-09-02 19:03:01 +02:00
|
|
|
CsCommand *CsState::new_command(
|
2016-09-02 19:01:25 +02:00
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange args, CsCommandCb func
|
2016-08-10 19:33:43 +02:00
|
|
|
) {
|
2015-08-05 23:58:45 +02:00
|
|
|
int nargs = 0;
|
2016-08-17 18:53:38 +02:00
|
|
|
for (ostd::ConstCharRange fmt(args); !fmt.empty(); ++fmt) {
|
|
|
|
switch (*fmt) {
|
|
|
|
case 'i':
|
|
|
|
case 'b':
|
|
|
|
case 'f':
|
|
|
|
case 'F':
|
|
|
|
case 't':
|
|
|
|
case 'T':
|
|
|
|
case 'E':
|
|
|
|
case 'N':
|
|
|
|
case 'S':
|
|
|
|
case 's':
|
|
|
|
case 'e':
|
|
|
|
case 'r':
|
|
|
|
case '$':
|
|
|
|
if (nargs < MaxArguments) {
|
2016-09-02 20:34:59 +02:00
|
|
|
++nargs;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
2016-09-02 20:34:59 +02:00
|
|
|
if (nargs < (*fmt - '0')) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
if ((fmt.size() != 2) || ((fmt[1] != 'C') && (fmt[1] != 'V'))) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-17 18:53:38 +02:00
|
|
|
if (nargs < MaxArguments) {
|
2016-09-02 18:20:53 +02:00
|
|
|
fmt.push_front_n(*fmt - '0' + 1);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
case 'V':
|
2016-09-02 20:34:59 +02:00
|
|
|
if (fmt.size() != 1) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-17 18:53:38 +02:00
|
|
|
break;
|
|
|
|
default:
|
2016-09-02 19:01:25 +02:00
|
|
|
return nullptr;
|
2015-08-05 23:58:45 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-02 19:01:25 +02:00
|
|
|
return static_cast<CsCommand *>(
|
2016-09-13 23:46:51 +02:00
|
|
|
add_ident(create<CsCommand>(name, args, nargs, ostd::move(func)))
|
2016-09-02 19:01:25 +02:00
|
|
|
);
|
2016-08-10 19:33:43 +02:00
|
|
|
}
|
|
|
|
|
2016-08-17 18:53:38 +02:00
|
|
|
static inline void cs_do_loop(
|
2016-08-29 19:17:11 +02:00
|
|
|
CsState &cs, CsIdent &id, CsInt offset, CsInt n, CsInt step,
|
2016-08-28 19:40:18 +02:00
|
|
|
CsBytecode *cond, CsBytecode *body
|
2016-08-17 18:53:38 +02:00
|
|
|
) {
|
2016-08-31 19:49:24 +02:00
|
|
|
CsStackedValue idv{&id};
|
|
|
|
if (n <= 0 || !idv.has_alias()) {
|
2016-08-06 17:34:10 +02:00
|
|
|
return;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-14 18:35:38 +02:00
|
|
|
for (CsInt i = 0; i < n; ++i) {
|
2016-08-31 19:49:24 +02:00
|
|
|
idv.set_int(offset + i * step);
|
|
|
|
idv.push();
|
2016-08-17 18:53:38 +02:00
|
|
|
if (cond && !cs.run_bool(cond)) {
|
|
|
|
break;
|
|
|
|
}
|
2016-09-14 23:24:13 +02:00
|
|
|
switch (cs.run_loop(body)) {
|
|
|
|
case CsLoopState::Break:
|
|
|
|
goto end;
|
|
|
|
default: /* continue and normal */
|
|
|
|
break;
|
|
|
|
}
|
2016-08-06 17:34:10 +02:00
|
|
|
}
|
2016-09-14 23:24:13 +02:00
|
|
|
end:
|
|
|
|
return;
|
2016-08-06 17:34:10 +02:00
|
|
|
}
|
|
|
|
|
2016-08-11 19:14:18 +02:00
|
|
|
static inline void cs_loop_conc(
|
2016-08-29 19:17:11 +02:00
|
|
|
CsState &cs, CsValue &res, CsIdent &id, CsInt offset, CsInt n,
|
2016-08-28 19:40:18 +02:00
|
|
|
CsInt step, CsBytecode *body, bool space
|
2016-08-11 19:14:18 +02:00
|
|
|
) {
|
2016-08-31 19:49:24 +02:00
|
|
|
CsStackedValue idv{&id};
|
|
|
|
if (n <= 0 || !idv.has_alias()) {
|
2016-08-06 17:34:10 +02:00
|
|
|
return;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-21 02:34:03 +02:00
|
|
|
CsVector<char> s;
|
2016-08-14 18:35:38 +02:00
|
|
|
for (CsInt i = 0; i < n; ++i) {
|
2016-08-31 19:49:24 +02:00
|
|
|
idv.set_int(offset + i * step);
|
|
|
|
idv.push();
|
2016-08-18 20:38:30 +02:00
|
|
|
CsValue v;
|
2016-09-14 23:24:13 +02:00
|
|
|
switch (cs.run_loop(body, v)) {
|
|
|
|
case CsLoopState::Break:
|
|
|
|
goto end;
|
|
|
|
case CsLoopState::Continue:
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2016-08-21 02:34:03 +02:00
|
|
|
CsString vstr = ostd::move(v.get_str());
|
2016-08-17 18:53:38 +02:00
|
|
|
if (space && i) {
|
|
|
|
s.push(' ');
|
|
|
|
}
|
2016-08-06 17:34:10 +02:00
|
|
|
s.push_n(vstr.data(), vstr.size());
|
|
|
|
}
|
2016-09-14 23:24:13 +02:00
|
|
|
end:
|
2016-08-06 17:34:10 +02:00
|
|
|
s.push('\0');
|
|
|
|
ostd::Size len = s.size() - 1;
|
2016-08-11 19:14:18 +02:00
|
|
|
res.set_mstr(ostd::CharRange(s.disown(), len));
|
2016-08-06 17:34:10 +02:00
|
|
|
}
|
|
|
|
|
2016-09-11 23:13:39 +02:00
|
|
|
void cs_init_lib_base(CsState &gcs) {
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("error", "s", [](auto &cs, auto args, auto &) {
|
2016-09-14 23:24:13 +02:00
|
|
|
throw CsErrorException(cs, args[0].get_strr());
|
2016-09-09 01:18:06 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("pcall", "err", [](auto &cs, auto args, auto &ret) {
|
2016-09-10 20:43:58 +02:00
|
|
|
CsAlias *cret = args[1].get_ident()->get_alias(),
|
|
|
|
*css = args[2].get_ident()->get_alias();
|
|
|
|
if (!cret || !css) {
|
2016-09-09 01:18:06 +02:00
|
|
|
ret.set_int(0);
|
|
|
|
return;
|
|
|
|
}
|
2016-09-10 20:43:58 +02:00
|
|
|
CsValue result, tback;
|
2016-09-13 23:46:51 +02:00
|
|
|
bool rc = true;
|
|
|
|
try {
|
2016-09-09 01:18:06 +02:00
|
|
|
cs.run(args[0].get_code(), result);
|
2016-09-13 23:46:51 +02:00
|
|
|
} catch (CsErrorException const &e) {
|
|
|
|
result.set_str(e.what());
|
|
|
|
if (e.get_stack().get()) {
|
2016-09-10 20:43:58 +02:00
|
|
|
auto app = ostd::appender<CsString>();
|
2016-09-13 23:46:51 +02:00
|
|
|
cscript::util::print_stack(app, e.get_stack());
|
2016-09-10 20:43:58 +02:00
|
|
|
tback.set_str(ostd::move(app.get()));
|
|
|
|
}
|
2016-09-13 23:46:51 +02:00
|
|
|
rc = false;
|
2016-09-10 20:43:58 +02:00
|
|
|
}
|
2016-09-13 23:46:51 +02:00
|
|
|
ret.set_int(rc);
|
2016-09-10 20:43:58 +02:00
|
|
|
CsAliasInternal::set_alias(cret, cs, result);
|
2016-09-15 21:15:54 +02:00
|
|
|
CsAliasInternal::set_alias(css, cs, tback);
|
2016-09-09 01:18:06 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("?", "tTT", [](auto &, auto args, auto &res) {
|
2016-09-06 22:23:03 +02:00
|
|
|
if (args[0].get_bool()) {
|
|
|
|
res = ostd::move(args[1]);
|
|
|
|
} else {
|
|
|
|
res = ostd::move(args[2]);
|
|
|
|
}
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("cond", "ee2V", [](auto &cs, auto args, auto &res) {
|
2016-08-06 17:34:10 +02:00
|
|
|
for (ostd::Size i = 0; i < args.size(); i += 2) {
|
|
|
|
if ((i + 1) < args.size()) {
|
2016-08-30 22:29:09 +02:00
|
|
|
if (cs.run_bool(args[i].get_code())) {
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[i + 1].get_code(), res);
|
2016-08-06 17:34:10 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[i].get_code(), res);
|
2016-08-06 17:34:10 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("case", "ite2V", [](auto &cs, auto args, auto &res) {
|
2016-08-17 18:53:38 +02:00
|
|
|
CsInt val = args[0].get_int();
|
|
|
|
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
|
2016-08-30 23:30:40 +02:00
|
|
|
if (
|
2016-09-07 19:42:12 +02:00
|
|
|
(args[i].get_type() == CsValueType::Null) ||
|
2016-08-30 23:30:40 +02:00
|
|
|
(args[i].get_int() == val)
|
|
|
|
) {
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[i + 1].get_code(), res);
|
2016-08-17 18:53:38 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("casef", "fte2V", [](auto &cs, auto args, auto &res) {
|
2016-08-17 18:53:38 +02:00
|
|
|
CsFloat val = args[0].get_float();
|
|
|
|
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
|
2016-08-30 23:30:40 +02:00
|
|
|
if (
|
2016-09-07 19:42:12 +02:00
|
|
|
(args[i].get_type() == CsValueType::Null) ||
|
2016-08-30 23:30:40 +02:00
|
|
|
(args[i].get_float() == val)
|
|
|
|
) {
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[i + 1].get_code(), res);
|
2016-08-17 18:53:38 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-08-06 17:34:10 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("cases", "ste2V", [](auto &cs, auto args, auto &res) {
|
2016-08-21 02:34:03 +02:00
|
|
|
CsString val = args[0].get_str();
|
2016-08-17 18:53:38 +02:00
|
|
|
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
|
2016-08-30 23:30:40 +02:00
|
|
|
if (
|
2016-09-07 19:42:12 +02:00
|
|
|
(args[i].get_type() == CsValueType::Null) ||
|
2016-08-30 23:30:40 +02:00
|
|
|
(args[i].get_str() == val)
|
|
|
|
) {
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[i + 1].get_code(), res);
|
2016-08-17 18:53:38 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-08-06 17:34:10 +02:00
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("pushif", "rTe", [](auto &cs, auto args, auto &res) {
|
2016-08-31 19:49:24 +02:00
|
|
|
CsStackedValue idv{args[0].get_ident()};
|
|
|
|
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
|
2016-08-06 17:34:10 +02:00
|
|
|
return;
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-08-31 19:49:24 +02:00
|
|
|
if (args[1].get_bool()) {
|
2016-09-06 22:23:03 +02:00
|
|
|
idv = ostd::move(args[1]);
|
2016-08-31 19:49:24 +02:00
|
|
|
idv.push();
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[2].get_code(), res);
|
2016-08-06 17:34:10 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loop", "rie", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, nullptr,
|
|
|
|
args[2].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loop+", "riie", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
|
|
|
nullptr, args[3].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loop*", "riie", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[1].get_int(), args[2].get_int(),
|
|
|
|
nullptr, args[3].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loop+*", "riiie", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
|
|
|
args[2].get_int(), nullptr, args[4].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopwhile", "riee", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
|
|
|
args[2].get_code(), args[3].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopwhile+", "riiee", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
|
|
|
args[3].get_code(), args[4].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopwhile*", "riiee", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
|
|
|
|
args[3].get_code(), args[4].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopwhile+*", "riiiee", [](auto &cs, auto args, auto &) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
|
|
|
args[2].get_int(), args[4].get_code(), args[5].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("while", "ee", [](auto &cs, auto args, auto &) {
|
2016-08-28 19:40:18 +02:00
|
|
|
CsBytecode *cond = args[0].get_code(), *body = args[1].get_code();
|
2016-08-06 17:34:10 +02:00
|
|
|
while (cs.run_bool(cond)) {
|
2016-09-14 23:24:13 +02:00
|
|
|
switch (cs.run_loop(body)) {
|
|
|
|
case CsLoopState::Break:
|
|
|
|
goto end;
|
|
|
|
default: /* continue and normal */
|
|
|
|
break;
|
|
|
|
}
|
2016-08-06 17:34:10 +02:00
|
|
|
}
|
2016-09-14 23:24:13 +02:00
|
|
|
end:
|
|
|
|
return;
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopconcat", "rie", [](auto &cs, auto args, auto &res) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-08-11 19:14:18 +02:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
2016-08-06 17:34:10 +02:00
|
|
|
args[2].get_code(), true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopconcat+", "riie", [](auto &cs, auto args, auto &res) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-09-11 23:13:39 +02:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(),
|
|
|
|
args[2].get_int(), 1, args[3].get_code(), true
|
2016-08-06 17:34:10 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopconcat*", "riie", [](auto &cs, auto args, auto &res) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-09-11 23:13:39 +02:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[2].get_int(),
|
|
|
|
args[1].get_int(), args[3].get_code(), true
|
2016-08-06 17:34:10 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopconcat+*", "riiie", [](auto &cs, auto args, auto &res) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-09-11 23:13:39 +02:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(),
|
|
|
|
args[3].get_int(), args[2].get_int(), args[4].get_code(), true
|
2016-08-06 17:34:10 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("loopconcatword", "rie", [](auto &cs, auto args, auto &res) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-08-11 19:14:18 +02:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
2016-08-06 17:34:10 +02:00
|
|
|
args[2].get_code(), false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-11 23:13:39 +02:00
|
|
|
gcs.new_command("loopconcatword+", "riie", [](
|
2016-09-15 00:42:19 +02:00
|
|
|
auto &cs, auto args, auto &res
|
2016-09-11 23:13:39 +02:00
|
|
|
) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-09-11 23:13:39 +02:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(),
|
|
|
|
args[2].get_int(), 1, args[3].get_code(), false
|
2016-08-06 17:34:10 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-11 23:13:39 +02:00
|
|
|
gcs.new_command("loopconcatword*", "riie", [](
|
2016-09-15 00:42:19 +02:00
|
|
|
auto &cs, auto args, auto &res
|
2016-09-11 23:13:39 +02:00
|
|
|
) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-09-11 23:13:39 +02:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[2].get_int(),
|
|
|
|
args[1].get_int(), args[3].get_code(), false
|
2016-08-06 17:34:10 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-11 23:13:39 +02:00
|
|
|
gcs.new_command("loopconcatword+*", "riiie", [](
|
2016-09-15 00:42:19 +02:00
|
|
|
auto &cs, auto args, auto &res
|
2016-09-11 23:13:39 +02:00
|
|
|
) {
|
2016-08-06 17:34:10 +02:00
|
|
|
cs_loop_conc(
|
2016-08-11 19:14:18 +02:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
2016-08-06 17:34:10 +02:00
|
|
|
args[2].get_int(), args[4].get_code(), false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("push", "rTe", [](auto &cs, auto args, auto &res) {
|
2016-08-31 19:49:24 +02:00
|
|
|
CsStackedValue idv{args[0].get_ident()};
|
|
|
|
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
|
2016-08-17 18:53:38 +02:00
|
|
|
return;
|
|
|
|
}
|
2016-09-06 22:23:03 +02:00
|
|
|
idv = ostd::move(args[1]);
|
2016-08-31 19:49:24 +02:00
|
|
|
idv.push();
|
2016-09-07 18:58:56 +02:00
|
|
|
cs.run(args[2].get_code(), res);
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 21:15:54 +02:00
|
|
|
gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &) {
|
|
|
|
cs.reset_var(args[0].get_strr());
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("alias", "sT", [](auto &cs, auto args, auto &) {
|
2016-09-06 22:57:10 +02:00
|
|
|
cs.set_alias(args[0].get_strr(), ostd::move(args[1]));
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("getvarmin", "s", [](auto &cs, auto args, auto &res) {
|
2016-08-11 19:14:18 +02:00
|
|
|
res.set_int(cs.get_var_min_int(args[0].get_strr()).value_or(0));
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("getvarmax", "s", [](auto &cs, auto args, auto &res) {
|
2016-08-11 19:14:18 +02:00
|
|
|
res.set_int(cs.get_var_max_int(args[0].get_strr()).value_or(0));
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("getfvarmin", "s", [](auto &cs, auto args, auto &res) {
|
2016-08-11 19:14:18 +02:00
|
|
|
res.set_float(cs.get_var_min_float(args[0].get_strr()).value_or(0.0f));
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("getfvarmax", "s", [](auto &cs, auto args, auto &res) {
|
2016-08-11 19:14:18 +02:00
|
|
|
res.set_float(cs.get_var_max_float(args[0].get_strr()).value_or(0.0f));
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("identexists", "s", [](auto &cs, auto args, auto &res) {
|
2016-08-11 19:14:18 +02:00
|
|
|
res.set_int(cs.have_ident(args[0].get_strr()));
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
|
2016-09-15 00:42:19 +02:00
|
|
|
gcs.new_command("getalias", "s", [](auto &cs, auto args, auto &res) {
|
2016-09-11 23:13:39 +02:00
|
|
|
res.set_str(
|
|
|
|
ostd::move(cs.get_alias_val(args[0].get_strr()).value_or(""))
|
|
|
|
);
|
2016-08-06 17:34:10 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-08-02 02:21:36 +02:00
|
|
|
void cs_init_lib_math(CsState &cs);
|
|
|
|
void cs_init_lib_string(CsState &cs);
|
|
|
|
void cs_init_lib_list(CsState &cs);
|
2015-08-08 02:40:29 +02:00
|
|
|
|
2016-08-18 20:47:29 +02:00
|
|
|
OSTD_EXPORT void CsState::init_libs(int libs) {
|
2016-09-07 20:20:36 +02:00
|
|
|
if (libs & CsLibMath) {
|
2016-08-18 20:47:29 +02:00
|
|
|
cs_init_lib_math(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
if (libs & CsLibString) {
|
2016-08-18 20:47:29 +02:00
|
|
|
cs_init_lib_string(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-09-07 20:20:36 +02:00
|
|
|
if (libs & CsLibList) {
|
2016-08-18 20:47:29 +02:00
|
|
|
cs_init_lib_list(*this);
|
2016-08-17 18:53:38 +02:00
|
|
|
}
|
2016-02-28 23:21:28 +01:00
|
|
|
}
|
|
|
|
|
2016-02-07 22:22:39 +01:00
|
|
|
} /* namespace cscript */
|