start splitting Ident

master
Daniel Kolesa 2016-08-17 22:04:43 +01:00
parent 03c3145956
commit 66c707a232
4 changed files with 176 additions and 114 deletions

View File

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

View File

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

View File

@ -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("")));
});
}

View File

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