2015-08-08 16:13:19 +00:00
|
|
|
#include "cubescript.hh"
|
2016-08-12 16:38:43 +00:00
|
|
|
#include "cs_vm.hh"
|
2016-08-15 01:19:59 +00:00
|
|
|
#include "cs_util.hh"
|
2015-08-08 16:13:19 +00:00
|
|
|
|
2015-08-08 15:13:46 +00:00
|
|
|
namespace cscript {
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString intstr(CsInt v) {
|
2016-07-13 18:24:26 +00:00
|
|
|
char buf[256];
|
2016-08-14 16:35:38 +00:00
|
|
|
snprintf(buf, sizeof(buf), IntFormat, v);
|
2016-08-31 20:50:43 +00:00
|
|
|
return static_cast<char const *>(buf);
|
2015-08-11 21:01:56 +00:00
|
|
|
}
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString floatstr(CsFloat v) {
|
2016-07-13 18:24:26 +00:00
|
|
|
char buf[256];
|
2016-08-14 16:35:38 +00:00
|
|
|
snprintf(buf, sizeof(buf), v == CsInt(v) ? RoundFloatFormat : FloatFormat, v);
|
2016-08-31 20:50:43 +00:00
|
|
|
return static_cast<char const *>(buf);
|
2015-08-11 21:01:56 +00:00
|
|
|
}
|
|
|
|
|
2016-08-02 00:21:36 +00:00
|
|
|
char *cs_dup_ostr(ostd::ConstCharRange s) {
|
2015-08-11 21:16:20 +00:00
|
|
|
char *r = new char[s.size() + 1];
|
2016-09-01 16:42:28 +00:00
|
|
|
if (s.data()) {
|
|
|
|
memcpy(r, s.data(), s.size());
|
|
|
|
}
|
2015-08-11 21:16:20 +00:00
|
|
|
r[s.size()] = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2016-08-12 16:38:43 +00:00
|
|
|
bool cs_check_num(ostd::ConstCharRange s) {
|
2016-08-17 16:53:38 +00:00
|
|
|
if (isdigit(s[0])) {
|
2015-08-06 22:16:02 +00:00
|
|
|
return true;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-06 22:16:02 +00:00
|
|
|
switch (s[0]) {
|
2016-08-17 16:53:38 +00:00
|
|
|
case '+':
|
|
|
|
case '-':
|
|
|
|
return isdigit(s[1]) || ((s[1] == '.') && isdigit(s[2]));
|
|
|
|
case '.':
|
|
|
|
return isdigit(s[1]) != 0;
|
|
|
|
default:
|
|
|
|
return false;
|
2015-08-06 22:16:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent::CsIdent(CsIdentType tp, ostd::ConstCharRange nm, int fl):
|
2016-08-18 01:53:51 +00:00
|
|
|
p_name(nm), p_type(int(tp)), p_flags(fl)
|
2016-08-18 01:00:32 +00:00
|
|
|
{}
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar::CsVar(CsIdentType tp, ostd::ConstCharRange name, CsVarCb f, int fl):
|
|
|
|
CsIdent(tp, name, fl), cb_var(ostd::move(f))
|
2016-08-18 01:00:32 +00:00
|
|
|
{}
|
2016-08-17 21:29:31 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIvar::CsIvar(
|
|
|
|
ostd::ConstCharRange name, CsInt m, CsInt x, CsInt v, CsVarCb f, int fl
|
2016-08-18 01:00:32 +00:00
|
|
|
):
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar(CsIdentType::ivar, name, ostd::move(f), fl | ((m > x) ? IDF_READONLY : 0)),
|
2016-08-22 17:43:58 +00:00
|
|
|
p_storage(v), p_minval(m), p_maxval(x), p_overrideval(0)
|
2016-08-18 01:00:32 +00:00
|
|
|
{}
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFvar::CsFvar(
|
|
|
|
ostd::ConstCharRange name, CsFloat m, CsFloat x, CsFloat v, CsVarCb f, int fl
|
2016-08-18 01:00:32 +00:00
|
|
|
):
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar(CsIdentType::fvar, name, ostd::move(f), fl | ((m > x) ? IDF_READONLY : 0)),
|
2016-08-22 17:43:58 +00:00
|
|
|
p_storage(v), p_minval(m), p_maxval(x), p_overrideval(0)
|
2016-08-18 01:00:32 +00:00
|
|
|
{}
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2016-08-31 20:46:25 +00:00
|
|
|
CsSvar::CsSvar(ostd::ConstCharRange name, CsString v, CsVarCb f, int fl):
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar(CsIdentType::svar, name, ostd::move(f), fl),
|
2016-08-31 20:46:25 +00:00
|
|
|
p_storage(ostd::move(v)), p_overrideval()
|
2016-08-18 01:00:32 +00:00
|
|
|
{}
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, char *a, int fl):
|
|
|
|
CsIdent(CsIdentType::alias, name, fl),
|
2016-08-20 23:51:45 +00:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-17 22:18:36 +00:00
|
|
|
{
|
2016-08-31 18:18:53 +00:00
|
|
|
p_val.set_mstr(a);
|
2015-08-11 21:16:20 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, CsInt a, int fl):
|
|
|
|
CsIdent(CsIdentType::alias, name, fl),
|
2016-08-20 23:51:45 +00:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-17 22:18:36 +00:00
|
|
|
{
|
2016-08-31 18:18:53 +00:00
|
|
|
p_val.set_int(a);
|
2015-08-11 21:16:20 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, CsFloat a, int fl):
|
|
|
|
CsIdent(CsIdentType::alias, name, fl),
|
2016-08-20 23:51:45 +00:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-17 22:18:36 +00:00
|
|
|
{
|
2016-08-31 18:18:53 +00:00
|
|
|
p_val.set_float(a);
|
2015-08-11 21:16:20 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, int fl):
|
|
|
|
CsIdent(CsIdentType::alias, name, fl),
|
2016-08-20 23:51:45 +00:00
|
|
|
p_acode(nullptr), p_astack(nullptr)
|
2016-08-17 22:18:36 +00:00
|
|
|
{
|
2016-08-31 18:18:53 +00:00
|
|
|
p_val.set_null();
|
2016-08-17 21:04:43 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias::CsAlias(ostd::ConstCharRange name, CsValue const &v, int fl):
|
|
|
|
CsIdent(CsIdentType::alias, name, fl),
|
2016-08-31 18:18:53 +00:00
|
|
|
p_acode(nullptr), p_astack(nullptr), p_val(v)
|
2016-08-18 01:00:32 +00:00
|
|
|
{}
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
Command::Command(
|
2016-08-18 01:00:32 +00:00
|
|
|
int tp, ostd::ConstCharRange name, ostd::ConstCharRange args,
|
2016-08-17 21:04:43 +00:00
|
|
|
ostd::Uint32 amask, int nargs, CmdFunc f
|
2016-08-17 16:53:38 +00:00
|
|
|
):
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent(CsIdentType::command, name, 0),
|
2016-09-01 16:42:28 +00:00
|
|
|
cargs(cs_dup_ostr(args)),
|
2016-08-17 21:04:43 +00:00
|
|
|
argmask(amask), numargs(nargs), cb_cftv(ostd::move(f))
|
|
|
|
{
|
2016-08-18 01:53:51 +00:00
|
|
|
p_type = tp;
|
2016-08-17 21:04:43 +00:00
|
|
|
}
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_alias() const {
|
|
|
|
return get_type() == CsIdentType::alias;
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *CsIdent::get_alias() {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsAlias *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias const *CsIdent::get_alias() const {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsAlias const *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_command() const {
|
|
|
|
return get_type() == CsIdentType::command;
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_special() const {
|
|
|
|
return get_type() == CsIdentType::special;
|
2016-08-18 01:53:51 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_var() const {
|
|
|
|
CsIdentType tp = get_type();
|
|
|
|
return (tp >= CsIdentType::ivar) && (tp <= CsIdentType::svar);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar *CsIdent::get_var() {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_var()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsVar *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar const *CsIdent::get_var() const {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_var()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsVar const *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_ivar() const {
|
|
|
|
return get_type() == CsIdentType::ivar;
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIvar *CsIdent::get_ivar() {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_ivar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsIvar *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIvar const *CsIdent::get_ivar() const {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_ivar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsIvar const *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_fvar() const {
|
|
|
|
return get_type() == CsIdentType::fvar;
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFvar *CsIdent::get_fvar() {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_fvar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsFvar *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFvar const *CsIdent::get_fvar() const {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_fvar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsFvar const *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
bool CsIdent::is_svar() const {
|
|
|
|
return get_type() == CsIdentType::svar;
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsSvar *CsIdent::get_svar() {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_svar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsSvar *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsSvar const *CsIdent::get_svar() const {
|
2016-08-17 22:54:57 +00:00
|
|
|
if (!is_svar()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsSvar const *>(this);
|
2016-08-17 22:54:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt CsIvar::get_val_min() const {
|
2016-08-18 02:14:55 +00:00
|
|
|
return p_minval;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt CsIvar::get_val_max() const {
|
2016-08-18 02:14:55 +00:00
|
|
|
return p_maxval;
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt CsIvar::get_value() const {
|
2016-08-22 17:43:58 +00:00
|
|
|
return p_storage;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsIvar::set_value(CsInt val) {
|
2016-08-22 17:43:58 +00:00
|
|
|
p_storage = val;
|
2016-08-18 02:14:55 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFloat CsFvar::get_val_min() const {
|
2016-08-18 02:14:55 +00:00
|
|
|
return p_minval;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFloat CsFvar::get_val_max() const {
|
2016-08-18 02:14:55 +00:00
|
|
|
return p_maxval;
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFloat CsFvar::get_value() const {
|
2016-08-22 17:43:58 +00:00
|
|
|
return p_storage;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsFvar::set_value(CsFloat val) {
|
2016-08-22 17:43:58 +00:00
|
|
|
p_storage = val;
|
2016-08-18 02:14:55 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
ostd::ConstCharRange CsSvar::get_value() const {
|
2016-08-22 17:43:58 +00:00
|
|
|
return p_storage.iter();
|
|
|
|
}
|
2016-08-31 20:46:25 +00:00
|
|
|
void CsSvar::set_value(CsString val) {
|
|
|
|
p_storage = ostd::move(val);
|
2016-08-18 02:14:55 +00:00
|
|
|
}
|
|
|
|
|
2016-08-06 15:34:10 +00:00
|
|
|
void cs_init_lib_base(CsState &cs);
|
|
|
|
|
2016-08-11 17:21:18 +00:00
|
|
|
CsState::CsState() {
|
2016-07-27 17:52:01 +00:00
|
|
|
noalias.id = nullptr;
|
|
|
|
noalias.next = nullptr;
|
|
|
|
noalias.usedargs = (1 << MaxArguments) - 1;
|
|
|
|
noalias.argstack = nullptr;
|
2016-02-06 23:17:28 +00:00
|
|
|
for (int i = 0; i < MaxArguments; ++i) {
|
2015-08-05 21:58:45 +00:00
|
|
|
char buf[32];
|
|
|
|
snprintf(buf, sizeof(buf), "arg%d", i + 1);
|
2016-07-17 17:50:40 +00:00
|
|
|
new_ident(static_cast<char const *>(buf), IDF_ARG);
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = new_ident("//dummy");
|
2016-08-24 17:54:24 +00:00
|
|
|
assert(id->get_index() == DummyIdx);
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
id = add_ident<CsIvar>("numargs", MaxArguments, 0, 0);
|
2016-08-24 17:54:24 +00:00
|
|
|
assert(id->get_index() == NumargsIdx);
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
id = add_ident<CsIvar>("dbgalias", 0, 1000, 4);
|
2016-08-24 17:54:24 +00:00
|
|
|
assert(id->get_index() == DbgaliasIdx);
|
|
|
|
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_init_lib_base(*this);
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CsState::~CsState() {
|
2016-08-17 20:21:16 +00:00
|
|
|
for (auto &p: idents.iter()) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *i = p.second;
|
|
|
|
CsAlias *a = i->get_alias();
|
2016-08-18 01:53:51 +00:00
|
|
|
if (a) {
|
2016-08-31 18:18:53 +00:00
|
|
|
a->get_value().force_null();
|
2016-08-20 23:51:45 +00:00
|
|
|
a->clean_code();
|
2016-08-18 01:53:51 +00:00
|
|
|
} else if (i->is_command() || i->is_special()) {
|
2016-08-17 21:04:43 +00:00
|
|
|
delete[] static_cast<Command *>(i)->cargs;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-17 20:21:16 +00:00
|
|
|
delete i;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::clear_override(CsIdent &id) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (!(id.get_flags() & IDF_OVERRIDDEN)) {
|
2016-08-17 16:53:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
switch (id.get_type()) {
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::alias: {
|
|
|
|
CsAlias &a = static_cast<CsAlias &>(id);
|
2016-08-31 18:18:53 +00:00
|
|
|
a.get_value().cleanup();
|
2016-08-17 21:29:31 +00:00
|
|
|
a.clean_code();
|
2016-08-31 18:18:53 +00:00
|
|
|
a.get_value().set_str("");
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::ivar: {
|
|
|
|
CsIvar &iv = static_cast<CsIvar &>(id);
|
2016-08-22 17:43:58 +00:00
|
|
|
iv.set_value(iv.p_overrideval);
|
2016-08-17 21:29:31 +00:00
|
|
|
iv.changed();
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::fvar: {
|
|
|
|
CsFvar &fv = static_cast<CsFvar &>(id);
|
2016-08-22 17:43:58 +00:00
|
|
|
fv.set_value(fv.p_overrideval);
|
2016-08-17 22:36:37 +00:00
|
|
|
fv.changed();
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::svar: {
|
|
|
|
CsSvar &sv = static_cast<CsSvar &>(id);
|
2016-08-22 17:43:58 +00:00
|
|
|
sv.set_value(sv.p_overrideval);
|
2016-08-17 22:36:37 +00:00
|
|
|
sv.changed();
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
id.p_flags &= ~IDF_OVERRIDDEN;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsState::clear_overrides() {
|
2016-08-17 20:21:16 +00:00
|
|
|
for (auto &p: idents.iter()) {
|
|
|
|
clear_override(*(p.second));
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *CsState::add_ident(CsIdent *id) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (!id) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
idents[id->get_name()] = id;
|
|
|
|
id->p_index = identmap.size();
|
|
|
|
return identmap.push(id);
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
|
|
|
|
CsIdent *id = get_ident(name);
|
2015-08-06 22:16:02 +00:00
|
|
|
if (!id) {
|
2015-08-11 20:41:12 +00:00
|
|
|
if (cs_check_num(name)) {
|
2016-08-17 16:53:38 +00:00
|
|
|
cs_debug_code(
|
|
|
|
*this, "number %s is not a valid identifier name", name
|
|
|
|
);
|
2016-08-24 17:54:24 +00:00
|
|
|
return identmap[DummyIdx];
|
2015-08-06 22:16:02 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
id = add_ident<CsAlias>(name, flags);
|
2015-08-06 22:16:02 +00:00
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *CsState::force_ident(CsValue &v) {
|
2015-08-13 20:48:03 +00:00
|
|
|
switch (v.get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::ident:
|
2016-08-30 20:29:09 +00:00
|
|
|
return v.get_ident();
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
|
|
|
case CsValueType::string: {
|
2016-08-30 20:55:35 +00:00
|
|
|
CsIdent *id = new_ident(v.get_strr());
|
|
|
|
v.cleanup();
|
2016-08-17 16:53:38 +00:00
|
|
|
v.set_ident(id);
|
|
|
|
return id;
|
|
|
|
}
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-06 22:16:02 +00:00
|
|
|
}
|
|
|
|
v.cleanup();
|
2016-08-24 17:54:24 +00:00
|
|
|
v.set_ident(identmap[DummyIdx]);
|
|
|
|
return identmap[DummyIdx];
|
2015-08-06 22:16:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CsState::reset_var(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
if (id->get_flags() & IDF_READONLY) {
|
|
|
|
cs_debug_code(*this, "variable %s is read only", id->get_name());
|
2015-08-06 22:16:02 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
clear_override(*id);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CsState::touch_var(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (id && id->is_var()) {
|
2016-08-29 17:17:11 +00:00
|
|
|
static_cast<CsVar *>(id)->changed();
|
2015-08-06 22:16:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void CsState::set_alias(ostd::ConstCharRange name, CsValue &v) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2015-08-06 22:38:22 +00:00
|
|
|
if (id) {
|
2016-08-18 01:53:51 +00:00
|
|
|
switch (id->get_type()) {
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::alias: {
|
|
|
|
CsAlias *a = static_cast<CsAlias *>(id);
|
2016-08-18 01:53:51 +00:00
|
|
|
if (a->get_index() < MaxArguments) {
|
2016-08-17 21:29:31 +00:00
|
|
|
a->set_arg(*this, v);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
2016-08-17 21:29:31 +00:00
|
|
|
a->set_alias(*this, v);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
return;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::ivar:
|
|
|
|
set_var_int_checked(static_cast<CsIvar *>(id), v.get_int());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::fvar:
|
|
|
|
set_var_float_checked(static_cast<CsFvar *>(id), v.get_float());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::svar:
|
|
|
|
set_var_str_checked(static_cast<CsSvar *>(id), v.get_str());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cs_debug_code(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, "cannot redefine builtin %s with an alias",
|
|
|
|
id->get_name()
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
break;
|
2015-08-06 22:38:22 +00:00
|
|
|
}
|
|
|
|
v.cleanup();
|
2015-08-11 20:41:12 +00:00
|
|
|
} else if (cs_check_num(name)) {
|
2015-08-12 17:50:02 +00:00
|
|
|
cs_debug_code(*this, "cannot alias number %s", name);
|
2015-08-06 22:38:22 +00:00
|
|
|
v.cleanup();
|
|
|
|
} else {
|
2016-08-29 17:17:11 +00:00
|
|
|
add_ident<CsAlias>(name, v, identflags);
|
2015-08-06 22:38:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::print_var_int(CsIvar *iv, CsInt i) {
|
2015-08-07 20:38:57 +00:00
|
|
|
if (i < 0) {
|
2016-08-18 01:53:51 +00:00
|
|
|
writefln("%s = %d", iv->get_name(), i);
|
2015-08-07 20:38:57 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
if (iv->get_flags() & IDF_HEX) {
|
2016-08-18 02:14:55 +00:00
|
|
|
if (iv->get_val_max() == 0xFFFFFF) {
|
2016-08-17 16:53:38 +00:00
|
|
|
writefln(
|
2016-08-18 01:53:51 +00:00
|
|
|
"%s = 0x%.6X (%d, %d, %d)", iv->get_name(),
|
2016-08-17 16:53:38 +00:00
|
|
|
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
|
|
|
|
);
|
|
|
|
} else {
|
2016-08-18 01:53:51 +00:00
|
|
|
writefln("%s = 0x%X", iv->get_name(), i);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
} else {
|
2016-08-18 01:53:51 +00:00
|
|
|
writefln("%s = %d", iv->get_name(), i);
|
2015-08-07 20:38:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::print_var_float(CsFvar *fv, CsFloat f) {
|
2016-08-18 01:53:51 +00:00
|
|
|
writefln("%s = %s", fv->get_name(), floatstr(f));
|
2015-08-07 20:38:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::print_var_str(CsSvar *sv, ostd::ConstCharRange s) {
|
2016-08-17 16:53:38 +00:00
|
|
|
if (ostd::find(s, '"').empty()) {
|
2016-08-18 01:53:51 +00:00
|
|
|
writefln("%s = \"%s\"", sv->get_name(), s);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
2016-08-18 01:53:51 +00:00
|
|
|
writefln("%s = [%s]", sv->get_name(), s);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-07 20:38:57 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::print_var(CsVar *v) {
|
2016-08-17 21:29:31 +00:00
|
|
|
switch (v->get_type()) {
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::ivar: {
|
|
|
|
CsIvar *iv = static_cast<CsIvar *>(v);
|
2016-08-22 17:43:58 +00:00
|
|
|
print_var_int(iv, iv->get_value());
|
2016-08-17 21:29:31 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::fvar: {
|
|
|
|
CsFvar *fv = static_cast<CsFvar *>(v);
|
2016-08-22 17:43:58 +00:00
|
|
|
print_var_float(fv, fv->get_value());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
case CsIdentType::svar: {
|
|
|
|
CsSvar *sv = static_cast<CsSvar *>(v);
|
2016-08-22 17:43:58 +00:00
|
|
|
print_var_str(sv, sv->get_value());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-17 21:29:31 +00:00
|
|
|
}
|
|
|
|
default:
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2015-08-07 20:38:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void CsValue::cleanup() {
|
2015-08-13 20:48:03 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
2016-08-30 20:55:35 +00:00
|
|
|
delete[] p_s;
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::code: {
|
2016-08-30 20:29:09 +00:00
|
|
|
ostd::Uint32 *bcode = reinterpret_cast<ostd::Uint32 *>(p_code);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (bcode[-1] == CODE_START) {
|
|
|
|
delete[] bcode;
|
|
|
|
}
|
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-30 21:30:40 +00:00
|
|
|
CsValueType CsValue::get_type() const {
|
2016-08-25 20:24:23 +00:00
|
|
|
return p_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set_int(CsInt val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::integer;
|
2016-08-30 20:55:35 +00:00
|
|
|
p_i = val;
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set_float(CsFloat val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::number;
|
2016-08-30 20:55:35 +00:00
|
|
|
p_f = val;
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set_str(CsString val) {
|
|
|
|
if (val.size() == 0) {
|
|
|
|
/* ostd zero length strings cannot be disowned */
|
|
|
|
char *buf = new char[1];
|
|
|
|
buf[0] = '\0';
|
|
|
|
set_mstr(buf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ostd::CharRange cr = val.iter();
|
|
|
|
val.disown();
|
|
|
|
set_mstr(cr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set_null() {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::null;
|
2016-08-30 20:55:35 +00:00
|
|
|
p_code = nullptr;
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
void CsValue::set_code(CsBytecode *val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::code;
|
2016-08-30 20:29:09 +00:00
|
|
|
p_code = val;
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set_cstr(ostd::ConstCharRange val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::cstring;
|
2016-08-30 20:55:35 +00:00
|
|
|
p_len = val.size();
|
|
|
|
p_cstr = val.data();
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set_mstr(ostd::CharRange val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::string;
|
2016-08-30 20:55:35 +00:00
|
|
|
p_len = val.size();
|
|
|
|
p_s = val.data();
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsValue::set_ident(CsIdent *val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::ident;
|
2016-08-30 20:29:09 +00:00
|
|
|
p_id = val;
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
void CsValue::set_macro(ostd::ConstCharRange val) {
|
2016-08-30 21:30:40 +00:00
|
|
|
p_type = CsValueType::macro;
|
2016-08-30 20:55:35 +00:00
|
|
|
p_len = val.size();
|
|
|
|
p_cstr = val.data();
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CsValue::set(CsValue &tv) {
|
|
|
|
*this = tv;
|
2016-08-31 17:49:24 +00:00
|
|
|
tv.set_null();
|
2016-08-25 20:24:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void CsValue::force_null() {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (get_type() == CsValueType::null) {
|
2016-08-17 16:53:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
cleanup();
|
|
|
|
set_null();
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
CsFloat CsValue::force_float() {
|
2016-08-14 16:35:38 +00:00
|
|
|
CsFloat rf = 0.0f;
|
2015-08-13 20:48:03 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
rf = p_i;
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
rf = cs_parse_float(ostd::ConstCharRange(p_s, p_len));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
return p_f;
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
cleanup();
|
|
|
|
set_float(rf);
|
|
|
|
return rf;
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
CsInt CsValue::force_int() {
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt ri = 0;
|
2015-08-13 20:48:03 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
ri = p_f;
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
ri = cs_parse_int(ostd::ConstCharRange(p_s, p_len));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
return p_i;
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
cleanup();
|
|
|
|
set_int(ri);
|
|
|
|
return ri;
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
ostd::ConstCharRange CsValue::force_str() {
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString rs;
|
2015-08-13 20:48:03 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
rs = ostd::move(floatstr(p_f));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
rs = ostd::move(intstr(p_i));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
rs = ostd::ConstCharRange(p_s, p_len);
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
2016-08-30 20:55:35 +00:00
|
|
|
return ostd::ConstCharRange(p_s, p_len);
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
cleanup();
|
2016-07-13 18:24:26 +00:00
|
|
|
set_str(ostd::move(rs));
|
2016-08-30 20:55:35 +00:00
|
|
|
return ostd::ConstCharRange(p_s, p_len);
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
CsInt CsValue::get_int() const {
|
2016-08-17 23:53:14 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
return CsInt(p_f);
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
return p_i;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
return cs_parse_int(ostd::ConstCharRange(p_s, p_len));
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-11 20:41:12 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
CsFloat CsValue::get_float() const {
|
2016-08-17 23:53:14 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
return p_f;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
return CsFloat(p_i);
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
return cs_parse_float(ostd::ConstCharRange(p_s, p_len));
|
2016-08-30 21:30:40 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-11 20:41:12 +00:00
|
|
|
}
|
|
|
|
return 0.0f;
|
|
|
|
}
|
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecode *CsValue::get_code() const {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (get_type() != CsValueType::code) {
|
2016-07-30 20:42:49 +00:00
|
|
|
return nullptr;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-30 20:29:09 +00:00
|
|
|
return p_code;
|
2016-07-30 20:42:49 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *CsValue::get_ident() const {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (get_type() != CsValueType::ident) {
|
2016-08-01 20:35:42 +00:00
|
|
|
return nullptr;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-30 20:29:09 +00:00
|
|
|
return p_id;
|
2016-08-01 20:35:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString CsValue::get_str() const {
|
2016-08-17 23:53:14 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
|
|
|
return ostd::ConstCharRange(p_s, p_len);
|
|
|
|
case CsValueType::integer:
|
|
|
|
return intstr(p_i);
|
|
|
|
case CsValueType::number:
|
|
|
|
return floatstr(p_f);
|
|
|
|
default:
|
|
|
|
break;
|
2015-08-11 21:01:56 +00:00
|
|
|
}
|
2016-08-21 00:34:03 +00:00
|
|
|
return CsString("");
|
2015-08-11 21:01:56 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
ostd::ConstCharRange CsValue::get_strr() const {
|
2016-08-17 23:53:14 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
return ostd::ConstCharRange(p_s, p_len);
|
2016-08-17 16:53:38 +00:00
|
|
|
default:
|
|
|
|
break;
|
2016-07-30 23:49:32 +00:00
|
|
|
}
|
|
|
|
return ostd::ConstCharRange();
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void CsValue::get_val(CsValue &r) const {
|
2016-08-17 23:53:14 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
r.set_str(ostd::ConstCharRange(p_s, p_len));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
r.set_int(p_i);
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
r.set_float(p_f);
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r.set_null();
|
|
|
|
break;
|
2015-08-11 20:41:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code) {
|
2016-08-14 15:05:55 +00:00
|
|
|
if (!code) {
|
|
|
|
return true;
|
|
|
|
}
|
2016-08-17 16:53:38 +00:00
|
|
|
return (
|
2016-08-30 20:29:09 +00:00
|
|
|
*reinterpret_cast<ostd::Uint32 *>(code) & CODE_OP_MASK
|
2016-08-17 16:53:38 +00:00
|
|
|
) == CODE_EXIT;
|
2016-08-14 15:05:55 +00:00
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
bool CsValue::code_is_empty() const {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (get_type() != CsValueType::code) {
|
2016-08-14 15:05:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
2016-08-30 20:29:09 +00:00
|
|
|
return cscript::cs_code_is_empty(p_code);
|
2016-08-14 15:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool cs_get_bool(ostd::ConstCharRange s) {
|
2016-08-15 01:19:59 +00:00
|
|
|
if (s.empty()) {
|
2016-08-14 15:05:55 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-08-15 01:19:59 +00:00
|
|
|
ostd::ConstCharRange end = s;
|
2016-08-15 17:55:22 +00:00
|
|
|
CsInt ival = cs_parse_int(end, &end);
|
2016-08-15 01:19:59 +00:00
|
|
|
if (end.empty()) {
|
|
|
|
return !!ival;
|
|
|
|
}
|
|
|
|
end = s;
|
2016-08-15 17:55:22 +00:00
|
|
|
CsFloat fval = cs_parse_float(end, &end);
|
2016-08-15 01:19:59 +00:00
|
|
|
if (end.empty()) {
|
|
|
|
return !!fval;
|
2016-08-14 15:05:55 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
bool CsValue::get_bool() const {
|
2016-08-14 15:05:55 +00:00
|
|
|
switch (get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-30 20:55:35 +00:00
|
|
|
return p_f != 0;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-30 20:55:35 +00:00
|
|
|
return p_i != 0;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::macro:
|
|
|
|
case CsValueType::cstring:
|
2016-08-30 20:55:35 +00:00
|
|
|
return cs_get_bool(ostd::ConstCharRange(p_s, p_len));
|
2016-08-17 16:53:38 +00:00
|
|
|
default:
|
|
|
|
return false;
|
2016-08-14 15:05:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsAlias::get_cstr(CsValue &v) const {
|
2016-08-31 18:18:53 +00:00
|
|
|
switch (p_val.get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::macro:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_macro(p_val.get_strr());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::cstring:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_cstr(p_val.get_strr());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_str(ostd::move(intstr(p_val.get_int())));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_str(ostd::move(floatstr(p_val.get_float())));
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
v.set_cstr("");
|
|
|
|
break;
|
2015-08-11 20:41:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsAlias::get_cval(CsValue &v) const {
|
2016-08-31 18:18:53 +00:00
|
|
|
switch (p_val.get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::macro:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_macro(p_val.get_strr());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::cstring:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_cstr(p_val.get_strr());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_int(p_val.get_int());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number:
|
2016-08-31 18:18:53 +00:00
|
|
|
v.set_float(p_val.get_float());
|
2016-08-17 16:53:38 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
v.set_null();
|
|
|
|
break;
|
2015-08-11 20:41:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentType CsIdent::get_type() const {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (p_type > ID_ALIAS) {
|
2016-08-29 17:17:11 +00:00
|
|
|
return CsIdentType::special;
|
2016-08-10 17:33:43 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return CsIdentType(p_type);
|
2016-08-18 01:53:51 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
ostd::ConstCharRange CsIdent::get_name() const {
|
2016-08-18 01:53:51 +00:00
|
|
|
return p_name;
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
int CsIdent::get_flags() const {
|
2016-08-18 01:53:51 +00:00
|
|
|
return p_flags;
|
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
int CsIdent::get_index() const {
|
2016-08-18 01:53:51 +00:00
|
|
|
return p_index;
|
2016-08-10 17:33:43 +00:00
|
|
|
}
|
|
|
|
|
2016-08-22 17:43:58 +00:00
|
|
|
template<typename SF>
|
2016-08-29 17:17:11 +00:00
|
|
|
static inline bool cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if ((cs.identflags & IDF_OVERRIDDEN) || (vflags & IDF_OVERRIDE)) {
|
|
|
|
if (vflags & IDF_PERSIST) {
|
2016-08-17 21:29:31 +00:00
|
|
|
cs_debug_code(
|
2016-08-18 01:53:51 +00:00
|
|
|
cs, "cannot override persistent variable '%s'", v->get_name()
|
2016-08-17 21:29:31 +00:00
|
|
|
);
|
2015-08-07 01:11:53 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
if (!(vflags & IDF_OVERRIDDEN)) {
|
2015-08-07 01:11:53 +00:00
|
|
|
sf();
|
2016-08-18 01:53:51 +00:00
|
|
|
vflags |= IDF_OVERRIDDEN;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-07 01:11:53 +00:00
|
|
|
} else {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (vflags & IDF_OVERRIDDEN) {
|
|
|
|
vflags &= ~IDF_OVERRIDDEN;
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-17 16:53:38 +00:00
|
|
|
void CsState::set_var_int(
|
|
|
|
ostd::ConstCharRange name, CsInt v, bool dofunc, bool doclamp
|
|
|
|
) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIvar *iv = static_cast<CsIvar *>(id);
|
2016-08-17 16:53:38 +00:00
|
|
|
bool success = cs_override_var(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, iv, iv->p_flags,
|
2016-08-22 17:43:58 +00:00
|
|
|
[&iv]() { iv->p_overrideval = iv->get_value(); }
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
if (!success) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (doclamp) {
|
2016-08-22 17:43:58 +00:00
|
|
|
iv->set_value(ostd::clamp(v, iv->get_val_min(), iv->get_val_max()));
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
2016-08-22 17:43:58 +00:00
|
|
|
iv->set_value(v);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (dofunc) {
|
2016-08-17 21:29:31 +00:00
|
|
|
iv->changed();
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 16:53:38 +00:00
|
|
|
void CsState::set_var_float(
|
|
|
|
ostd::ConstCharRange name, CsFloat v, bool dofunc, bool doclamp
|
|
|
|
) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFvar *fv = static_cast<CsFvar *>(id);
|
2016-08-17 16:53:38 +00:00
|
|
|
bool success = cs_override_var(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, fv, fv->p_flags,
|
2016-08-22 17:43:58 +00:00
|
|
|
[&fv]() { fv->p_overrideval = fv->get_value(); }
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
if (!success) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (doclamp) {
|
2016-08-22 17:43:58 +00:00
|
|
|
fv->set_value(ostd::clamp(v, fv->get_val_min(), fv->get_val_max()));
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
2016-08-22 17:43:58 +00:00
|
|
|
fv->set_value(v);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (dofunc) {
|
2016-08-17 21:29:31 +00:00
|
|
|
fv->changed();
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 16:53:38 +00:00
|
|
|
void CsState::set_var_str(
|
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange v, bool dofunc
|
|
|
|
) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_svar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
CsSvar *sv = static_cast<CsSvar *>(id);
|
2016-08-17 16:53:38 +00:00
|
|
|
bool success = cs_override_var(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, sv, sv->p_flags,
|
2016-08-22 17:43:58 +00:00
|
|
|
[&sv]() { sv->p_overrideval = sv->get_value(); }
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
if (!success) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-22 17:43:58 +00:00
|
|
|
sv->set_value(v);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (dofunc) {
|
2016-08-17 21:29:31 +00:00
|
|
|
sv->changed();
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsInt> CsState::get_var_int(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsIvar *>(id)->get_value();
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsFloat> CsState::get_var_float(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsFvar *>(id)->get_value();
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString> CsState::get_var_str(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_svar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return CsString(static_cast<CsSvar *>(id)->get_value());
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsInt> CsState::get_var_min_int(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsIvar *>(id)->get_val_min();
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsInt> CsState::get_var_max_int(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_ivar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsIvar *>(id)->get_val_max();
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsFloat> CsState::get_var_min_float(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsFvar *>(id)->get_val_min();
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsFloat> CsState::get_var_max_float(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (!id || id->is_fvar()) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsFvar *>(id)->get_val_max();
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString>
|
2016-08-17 21:04:43 +00:00
|
|
|
CsState::get_alias_val(ostd::ConstCharRange name) {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *a = get_alias(name);
|
2016-08-17 21:29:31 +00:00
|
|
|
if (!a) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-18 01:53:51 +00:00
|
|
|
if (
|
|
|
|
(a->get_index() < MaxArguments) &&
|
2016-08-20 15:40:00 +00:00
|
|
|
!(p_stack->usedargs & (1 << a->get_index()))
|
2016-08-18 01:53:51 +00:00
|
|
|
) {
|
2015-08-07 01:11:53 +00:00
|
|
|
return ostd::nothing;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-31 18:18:53 +00:00
|
|
|
return ostd::move(a->get_value().get_str());
|
2015-08-07 01:11:53 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt cs_clamp_var(CsState &cs, CsIvar *iv, CsInt v) {
|
2016-08-18 02:14:55 +00: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 16:53:38 +00:00
|
|
|
} else {
|
2015-08-07 01:44:51 +00:00
|
|
|
return v;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
cs_debug_code(
|
|
|
|
cs,
|
2016-08-18 01:53:51 +00:00
|
|
|
(iv->get_flags() & IDF_HEX)
|
2016-08-17 16:53:38 +00:00
|
|
|
? (
|
2016-08-18 02:14:55 +00:00
|
|
|
(iv->get_val_min() <= 255)
|
2016-08-17 16:53:38 +00: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 02:14:55 +00:00
|
|
|
iv->get_name(), iv->get_val_min(), iv->get_val_max()
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
2015-08-07 01:44:51 +00:00
|
|
|
return v;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::set_var_int_checked(CsIvar *iv, CsInt v) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (iv->get_flags() & IDF_READONLY) {
|
|
|
|
cs_debug_code(*this, "variable '%s' is read only", iv->get_name());
|
2015-08-07 01:44:51 +00:00
|
|
|
return;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-17 16:53:38 +00:00
|
|
|
bool success = cs_override_var(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, iv, iv->p_flags,
|
2016-08-22 17:43:58 +00:00
|
|
|
[&iv]() { iv->p_overrideval = iv->get_value(); }
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
if (!success) {
|
2015-08-07 01:44:51 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-18 02:14:55 +00:00
|
|
|
if ((v < iv->get_val_min()) || (v > iv->get_val_max())) {
|
2016-08-17 21:29:31 +00:00
|
|
|
v = cs_clamp_var(*this, iv, v);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-22 17:43:58 +00:00
|
|
|
iv->set_value(v);
|
2016-08-17 21:29:31 +00:00
|
|
|
iv->changed();
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::set_var_int_checked(CsIvar *iv, CsValueRange args) {
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt v = args[0].force_int();
|
2016-08-18 01:53:51 +00:00
|
|
|
if ((iv->get_flags() & IDF_HEX) && (args.size() > 1)) {
|
2015-08-07 01:44:51 +00:00
|
|
|
v = (v << 16) | (args[1].force_int() << 8);
|
2016-08-17 16:53:38 +00:00
|
|
|
if (args.size() > 2) {
|
2015-08-07 01:44:51 +00:00
|
|
|
v |= args[2].force_int();
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-17 21:29:31 +00:00
|
|
|
set_var_int_checked(iv, v);
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFloat cs_clamp_fvar(CsState &cs, CsFvar *fv, CsFloat v) {
|
2016-08-18 02:14:55 +00: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 16:53:38 +00:00
|
|
|
} else {
|
2015-08-07 01:44:51 +00:00
|
|
|
return v;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
cs_debug_code(
|
2016-08-18 02:14:55 +00:00
|
|
|
cs, "valid range for '%s' is %s..%s", floatstr(fv->get_val_min()),
|
|
|
|
floatstr(fv->get_val_max())
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
2015-08-07 01:44:51 +00:00
|
|
|
return v;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (fv->get_flags() & IDF_READONLY) {
|
|
|
|
cs_debug_code(*this, "variable '%s' is read only", fv->get_name());
|
2015-08-07 01:44:51 +00:00
|
|
|
return;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-17 16:53:38 +00:00
|
|
|
bool success = cs_override_var(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, fv, fv->p_flags,
|
2016-08-22 17:43:58 +00:00
|
|
|
[&fv]() { fv->p_overrideval = fv->get_value(); }
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
if (!success) {
|
2015-08-07 01:44:51 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-18 02:14:55 +00:00
|
|
|
if ((v < fv->get_val_min()) || (v > fv->get_val_max())) {
|
2016-08-17 21:29:31 +00:00
|
|
|
v = cs_clamp_fvar(*this, fv, v);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-22 17:43:58 +00:00
|
|
|
fv->set_value(v);
|
2016-08-17 21:29:31 +00:00
|
|
|
fv->changed();
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void CsState::set_var_str_checked(CsSvar *sv, ostd::ConstCharRange v) {
|
2016-08-18 01:53:51 +00:00
|
|
|
if (sv->get_flags() & IDF_READONLY) {
|
|
|
|
cs_debug_code(*this, "variable '%s' is read only", sv->get_name());
|
2015-08-07 01:44:51 +00:00
|
|
|
return;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-08-17 16:53:38 +00:00
|
|
|
bool success = cs_override_var(
|
2016-08-18 01:53:51 +00:00
|
|
|
*this, sv, sv->p_flags,
|
2016-08-22 17:43:58 +00:00
|
|
|
[&sv]() { sv->p_overrideval = sv->get_value(); }
|
2016-08-17 16:53:38 +00:00
|
|
|
);
|
|
|
|
if (!success) {
|
|
|
|
return;
|
|
|
|
}
|
2016-08-22 17:43:58 +00:00
|
|
|
sv->set_value(v);
|
2016-08-17 21:29:31 +00:00
|
|
|
sv->changed();
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-10 17:33:43 +00:00
|
|
|
static bool cs_add_command(
|
|
|
|
CsState &cs, ostd::ConstCharRange name, ostd::ConstCharRange args,
|
|
|
|
CmdFunc func, int type = ID_COMMAND
|
|
|
|
) {
|
2015-08-07 22:37:54 +00:00
|
|
|
ostd::Uint32 argmask = 0;
|
2015-08-05 21:58:45 +00:00
|
|
|
int nargs = 0;
|
2016-08-17 16:53:38 +00: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 'D':
|
|
|
|
if (nargs < MaxArguments) {
|
|
|
|
nargs++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
case 's':
|
|
|
|
case 'e':
|
|
|
|
case 'r':
|
|
|
|
case '$':
|
|
|
|
if (nargs < MaxArguments) {
|
|
|
|
argmask |= 1 << nargs;
|
|
|
|
nargs++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '3':
|
|
|
|
case '4':
|
|
|
|
if (nargs < MaxArguments) {
|
|
|
|
fmt.push_front_n(fmt.front() - '0' + 1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
case 'V':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ostd::err.writefln(
|
|
|
|
"builtin %s declared with illegal type: %c",
|
|
|
|
name, fmt.front()
|
|
|
|
);
|
|
|
|
return false;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
}
|
2016-08-20 15:52:54 +00:00
|
|
|
cs.add_ident<Command>(type, name, args, argmask, nargs, ostd::move(func));
|
2015-08-05 21:58:45 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-08-10 17:33:43 +00:00
|
|
|
bool CsState::add_command(
|
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange args, CmdFunc func
|
|
|
|
) {
|
|
|
|
return cs_add_command(*this, name, args, ostd::move(func));
|
|
|
|
}
|
|
|
|
|
2016-08-06 15:34:10 +00:00
|
|
|
void cs_init_lib_io(CsState &cs) {
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "exec", "sb", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
auto file = args[0].get_strr();
|
|
|
|
bool ret = cs.run_file(file);
|
|
|
|
if (!ret) {
|
2016-08-17 16:53:38 +00:00
|
|
|
if (args[1].get_int()) {
|
2016-08-06 15:34:10 +00:00
|
|
|
ostd::err.writefln("could not run file \"%s\"", file);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(0);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(1);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "echo", "C", [](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00:00
|
|
|
ostd::writeln(args[0].get_strr());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-08-17 16:53:38 +00:00
|
|
|
static inline void cs_do_loop(
|
2016-08-29 17:17:11 +00:00
|
|
|
CsState &cs, CsIdent &id, CsInt offset, CsInt n, CsInt step,
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecode *cond, CsBytecode *body
|
2016-08-17 16:53:38 +00:00
|
|
|
) {
|
2016-08-31 17:49:24 +00:00
|
|
|
CsStackedValue idv{&id};
|
|
|
|
if (n <= 0 || !idv.has_alias()) {
|
2016-08-06 15:34:10 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-14 16:35:38 +00:00
|
|
|
for (CsInt i = 0; i < n; ++i) {
|
2016-08-31 17:49:24 +00:00
|
|
|
idv.set_int(offset + i * step);
|
|
|
|
idv.push();
|
2016-08-17 16:53:38 +00:00
|
|
|
if (cond && !cs.run_bool(cond)) {
|
|
|
|
break;
|
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
cs.run_int(body);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-11 17:14:18 +00:00
|
|
|
static inline void cs_loop_conc(
|
2016-08-29 17:17:11 +00:00
|
|
|
CsState &cs, CsValue &res, CsIdent &id, CsInt offset, CsInt n,
|
2016-08-28 17:40:18 +00:00
|
|
|
CsInt step, CsBytecode *body, bool space
|
2016-08-11 17:14:18 +00:00
|
|
|
) {
|
2016-08-31 17:49:24 +00:00
|
|
|
CsStackedValue idv{&id};
|
|
|
|
if (n <= 0 || !idv.has_alias()) {
|
2016-08-06 15:34:10 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-21 00:34:03 +00:00
|
|
|
CsVector<char> s;
|
2016-08-14 16:35:38 +00:00
|
|
|
for (CsInt i = 0; i < n; ++i) {
|
2016-08-31 17:49:24 +00:00
|
|
|
idv.set_int(offset + i * step);
|
|
|
|
idv.push();
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue v;
|
2016-08-06 15:34:10 +00:00
|
|
|
cs.run_ret(body, v);
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString vstr = ostd::move(v.get_str());
|
2016-08-17 16:53:38 +00:00
|
|
|
if (space && i) {
|
|
|
|
s.push(' ');
|
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
s.push_n(vstr.data(), vstr.size());
|
|
|
|
v.cleanup();
|
|
|
|
}
|
|
|
|
s.push('\0');
|
|
|
|
ostd::Size len = s.size() - 1;
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_mstr(ostd::CharRange(s.disown(), len));
|
2016-08-06 15:34:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void cs_init_lib_base(CsState &cs) {
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "do", "e", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
cs.run_ret(args[0].get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
}, ID_DO);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "doargs", "e", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-20 15:40:00 +00:00
|
|
|
if (cs.p_stack != &cs.noalias) {
|
2016-08-11 17:14:18 +00:00
|
|
|
cs_do_args(cs, [&]() { cs.run_ret(args[0].get_code(), res); });
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
2016-08-11 17:14:18 +00:00
|
|
|
cs.run_ret(args[0].get_code(), res);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
}, ID_DOARGS);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "if", "tee", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
cs.run_ret((args[0].get_bool() ? args[1] : args[2]).get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
}, ID_IF);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "result", "T", [](CsValueRange args, CsValue &res) {
|
|
|
|
CsValue &v = args[0];
|
2016-08-11 17:14:18 +00:00
|
|
|
res = v;
|
2016-08-06 15:34:10 +00:00
|
|
|
v.set_null();
|
|
|
|
}, ID_RESULT);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "!", "t", [](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(!args[0].get_bool());
|
2016-08-06 15:34:10 +00:00
|
|
|
}, ID_NOT);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "&&", "E1V", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-17 16:53:38 +00:00
|
|
|
if (args.empty()) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(1);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
|
|
|
for (ostd::Size i = 0; i < args.size(); ++i) {
|
|
|
|
if (i) {
|
|
|
|
res.cleanup();
|
|
|
|
}
|
2016-08-30 20:29:09 +00:00
|
|
|
CsBytecode *code = args[i].get_code();
|
|
|
|
if (code) {
|
|
|
|
cs.run_ret(code, res);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
|
|
|
res = args[i];
|
|
|
|
}
|
|
|
|
if (!res.get_bool()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
}
|
|
|
|
}, ID_AND);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "||", "E1V", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-17 16:53:38 +00:00
|
|
|
if (args.empty()) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(0);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
|
|
|
for (ostd::Size i = 0; i < args.size(); ++i) {
|
|
|
|
if (i) {
|
|
|
|
res.cleanup();
|
|
|
|
}
|
2016-08-30 20:29:09 +00:00
|
|
|
CsBytecode *code = args[i].get_code();
|
|
|
|
if (code) {
|
|
|
|
cs.run_ret(code, res);
|
2016-08-17 16:53:38 +00:00
|
|
|
} else {
|
|
|
|
res = args[i];
|
|
|
|
}
|
|
|
|
if (res.get_bool()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
}
|
|
|
|
}, ID_OR);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "?", "tTT", [](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set(args[0].get_bool() ? args[1] : args[2]);
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "cond", "ee2V", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
for (ostd::Size i = 0; i < args.size(); i += 2) {
|
|
|
|
if ((i + 1) < args.size()) {
|
2016-08-30 20:29:09 +00:00
|
|
|
if (cs.run_bool(args[i].get_code())) {
|
|
|
|
cs.run_ret(args[i + 1].get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2016-08-30 20:29:09 +00:00
|
|
|
cs.run_ret(args[i].get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "case", "ite2V", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-17 16:53:38 +00:00
|
|
|
CsInt val = args[0].get_int();
|
|
|
|
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (
|
|
|
|
(args[i].get_type() == CsValueType::null) ||
|
|
|
|
(args[i].get_int() == val)
|
|
|
|
) {
|
2016-08-30 20:29:09 +00:00
|
|
|
cs.run_ret(args[i + 1].get_code(), res);
|
2016-08-17 16:53:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "casef", "fte2V", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-17 16:53:38 +00:00
|
|
|
CsFloat val = args[0].get_float();
|
|
|
|
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (
|
|
|
|
(args[i].get_type() == CsValueType::null) ||
|
|
|
|
(args[i].get_float() == val)
|
|
|
|
) {
|
2016-08-30 20:29:09 +00:00
|
|
|
cs.run_ret(args[i + 1].get_code(), res);
|
2016-08-17 16:53:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-08-06 15:34:10 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "cases", "ste2V", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString val = args[0].get_str();
|
2016-08-17 16:53:38 +00:00
|
|
|
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
|
2016-08-30 21:30:40 +00:00
|
|
|
if (
|
|
|
|
(args[i].get_type() == CsValueType::null) ||
|
|
|
|
(args[i].get_str() == val)
|
|
|
|
) {
|
2016-08-30 20:29:09 +00:00
|
|
|
cs.run_ret(args[i + 1].get_code(), res);
|
2016-08-17 16:53:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-08-06 15:34:10 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "pushif", "rTe", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-31 17:49:24 +00:00
|
|
|
CsStackedValue idv{args[0].get_ident()};
|
|
|
|
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
|
2016-08-06 15:34:10 +00:00
|
|
|
return;
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-08-31 17:49:24 +00:00
|
|
|
if (args[1].get_bool()) {
|
|
|
|
idv.set(args[1]);
|
|
|
|
idv.push();
|
|
|
|
cs.run_ret(args[2].get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loop", "rie", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[1].get_int(), 1, nullptr,
|
|
|
|
args[2].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loop+", "riie", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
|
|
|
nullptr, args[3].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loop*", "riie", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[1].get_int(), args[2].get_int(),
|
|
|
|
nullptr, args[3].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loop+*", "riiie", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00: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-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopwhile", "riee", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_do_loop(
|
|
|
|
cs, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
|
|
|
args[2].get_code(), args[3].get_code()
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopwhile+", "riiee", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00: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-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopwhile*", "riiee", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00: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-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopwhile+*", "riiiee", [&cs](CsValueRange args, CsValue &) {
|
2016-08-06 15:34:10 +00: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-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "while", "ee", [&cs](CsValueRange args, CsValue &) {
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecode *cond = args[0].get_code(), *body = args[1].get_code();
|
2016-08-06 15:34:10 +00:00
|
|
|
while (cs.run_bool(cond)) {
|
|
|
|
cs.run_int(body);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcat", "rie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
2016-08-06 15:34:10 +00:00
|
|
|
args[2].get_code(), true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcat+", "riie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
2016-08-06 15:34:10 +00:00
|
|
|
args[3].get_code(), true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcat*", "riie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
|
2016-08-06 15:34:10 +00:00
|
|
|
args[3].get_code(), true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcat+*", "riiie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
2016-08-06 15:34:10 +00:00
|
|
|
args[2].get_int(), args[4].get_code(), true
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcatword", "rie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[1].get_int(), 1,
|
2016-08-06 15:34:10 +00:00
|
|
|
args[2].get_code(), false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcatword+", "riie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(), args[2].get_int(), 1,
|
2016-08-06 15:34:10 +00:00
|
|
|
args[3].get_code(), false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcatword*", "riie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), 0, args[2].get_int(), args[1].get_int(),
|
2016-08-06 15:34:10 +00:00
|
|
|
args[3].get_code(), false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "loopconcatword+*", "riiie", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
cs_loop_conc(
|
2016-08-11 17:14:18 +00:00
|
|
|
cs, res, *args[0].get_ident(), args[1].get_int(), args[3].get_int(),
|
2016-08-06 15:34:10 +00:00
|
|
|
args[2].get_int(), args[4].get_code(), false
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "nodebug", "e", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-06 15:34:10 +00:00
|
|
|
++cs.nodebug;
|
2016-08-11 17:14:18 +00:00
|
|
|
cs.run_ret(args[0].get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
--cs.nodebug;
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "push", "rTe", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-31 17:49:24 +00:00
|
|
|
CsStackedValue idv{args[0].get_ident()};
|
|
|
|
if (!idv.has_alias() || (idv.get_alias()->get_index() < MaxArguments)) {
|
2016-08-17 16:53:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-08-31 17:49:24 +00:00
|
|
|
idv.set(args[1]);
|
|
|
|
idv.push();
|
2016-08-11 17:14:18 +00:00
|
|
|
cs.run_ret(args[2].get_code(), res);
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-10 17:33:43 +00:00
|
|
|
cs_add_command(cs, "local", nullptr, nullptr, ID_LOCAL);
|
2016-08-06 15:34:10 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "resetvar", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(cs.reset_var(args[0].get_strr()));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "alias", "sT", [&cs](CsValueRange args, CsValue &) {
|
|
|
|
CsValue &v = args[1];
|
2016-08-06 15:34:10 +00:00
|
|
|
cs.set_alias(args[0].get_strr(), v);
|
|
|
|
v.set_null();
|
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "getvarmin", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(cs.get_var_min_int(args[0].get_strr()).value_or(0));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "getvarmax", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(cs.get_var_max_int(args[0].get_strr()).value_or(0));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "getfvarmin", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_float(cs.get_var_min_float(args[0].get_strr()).value_or(0.0f));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "getfvarmax", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_float(cs.get_var_max_float(args[0].get_strr()).value_or(0.0f));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "identexists", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-11 17:14:18 +00:00
|
|
|
res.set_int(cs.have_ident(args[0].get_strr()));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
cs_add_command(cs, "getalias", "s", [&cs](CsValueRange args, CsValue &res) {
|
2016-08-17 21:04:43 +00:00
|
|
|
res.set_str(ostd::move(cs.get_alias_val(args[0].get_strr()).value_or("")));
|
2016-08-06 15:34:10 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-08-02 00:21:36 +00: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 00:40:29 +00:00
|
|
|
|
2016-08-18 18:47:29 +00:00
|
|
|
OSTD_EXPORT void CsState::init_libs(int libs) {
|
2016-08-17 16:53:38 +00:00
|
|
|
if (libs & CS_LIB_IO) {
|
2016-08-18 18:47:29 +00:00
|
|
|
cs_init_lib_io(*this);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (libs & CS_LIB_MATH) {
|
2016-08-18 18:47:29 +00:00
|
|
|
cs_init_lib_math(*this);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (libs & CS_LIB_STRING) {
|
2016-08-18 18:47:29 +00:00
|
|
|
cs_init_lib_string(*this);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
|
|
|
if (libs & CS_LIB_LIST) {
|
2016-08-18 18:47:29 +00:00
|
|
|
cs_init_lib_list(*this);
|
2016-08-17 16:53:38 +00:00
|
|
|
}
|
2016-02-28 22:21:28 +00:00
|
|
|
}
|
|
|
|
|
2016-02-07 21:22:39 +00:00
|
|
|
} /* namespace cscript */
|