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) { if (prevargs >= MaxResults) {
gs.code.push(CODE_ENTER); 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) { switch (*fmt) {
case 'S': case 'S':
gs.gen_str(); gs.gen_str();
@ -1190,7 +1191,8 @@ noid:
case ID_COMMAND: { case ID_COMMAND: {
int comtype = CODE_COM, fakeargs = 0; int comtype = CODE_COM, fakeargs = 0;
bool rep = false; bool rep = false;
for (char const *fmt = id->cargs; *fmt; fmt++) { char const *fmt = static_cast<Command *>(id)->cargs;
for (; *fmt; fmt++) {
switch (*fmt) { switch (*fmt) {
case 'S': case 'S':
case 's': case 's':

View File

@ -6,6 +6,14 @@
namespace cscript { 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( ostd::ConstCharRange cs_debug_line(
CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt, CsState &cs, ostd::ConstCharRange p, ostd::ConstCharRange fmt,
ostd::CharRange buf ostd::CharRange buf
@ -256,7 +264,7 @@ void TaggedValue::copy_arg(TaggedValue &r) const {
} }
static inline void callcommand( 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 bool lookup = false
) { ) {
int i = -1, fakeargs = 0; int i = -1, fakeargs = 0;
@ -522,7 +530,7 @@ static inline int cs_get_lookupu_type(
arg.cleanup(); arg.cleanup();
arg.set_null(); arg.set_null();
TaggedValue buf[MaxArguments]; 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); force_arg(arg, op & CODE_RET_MASK);
return -2; /* ignore */ return -2; /* ignore */
} }
@ -1234,7 +1242,7 @@ static ostd::Uint32 const *runcode(
case CODE_COM | RET_STR: case CODE_COM | RET_STR:
case CODE_COM | RET_FLOAT: case CODE_COM | RET_FLOAT:
case CODE_COM | RET_INT: { 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; int offset = numargs - id->numargs;
result.force_null(); result.force_null();
id->cb_cftv(TvalRange(args + offset, id->numargs), result); 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_STR:
case CODE_COMV | RET_FLOAT: case CODE_COMV | RET_FLOAT:
case CODE_COMV | RET_INT: { 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; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
result.force_null(); result.force_null();
id->cb_cftv(ostd::iter(&args[offset], callargs), result); 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_STR:
case CODE_COMC | RET_FLOAT: case CODE_COMC | RET_FLOAT:
case CODE_COMC | RET_INT: { 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; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
result.force_null(); result.force_null();
{ {
@ -1397,7 +1405,7 @@ noid:
result.force_null(); result.force_null();
switch (id->type) { switch (id->type) {
default: default:
if (!id->cb_cftv) { if (!cs_has_cmd_cb(id)) {
free_args(args, numargs, offset - 1); free_args(args, numargs, offset - 1);
force_arg(result, op & CODE_RET_MASK); force_arg(result, op & CODE_RET_MASK);
continue; continue;
@ -1405,7 +1413,10 @@ noid:
/* fallthrough */ /* fallthrough */
case ID_COMMAND: case ID_COMMAND:
idarg.cleanup(); 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); force_arg(result, op & CODE_RET_MASK);
numargs = offset - 1; numargs = offset - 1;
continue; continue;
@ -1506,17 +1517,23 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
} else if (id) { } else if (id) {
switch (id->type) { switch (id->type) {
default: default:
if (!id->cb_cftv) { if (!cs_has_cmd_cb(id)) {
break; break;
} }
/* fallthrough */ /* fallthrough */
case ID_COMMAND: case ID_COMMAND:
if (nargs < id->numargs) { if (nargs < static_cast<Command *>(id)->numargs) {
TaggedValue buf[MaxArguments]; TaggedValue buf[MaxArguments];
memcpy(buf, args.data(), args.size() * sizeof(TaggedValue)); 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 { } else {
callcommand(*this, id, args.data(), ret, nargs, false); callcommand(
*this, static_cast<Command *>(id), args.data(),
ret, nargs, false
);
} }
nargs = 0; nargs = 0;
break; break;

View File

@ -41,73 +41,100 @@ bool cs_check_num(ostd::ConstCharRange s) {
Ident::Ident(): type(ID_UNKNOWN) {} Ident::Ident(): type(ID_UNKNOWN) {}
/* ID_IVAR */ /* ID_IVAR */
Ident::Ident( Ivar::Ivar(
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s, VarCb f, int flagsv 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), type = ID_IVAR;
minval(m), maxval(x), cb_var(ostd::move(f)) flags = flagsv | (m > x ? IDF_READONLY : 0);
{ name = n;
minval = m;
maxval = x;
cb_var = ostd::move(f);
storage.ip = s; storage.ip = s;
} }
/* ID_FVAR */ /* ID_FVAR */
Ident::Ident( Fvar::Fvar(
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s, ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
VarCb f, int flagsv VarCb f, int flagsv
): ) {
type(ID_FVAR), flags(flagsv | (m > x ? IDF_READONLY : 0)), name(n), type = ID_FVAR;
minvalf(m), maxvalf(x), cb_var(ostd::move(f)) flags = flagsv | (m > x ? IDF_READONLY : 0);
{ name = n;
minvalf = m;
maxvalf = x;
cb_var = ostd::move(f);
storage.fp = s; storage.fp = s;
} }
/* ID_SVAR */ /* ID_SVAR */
Ident::Ident(ostd::ConstCharRange n, char **s, VarCb f, int flagsv): Svar::Svar(ostd::ConstCharRange n, char **s, VarCb f, int flagsv) {
type(ID_SVAR), flags(flagsv), name(n), cb_var(ostd::move(f)) type = ID_SVAR;
{ flags = flagsv;
name = n;
cb_var = ostd::move(f);
storage.sp = s; storage.sp = s;
} }
/* ID_ALIAS */ /* ID_ALIAS */
Ident::Ident(ostd::ConstCharRange n, char *a, int flagsv): Alias::Alias(ostd::ConstCharRange n, char *a, int flagsv) {
type(ID_ALIAS), valtype(VAL_STR), flags(flagsv), name(n), code(nullptr), type = ID_ALIAS;
stack(nullptr) valtype = VAL_STR;
{ flags = flagsv;
name = n;
code = nullptr;
stack = nullptr;
val.s = a; val.s = a;
val.len = strlen(a); val.len = strlen(a);
} }
Ident::Ident(ostd::ConstCharRange n, CsInt a, int flagsv): Alias::Alias(ostd::ConstCharRange n, CsInt a, int flagsv) {
type(ID_ALIAS), valtype(VAL_INT), flags(flagsv), name(n), code(nullptr), type = ID_ALIAS;
stack(nullptr) valtype = VAL_INT;
{ flags = flagsv;
name = n;
code = nullptr;
stack = nullptr;
val.i = a; val.i = a;
} }
Ident::Ident(ostd::ConstCharRange n, CsFloat a, int flagsv): Alias::Alias(ostd::ConstCharRange n, CsFloat a, int flagsv) {
type(ID_ALIAS), valtype(VAL_FLOAT), flags(flagsv), name(n), code(nullptr), type = ID_ALIAS;
stack(nullptr) valtype = VAL_FLOAT;
{ flags = flagsv;
name = n;
code = nullptr;
stack = nullptr;
val.f = a; val.f = a;
} }
Ident::Ident(ostd::ConstCharRange n, int flagsv): Alias::Alias(ostd::ConstCharRange n, int flagsv) {
type(ID_ALIAS), valtype(VAL_NULL), flags(flagsv), name(n), code(nullptr), type = ID_ALIAS;
stack(nullptr) valtype = VAL_NULL;
{} flags = flagsv;
Ident::Ident(ostd::ConstCharRange n, TaggedValue const &v, int flagsv): name = n;
type(ID_ALIAS), valtype(v.p_type), flags(flagsv), name(n), code(nullptr), code = nullptr;
stack(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; val = v;
} }
/* ID_COMMAND */ /* ID_COMMAND */
Ident::Ident( Command::Command(
int t, ostd::ConstCharRange n, ostd::ConstCharRange args, 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), 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); void cs_init_lib_base(CsState &cs);
@ -122,8 +149,8 @@ CsState::CsState() {
new_ident(static_cast<char const *>(buf), IDF_ARG); new_ident(static_cast<char const *>(buf), IDF_ARG);
} }
dummy = new_ident("//dummy"); dummy = new_ident("//dummy");
add_ident(new Ident("numargs", MaxArguments, 0, &numargs)); add_ident(new Ivar("numargs", MaxArguments, 0, &numargs));
add_ident(new Ident("dbgalias", 0, 1000, &dbgalias)); add_ident(new Ivar("dbgalias", 0, 1000, &dbgalias));
cs_init_lib_base(*this); cs_init_lib_base(*this);
} }
@ -131,10 +158,10 @@ CsState::~CsState() {
for (auto &p: idents.iter()) { for (auto &p: idents.iter()) {
Ident *i = p.second; Ident *i = p.second;
if (i->type == ID_ALIAS) { if (i->type == ID_ALIAS) {
i->force_null(); static_cast<Alias *>(i)->force_null();
delete[] reinterpret_cast<ostd::Uint32 *>(i->code); delete[] reinterpret_cast<ostd::Uint32 *>(i->code);
} else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) { } else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) {
delete[] i->cargs; delete[] static_cast<Command *>(i)->cargs;
} }
delete i; delete i;
} }
@ -186,7 +213,7 @@ Ident *CsState::new_ident(ostd::ConstCharRange name, int flags) {
); );
return dummy; return dummy;
} }
id = add_ident(new Ident(name, flags)); id = add_ident(new Alias(name, flags));
} }
return id; return id;
} }
@ -264,7 +291,7 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
cs_debug_code(*this, "cannot alias number %s", name); cs_debug_code(*this, "cannot alias number %s", name);
v.cleanup(); v.cleanup();
} else { } 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> ostd::Maybe<ostd::String>
CsState::get_alias(ostd::ConstCharRange name) { CsState::get_alias_val(ostd::ConstCharRange name) {
Ident *id = get_ident(name); Ident *id = get_ident(name);
if (!id || id->is_alias()) { if (!id || id->is_alias()) {
return ostd::nothing; return ostd::nothing;
@ -1027,7 +1054,7 @@ static bool cs_add_command(
return false; 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; return true;
} }
@ -1420,7 +1447,7 @@ void cs_init_lib_base(CsState &cs) {
}); });
cs_add_command(cs, "getalias", "s", [&cs](TvalRange args, TaggedValue &res) { 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); OSTD_EXPORT bool code_is_empty(Bytecode const *code);
struct Ident; struct Ident;
struct Alias;
struct IdentValue { struct IdentValue {
union { union {
@ -79,7 +80,7 @@ struct IdentValue {
}; };
struct OSTD_EXPORT TaggedValue: IdentValue { struct OSTD_EXPORT TaggedValue: IdentValue {
friend struct Ident; friend struct Alias;
int get_type() const { int get_type() const {
return p_type; return p_type;
@ -172,7 +173,6 @@ union IdentValuePtr {
struct CsState; struct CsState;
using VarCb = ostd::Function<void(Ident &)>; using VarCb = ostd::Function<void(Ident &)>;
using CmdFunc = ostd::Function<void(TvalRange, TaggedValue &)>;
enum class IdentType { enum class IdentType {
unknown = -1, unknown = -1,
@ -181,10 +181,7 @@ enum class IdentType {
struct OSTD_EXPORT Ident { struct OSTD_EXPORT Ident {
ostd::byte type; /* ID_something */ ostd::byte type; /* ID_something */
union { int valtype; /* ID_ALIAS */
int valtype; /* ID_ALIAS */
int numargs; /* ID_COMMAND */
};
ostd::ushort flags; ostd::ushort flags;
int index; int index;
ostd::String name; ostd::String name;
@ -206,46 +203,8 @@ struct OSTD_EXPORT Ident {
IdentValue val; IdentValue val;
IdentStack *stack; IdentStack *stack;
}; };
struct { /* ID_COMMAND */
char *cargs;
ostd::Uint32 argmask;
};
}; };
VarCb cb_var; 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() { void changed() {
if (cb_var) { if (cb_var) {
@ -263,15 +222,6 @@ struct OSTD_EXPORT Ident {
val = v.val; 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; CsFloat get_float() const;
CsInt get_int() const; CsInt get_int() const;
ostd::String get_str() const; ostd::String get_str() const;
@ -323,6 +273,64 @@ struct OSTD_EXPORT Ident {
bool is_svar() const { bool is_svar() const {
return get_type() == IdentType::svar; 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 { struct IdentLink {
@ -375,6 +383,14 @@ struct OSTD_EXPORT CsState {
return *id; 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) { bool have_ident(ostd::ConstCharRange name) {
return idents.at(name) != nullptr; 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_min_float(ostd::ConstCharRange name);
ostd::Maybe<CsFloat> get_var_max_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(Ident *id);
void print_var_int(Ident *id, CsInt i); void print_var_int(Ident *id, CsInt i);