From 66c707a232cebe30567868bd0e4b0e6b282ce091 Mon Sep 17 00:00:00 2001 From: q66 Date: Wed, 17 Aug 2016 22:04:43 +0100 Subject: [PATCH] start splitting Ident --- cs_gen.cc | 6 ++- cs_vm.cc | 39 +++++++++++----- cubescript.cc | 121 +++++++++++++++++++++++++++++------------------- cubescript.hh | 124 ++++++++++++++++++++++++++++---------------------- 4 files changed, 176 insertions(+), 114 deletions(-) diff --git a/cs_gen.cc b/cs_gen.cc index 4b9a710..7bc36c1 100644 --- a/cs_gen.cc +++ b/cs_gen.cc @@ -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(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(id)->cargs; + for (; *fmt; fmt++) { switch (*fmt) { case 'S': case 's': diff --git a/cs_vm.cc b/cs_vm.cc index 942a11e..e7646c9 100644 --- a/cs_vm.cc +++ b/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(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(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(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(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(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(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(id)->numargs) { TaggedValue buf[MaxArguments]; memcpy(buf, args.data(), args.size() * sizeof(TaggedValue)); - callcommand(*this, id, buf, ret, nargs, false); + callcommand( + *this, static_cast(id), buf, ret, + nargs, false + ); } else { - callcommand(*this, id, args.data(), ret, nargs, false); + callcommand( + *this, static_cast(id), args.data(), + ret, nargs, false + ); } nargs = 0; break; diff --git a/cubescript.cc b/cubescript.cc index 2705740..5f05cb7 100644 --- a/cubescript.cc +++ b/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(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(i)->force_null(); delete[] reinterpret_cast(i->code); } else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) { - delete[] i->cargs; + delete[] static_cast(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 CsState::get_var_max_float(ostd::ConstCharRange name) { } ostd::Maybe -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(""))); }); } diff --git a/cubescript.hh b/cubescript.hh index 6c8179a..d4fd4cf 100644 --- a/cubescript.hh +++ b/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; -using CmdFunc = ostd::Function; 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; + +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(id); + } + bool have_ident(ostd::ConstCharRange name) { return idents.at(name) != nullptr; } @@ -437,7 +453,7 @@ struct OSTD_EXPORT CsState { ostd::Maybe get_var_min_float(ostd::ConstCharRange name); ostd::Maybe get_var_max_float(ostd::ConstCharRange name); - ostd::Maybe get_alias(ostd::ConstCharRange name); + ostd::Maybe get_alias_val(ostd::ConstCharRange name); void print_var(Ident *id); void print_var_int(Ident *id, CsInt i);