start splitting Ident
parent
03c3145956
commit
66c707a232
|
@ -515,7 +515,8 @@ lookupid:
|
|||
if (prevargs >= MaxResults) {
|
||||
gs.code.push(CODE_ENTER);
|
||||
}
|
||||
for (char const *fmt = id->cargs; *fmt; fmt++) {
|
||||
char const *fmt = static_cast<Command *>(id)->cargs;
|
||||
for (; *fmt; fmt++) {
|
||||
switch (*fmt) {
|
||||
case 'S':
|
||||
gs.gen_str();
|
||||
|
@ -1190,7 +1191,8 @@ noid:
|
|||
case ID_COMMAND: {
|
||||
int comtype = CODE_COM, fakeargs = 0;
|
||||
bool rep = false;
|
||||
for (char const *fmt = id->cargs; *fmt; fmt++) {
|
||||
char const *fmt = static_cast<Command *>(id)->cargs;
|
||||
for (; *fmt; fmt++) {
|
||||
switch (*fmt) {
|
||||
case 'S':
|
||||
case 's':
|
||||
|
|
39
cs_vm.cc
39
cs_vm.cc
|
@ -6,6 +6,14 @@
|
|||
|
||||
namespace cscript {
|
||||
|
||||
static inline bool cs_has_cmd_cb(Ident *id) {
|
||||
if ((id->type != ID_COMMAND) && (id->type < ID_LOCAL)) {
|
||||
return false;
|
||||
}
|
||||
Command *cb = static_cast<Command *>(id);
|
||||
return !!cb->cb_cftv;
|
||||
}
|
||||
|
||||
ostd::ConstCharRange cs_debug_line(
|
||||
CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt,
|
||||
ostd::CharRange buf
|
||||
|
@ -256,7 +264,7 @@ void TaggedValue::copy_arg(TaggedValue &r) const {
|
|||
}
|
||||
|
||||
static inline void callcommand(
|
||||
CsState &cs, Ident *id, TaggedValue *args, TaggedValue &res, int numargs,
|
||||
CsState &cs, Command *id, TaggedValue *args, TaggedValue &res, int numargs,
|
||||
bool lookup = false
|
||||
) {
|
||||
int i = -1, fakeargs = 0;
|
||||
|
@ -522,7 +530,7 @@ static inline int cs_get_lookupu_type(
|
|||
arg.cleanup();
|
||||
arg.set_null();
|
||||
TaggedValue buf[MaxArguments];
|
||||
callcommand(cs, id, buf, arg, 0, true);
|
||||
callcommand(cs, static_cast<Command *>(id), buf, arg, 0, true);
|
||||
force_arg(arg, op & CODE_RET_MASK);
|
||||
return -2; /* ignore */
|
||||
}
|
||||
|
@ -1234,7 +1242,7 @@ static ostd::Uint32 const *runcode(
|
|||
case CODE_COM | RET_STR:
|
||||
case CODE_COM | RET_FLOAT:
|
||||
case CODE_COM | RET_INT: {
|
||||
Ident *id = cs.identmap[op >> 8];
|
||||
Command *id = static_cast<Command *>(cs.identmap[op >> 8]);
|
||||
int offset = numargs - id->numargs;
|
||||
result.force_null();
|
||||
id->cb_cftv(TvalRange(args + offset, id->numargs), result);
|
||||
|
@ -1247,7 +1255,7 @@ static ostd::Uint32 const *runcode(
|
|||
case CODE_COMV | RET_STR:
|
||||
case CODE_COMV | RET_FLOAT:
|
||||
case CODE_COMV | RET_INT: {
|
||||
Ident *id = cs.identmap[op >> 13];
|
||||
Command *id = static_cast<Command *>(cs.identmap[op >> 13]);
|
||||
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
||||
result.force_null();
|
||||
id->cb_cftv(ostd::iter(&args[offset], callargs), result);
|
||||
|
@ -1259,7 +1267,7 @@ static ostd::Uint32 const *runcode(
|
|||
case CODE_COMC | RET_STR:
|
||||
case CODE_COMC | RET_FLOAT:
|
||||
case CODE_COMC | RET_INT: {
|
||||
Ident *id = cs.identmap[op >> 13];
|
||||
Command *id = static_cast<Command *>(cs.identmap[op >> 13]);
|
||||
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
||||
result.force_null();
|
||||
{
|
||||
|
@ -1397,7 +1405,7 @@ noid:
|
|||
result.force_null();
|
||||
switch (id->type) {
|
||||
default:
|
||||
if (!id->cb_cftv) {
|
||||
if (!cs_has_cmd_cb(id)) {
|
||||
free_args(args, numargs, offset - 1);
|
||||
force_arg(result, op & CODE_RET_MASK);
|
||||
continue;
|
||||
|
@ -1405,7 +1413,10 @@ noid:
|
|||
/* fallthrough */
|
||||
case ID_COMMAND:
|
||||
idarg.cleanup();
|
||||
callcommand(cs, id, &args[offset], result, callargs);
|
||||
callcommand(
|
||||
cs, static_cast<Command *>(id), &args[offset],
|
||||
result, callargs
|
||||
);
|
||||
force_arg(result, op & CODE_RET_MASK);
|
||||
numargs = offset - 1;
|
||||
continue;
|
||||
|
@ -1506,17 +1517,23 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
|||
} else if (id) {
|
||||
switch (id->type) {
|
||||
default:
|
||||
if (!id->cb_cftv) {
|
||||
if (!cs_has_cmd_cb(id)) {
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case ID_COMMAND:
|
||||
if (nargs < id->numargs) {
|
||||
if (nargs < static_cast<Command *>(id)->numargs) {
|
||||
TaggedValue buf[MaxArguments];
|
||||
memcpy(buf, args.data(), args.size() * sizeof(TaggedValue));
|
||||
callcommand(*this, id, buf, ret, nargs, false);
|
||||
callcommand(
|
||||
*this, static_cast<Command *>(id), buf, ret,
|
||||
nargs, false
|
||||
);
|
||||
} else {
|
||||
callcommand(*this, id, args.data(), ret, nargs, false);
|
||||
callcommand(
|
||||
*this, static_cast<Command *>(id), args.data(),
|
||||
ret, nargs, false
|
||||
);
|
||||
}
|
||||
nargs = 0;
|
||||
break;
|
||||
|
|
121
cubescript.cc
121
cubescript.cc
|
@ -41,73 +41,100 @@ bool cs_check_num(ostd::ConstCharRange s) {
|
|||
Ident::Ident(): type(ID_UNKNOWN) {}
|
||||
|
||||
/* ID_IVAR */
|
||||
Ident::Ident(
|
||||
Ivar::Ivar(
|
||||
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s, VarCb f, int flagsv
|
||||
):
|
||||
type(ID_IVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n),
|
||||
minval(m), maxval(x), cb_var(ostd::move(f))
|
||||
{
|
||||
) {
|
||||
type = ID_IVAR;
|
||||
flags = flagsv | (m > x ? IDF_READONLY : 0);
|
||||
name = n;
|
||||
minval = m;
|
||||
maxval = x;
|
||||
cb_var = ostd::move(f);
|
||||
storage.ip = s;
|
||||
}
|
||||
|
||||
/* ID_FVAR */
|
||||
Ident::Ident(
|
||||
Fvar::Fvar(
|
||||
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
|
||||
VarCb f, int flagsv
|
||||
):
|
||||
type(ID_FVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n),
|
||||
minvalf(m), maxvalf(x), cb_var(ostd::move(f))
|
||||
{
|
||||
) {
|
||||
type = ID_FVAR;
|
||||
flags = flagsv | (m > x ? IDF_READONLY : 0);
|
||||
name = n;
|
||||
minvalf = m;
|
||||
maxvalf = x;
|
||||
cb_var = ostd::move(f);
|
||||
storage.fp = s;
|
||||
}
|
||||
|
||||
/* ID_SVAR */
|
||||
Ident::Ident(ostd::ConstCharRange n, char **s, VarCb f, int flagsv):
|
||||
type(ID_SVAR), flags(flagsv), name(n), cb_var(ostd::move(f))
|
||||
{
|
||||
Svar::Svar(ostd::ConstCharRange n, char **s, VarCb f, int flagsv) {
|
||||
type = ID_SVAR;
|
||||
flags = flagsv;
|
||||
name = n;
|
||||
cb_var = ostd::move(f);
|
||||
storage.sp = s;
|
||||
}
|
||||
|
||||
/* ID_ALIAS */
|
||||
Ident::Ident(ostd::ConstCharRange n, char *a, int flagsv):
|
||||
type(ID_ALIAS), valtype(VAL_STR), flags(flagsv), name(n), code(nullptr),
|
||||
stack(nullptr)
|
||||
{
|
||||
Alias::Alias(ostd::ConstCharRange n, char *a, int flagsv) {
|
||||
type = ID_ALIAS;
|
||||
valtype = VAL_STR;
|
||||
flags = flagsv;
|
||||
name = n;
|
||||
code = nullptr;
|
||||
stack = nullptr;
|
||||
val.s = a;
|
||||
val.len = strlen(a);
|
||||
}
|
||||
Ident::Ident(ostd::ConstCharRange n, CsInt a, int flagsv):
|
||||
type(ID_ALIAS), valtype(VAL_INT), flags(flagsv), name(n), code(nullptr),
|
||||
stack(nullptr)
|
||||
{
|
||||
Alias::Alias(ostd::ConstCharRange n, CsInt a, int flagsv) {
|
||||
type = ID_ALIAS;
|
||||
valtype = VAL_INT;
|
||||
flags = flagsv;
|
||||
name = n;
|
||||
code = nullptr;
|
||||
stack = nullptr;
|
||||
val.i = a;
|
||||
}
|
||||
Ident::Ident(ostd::ConstCharRange n, CsFloat a, int flagsv):
|
||||
type(ID_ALIAS), valtype(VAL_FLOAT), flags(flagsv), name(n), code(nullptr),
|
||||
stack(nullptr)
|
||||
{
|
||||
Alias::Alias(ostd::ConstCharRange n, CsFloat a, int flagsv) {
|
||||
type = ID_ALIAS;
|
||||
valtype = VAL_FLOAT;
|
||||
flags = flagsv;
|
||||
name = n;
|
||||
code = nullptr;
|
||||
stack = nullptr;
|
||||
val.f = a;
|
||||
}
|
||||
Ident::Ident(ostd::ConstCharRange n, int flagsv):
|
||||
type(ID_ALIAS), valtype(VAL_NULL), flags(flagsv), name(n), code(nullptr),
|
||||
stack(nullptr)
|
||||
{}
|
||||
Ident::Ident(ostd::ConstCharRange n, TaggedValue const &v, int flagsv):
|
||||
type(ID_ALIAS), valtype(v.p_type), flags(flagsv), name(n), code(nullptr),
|
||||
stack(nullptr)
|
||||
{
|
||||
Alias::Alias(ostd::ConstCharRange n, int flagsv) {
|
||||
type = ID_ALIAS;
|
||||
valtype = VAL_NULL;
|
||||
flags = flagsv;
|
||||
name = n;
|
||||
code = nullptr;
|
||||
stack = nullptr;
|
||||
}
|
||||
Alias::Alias(ostd::ConstCharRange n, TaggedValue const &v, int flagsv) {
|
||||
type = ID_ALIAS;
|
||||
valtype = v.p_type;
|
||||
flags = flagsv;
|
||||
name = n;
|
||||
code = nullptr;
|
||||
stack = nullptr;
|
||||
val = v;
|
||||
}
|
||||
|
||||
/* ID_COMMAND */
|
||||
Ident::Ident(
|
||||
Command::Command(
|
||||
int t, ostd::ConstCharRange n, ostd::ConstCharRange args,
|
||||
ostd::Uint32 argmask, int numargs, CmdFunc f
|
||||
ostd::Uint32 amask, int nargs, CmdFunc f
|
||||
):
|
||||
type(t), numargs(numargs), flags(0), name(n),
|
||||
cargs(!args.empty() ? cs_dup_ostr(args) : nullptr),
|
||||
argmask(argmask), cb_cftv(ostd::move(f))
|
||||
{}
|
||||
argmask(amask), numargs(nargs), cb_cftv(ostd::move(f))
|
||||
{
|
||||
type = t;
|
||||
flags = 0;
|
||||
name = n;
|
||||
}
|
||||
|
||||
void cs_init_lib_base(CsState &cs);
|
||||
|
||||
|
@ -122,8 +149,8 @@ CsState::CsState() {
|
|||
new_ident(static_cast<char const *>(buf), IDF_ARG);
|
||||
}
|
||||
dummy = new_ident("//dummy");
|
||||
add_ident(new Ident("numargs", MaxArguments, 0, &numargs));
|
||||
add_ident(new Ident("dbgalias", 0, 1000, &dbgalias));
|
||||
add_ident(new Ivar("numargs", MaxArguments, 0, &numargs));
|
||||
add_ident(new Ivar("dbgalias", 0, 1000, &dbgalias));
|
||||
cs_init_lib_base(*this);
|
||||
}
|
||||
|
||||
|
@ -131,10 +158,10 @@ CsState::~CsState() {
|
|||
for (auto &p: idents.iter()) {
|
||||
Ident *i = p.second;
|
||||
if (i->type == ID_ALIAS) {
|
||||
i->force_null();
|
||||
static_cast<Alias *>(i)->force_null();
|
||||
delete[] reinterpret_cast<ostd::Uint32 *>(i->code);
|
||||
} else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) {
|
||||
delete[] i->cargs;
|
||||
delete[] static_cast<Command *>(i)->cargs;
|
||||
}
|
||||
delete i;
|
||||
}
|
||||
|
@ -186,7 +213,7 @@ Ident *CsState::new_ident(ostd::ConstCharRange name, int flags) {
|
|||
);
|
||||
return dummy;
|
||||
}
|
||||
id = add_ident(new Ident(name, flags));
|
||||
id = add_ident(new Alias(name, flags));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
@ -264,7 +291,7 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
|
|||
cs_debug_code(*this, "cannot alias number %s", name);
|
||||
v.cleanup();
|
||||
} else {
|
||||
add_ident(new Ident(name, v, identflags));
|
||||
add_ident(new Alias(name, v, identflags));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -860,7 +887,7 @@ ostd::Maybe<CsFloat> CsState::get_var_max_float(ostd::ConstCharRange name) {
|
|||
}
|
||||
|
||||
ostd::Maybe<ostd::String>
|
||||
CsState::get_alias(ostd::ConstCharRange name) {
|
||||
CsState::get_alias_val(ostd::ConstCharRange name) {
|
||||
Ident *id = get_ident(name);
|
||||
if (!id || id->is_alias()) {
|
||||
return ostd::nothing;
|
||||
|
@ -1027,7 +1054,7 @@ static bool cs_add_command(
|
|||
return false;
|
||||
}
|
||||
}
|
||||
cs.add_ident(new Ident(type, name, args, argmask, nargs, ostd::move(func)));
|
||||
cs.add_ident(new Command(type, name, args, argmask, nargs, ostd::move(func)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1420,7 +1447,7 @@ void cs_init_lib_base(CsState &cs) {
|
|||
});
|
||||
|
||||
cs_add_command(cs, "getalias", "s", [&cs](TvalRange args, TaggedValue &res) {
|
||||
res.set_str(ostd::move(cs.get_alias(args[0].get_strr()).value_or("")));
|
||||
res.set_str(ostd::move(cs.get_alias_val(args[0].get_strr()).value_or("")));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
124
cubescript.hh
124
cubescript.hh
|
@ -65,6 +65,7 @@ private:
|
|||
OSTD_EXPORT bool code_is_empty(Bytecode const *code);
|
||||
|
||||
struct Ident;
|
||||
struct Alias;
|
||||
|
||||
struct IdentValue {
|
||||
union {
|
||||
|
@ -79,7 +80,7 @@ struct IdentValue {
|
|||
};
|
||||
|
||||
struct OSTD_EXPORT TaggedValue: IdentValue {
|
||||
friend struct Ident;
|
||||
friend struct Alias;
|
||||
|
||||
int get_type() const {
|
||||
return p_type;
|
||||
|
@ -172,7 +173,6 @@ union IdentValuePtr {
|
|||
struct CsState;
|
||||
|
||||
using VarCb = ostd::Function<void(Ident &)>;
|
||||
using CmdFunc = ostd::Function<void(TvalRange, TaggedValue &)>;
|
||||
|
||||
enum class IdentType {
|
||||
unknown = -1,
|
||||
|
@ -181,10 +181,7 @@ enum class IdentType {
|
|||
|
||||
struct OSTD_EXPORT Ident {
|
||||
ostd::byte type; /* ID_something */
|
||||
union {
|
||||
int valtype; /* ID_ALIAS */
|
||||
int numargs; /* ID_COMMAND */
|
||||
};
|
||||
int valtype; /* ID_ALIAS */
|
||||
ostd::ushort flags;
|
||||
int index;
|
||||
ostd::String name;
|
||||
|
@ -206,46 +203,8 @@ struct OSTD_EXPORT Ident {
|
|||
IdentValue val;
|
||||
IdentStack *stack;
|
||||
};
|
||||
struct { /* ID_COMMAND */
|
||||
char *cargs;
|
||||
ostd::Uint32 argmask;
|
||||
};
|
||||
};
|
||||
VarCb cb_var;
|
||||
CmdFunc cb_cftv;
|
||||
|
||||
Ident();
|
||||
|
||||
/* ID_IVAR */
|
||||
Ident(
|
||||
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s,
|
||||
VarCb f = VarCb(), int flags = 0
|
||||
);
|
||||
|
||||
/* ID_FVAR */
|
||||
Ident(
|
||||
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
|
||||
VarCb f = VarCb(), int flags = 0
|
||||
);
|
||||
|
||||
/* ID_SVAR */
|
||||
Ident(
|
||||
ostd::ConstCharRange n, char **s, VarCb f = VarCb(),
|
||||
int flags = 0
|
||||
);
|
||||
|
||||
/* ID_ALIAS */
|
||||
Ident(ostd::ConstCharRange n, char *a, int flags);
|
||||
Ident(ostd::ConstCharRange n, CsInt a, int flags);
|
||||
Ident(ostd::ConstCharRange n, CsFloat a, int flags);
|
||||
Ident(ostd::ConstCharRange n, int flags);
|
||||
Ident(ostd::ConstCharRange n, TaggedValue const &v, int flags);
|
||||
|
||||
/* ID_COMMAND */
|
||||
Ident(
|
||||
int t, ostd::ConstCharRange n, ostd::ConstCharRange args,
|
||||
ostd::Uint32 argmask, int numargs, CmdFunc f = CmdFunc()
|
||||
);
|
||||
|
||||
void changed() {
|
||||
if (cb_var) {
|
||||
|
@ -263,15 +222,6 @@ struct OSTD_EXPORT Ident {
|
|||
val = v.val;
|
||||
}
|
||||
|
||||
void force_null() {
|
||||
if (valtype == VAL_STR) {
|
||||
delete[] val.s;
|
||||
val.s = nullptr;
|
||||
val.len = 0;
|
||||
}
|
||||
valtype = VAL_NULL;
|
||||
}
|
||||
|
||||
CsFloat get_float() const;
|
||||
CsInt get_int() const;
|
||||
ostd::String get_str() const;
|
||||
|
@ -323,6 +273,64 @@ struct OSTD_EXPORT Ident {
|
|||
bool is_svar() const {
|
||||
return get_type() == IdentType::svar;
|
||||
}
|
||||
|
||||
protected:
|
||||
Ident();
|
||||
};
|
||||
|
||||
struct Var: Ident {
|
||||
};
|
||||
|
||||
struct Ivar: Var {
|
||||
Ivar(
|
||||
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s,
|
||||
VarCb f = VarCb(), int flags = 0
|
||||
);
|
||||
};
|
||||
|
||||
struct Fvar: Var {
|
||||
Fvar(
|
||||
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
|
||||
VarCb f = VarCb(), int flags = 0
|
||||
);
|
||||
};
|
||||
|
||||
struct Svar: Var {
|
||||
Svar(
|
||||
ostd::ConstCharRange n, char **s, VarCb f = VarCb(),
|
||||
int flags = 0
|
||||
);
|
||||
};
|
||||
|
||||
struct Alias: Ident {
|
||||
Alias(ostd::ConstCharRange n, char *a, int flags);
|
||||
Alias(ostd::ConstCharRange n, CsInt a, int flags);
|
||||
Alias(ostd::ConstCharRange n, CsFloat a, int flags);
|
||||
Alias(ostd::ConstCharRange n, int flags);
|
||||
Alias(ostd::ConstCharRange n, TaggedValue const &v, int flags);
|
||||
|
||||
void force_null() {
|
||||
if (valtype == VAL_STR) {
|
||||
delete[] val.s;
|
||||
val.s = nullptr;
|
||||
val.len = 0;
|
||||
}
|
||||
valtype = VAL_NULL;
|
||||
}
|
||||
};
|
||||
|
||||
using CmdFunc = ostd::Function<void(TvalRange, TaggedValue &)>;
|
||||
|
||||
struct Command: Ident {
|
||||
char *cargs;
|
||||
ostd::Uint32 argmask;
|
||||
int numargs;
|
||||
CmdFunc cb_cftv;
|
||||
|
||||
Command(
|
||||
int t, ostd::ConstCharRange n, ostd::ConstCharRange args,
|
||||
ostd::Uint32 argmask, int numargs, CmdFunc f = CmdFunc()
|
||||
);
|
||||
};
|
||||
|
||||
struct IdentLink {
|
||||
|
@ -375,6 +383,14 @@ struct OSTD_EXPORT CsState {
|
|||
return *id;
|
||||
}
|
||||
|
||||
Alias *get_alias(ostd::ConstCharRange name) {
|
||||
Ident *id = get_ident(name);
|
||||
if (!id->is_alias()) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Alias *>(id);
|
||||
}
|
||||
|
||||
bool have_ident(ostd::ConstCharRange name) {
|
||||
return idents.at(name) != nullptr;
|
||||
}
|
||||
|
@ -437,7 +453,7 @@ struct OSTD_EXPORT CsState {
|
|||
ostd::Maybe<CsFloat> get_var_min_float(ostd::ConstCharRange name);
|
||||
ostd::Maybe<CsFloat> get_var_max_float(ostd::ConstCharRange name);
|
||||
|
||||
ostd::Maybe<ostd::String> get_alias(ostd::ConstCharRange name);
|
||||
ostd::Maybe<ostd::String> get_alias_val(ostd::ConstCharRange name);
|
||||
|
||||
void print_var(Ident *id);
|
||||
void print_var_int(Ident *id, CsInt i);
|
||||
|
|
Loading…
Reference in New Issue