From f3b3751f76a182013b6ce381811dde5a8f93e308 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 18 Aug 2016 02:53:51 +0100 Subject: [PATCH] clean up Ident interface --- cs_gen.cc | 126 +++++++++++++++++++++------------------ cs_vm.cc | 82 +++++++++++++------------ cs_vm.hh | 4 +- cubescript.cc | 161 ++++++++++++++++++++++++++++++-------------------- cubescript.hh | 35 ++++++----- 5 files changed, 232 insertions(+), 176 deletions(-) diff --git a/cs_gen.cc b/cs_gen.cc index 7bc36c1..ada1275 100644 --- a/cs_gen.cc +++ b/cs_gen.cc @@ -422,11 +422,11 @@ static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) { lookupid: Ident *id = gs.cs.new_ident(lookup.get()); if (id) { - switch (id->type) { - case ID_IVAR: + switch (id->get_type()) { + case IdentType::ivar: gs.code.push( CODE_IVAR | cs_ret_code(ltype, RET_INT) | - (id->index << 8) + (id->get_index() << 8) ); switch (ltype) { case VAL_POP: @@ -440,10 +440,10 @@ lookupid: break; } return; - case ID_FVAR: + case IdentType::fvar: gs.code.push( CODE_FVAR | cs_ret_code(ltype, RET_FLOAT) | - (id->index << 8) + (id->get_index() << 8) ); switch (ltype) { case VAL_POP: @@ -457,7 +457,7 @@ lookupid: break; } return; - case ID_SVAR: + case IdentType::svar: switch (ltype) { case VAL_POP: return; @@ -466,51 +466,53 @@ lookupid: case VAL_CODE: case VAL_IDENT: case VAL_COND: - gs.code.push(CODE_SVARM | (id->index << 8)); + gs.code.push( + CODE_SVARM | (id->get_index() << 8) + ); break; default: gs.code.push( CODE_SVAR | cs_ret_code(ltype, RET_STR) | - (id->index << 8) + (id->get_index() << 8) ); break; } goto done; - case ID_ALIAS: + case IdentType::alias: switch (ltype) { case VAL_POP: return; case VAL_CANY: case VAL_COND: gs.code.push( - (id->index < MaxArguments + (id->get_index() < MaxArguments ? CODE_LOOKUPMARG : CODE_LOOKUPM - ) | (id->index << 8) + ) | (id->get_index() << 8) ); break; case VAL_CSTR: case VAL_CODE: case VAL_IDENT: gs.code.push( - (id->index < MaxArguments + (id->get_index() < MaxArguments ? CODE_LOOKUPMARG : CODE_LOOKUPM - ) | RET_STR | (id->index << 8) + ) | RET_STR | (id->get_index() << 8) ); break; default: gs.code.push( - (id->index < MaxArguments + (id->get_index() < MaxArguments ? CODE_LOOKUPARG : CODE_LOOKUP ) | cs_ret_code(ltype, RET_STR) | - (id->index << 8) + (id->get_index() << 8) ); break; } goto done; - case ID_COMMAND: { + case IdentType::command: { int comtype = CODE_COM, numargs = 0; if (prevargs >= MaxResults) { gs.code.push(CODE_ENTER); @@ -578,7 +580,7 @@ lookupid: } } gs.code.push( - comtype | cs_ret_code(ltype) | (id->index << 8) + comtype | cs_ret_code(ltype) | (id->get_index() << 8) ); gs.code.push( (prevargs >= MaxResults @@ -590,7 +592,7 @@ lookupid: compilecomv: gs.code.push( comtype | cs_ret_code(ltype) | (numargs << 8) | - (id->index << 13) + (id->get_index() << 13) ); gs.code.push( (prevargs >= MaxResults @@ -740,24 +742,26 @@ static bool compileblocksub(GenState &gs, int prevargs) { lookupid: Ident *id = gs.cs.new_ident(lookup.get()); if (id) { - switch (id->type) { - case ID_IVAR: - gs.code.push(CODE_IVAR | (id->index << 8)); + switch (id->get_type()) { + case IdentType::ivar: + gs.code.push(CODE_IVAR | (id->get_index() << 8)); goto done; - case ID_FVAR: - gs.code.push(CODE_FVAR | (id->index << 8)); + case IdentType::fvar: + gs.code.push(CODE_FVAR | (id->get_index() << 8)); goto done; - case ID_SVAR: - gs.code.push(CODE_SVARM | (id->index << 8)); + case IdentType::svar: + gs.code.push(CODE_SVARM | (id->get_index() << 8)); goto done; - case ID_ALIAS: + case IdentType::alias: gs.code.push( - (id->index < MaxArguments + (id->get_index() < MaxArguments ? CODE_LOOKUPMARG : CODE_LOOKUPM - ) | (id->index << 8) + ) | (id->get_index() << 8) ); goto done; + default: + break; } } gs.gen_str(lookup.get(), true); @@ -1091,39 +1095,48 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs) if (idname) { Ident *id = gs.cs.new_ident(idname.get()); if (id) { - switch (id->type) { - case ID_ALIAS: + switch (id->get_type()) { + case IdentType::alias: more = compilearg(gs, VAL_ANY, prevargs); if (!more) { gs.gen_str(); } gs.code.push( - (id->index < MaxArguments + (id->get_index() < MaxArguments ? CODE_ALIASARG - : CODE_ALIAS) | (id->index << 8) + : CODE_ALIAS + ) | (id->get_index() << 8) ); goto endstatement; - case ID_IVAR: + case IdentType::ivar: more = compilearg(gs, VAL_INT, prevargs); if (!more) { gs.gen_int(); } - gs.code.push(CODE_IVAR1 | (id->index << 8)); + gs.code.push( + CODE_IVAR1 | (id->get_index() << 8) + ); goto endstatement; - case ID_FVAR: + case IdentType::fvar: more = compilearg(gs, VAL_FLOAT, prevargs); if (!more) { gs.gen_float(); } - gs.code.push(CODE_FVAR1 | (id->index << 8)); + gs.code.push( + CODE_FVAR1 | (id->get_index() << 8) + ); goto endstatement; - case ID_SVAR: + case IdentType::svar: more = compilearg(gs, VAL_CSTR, prevargs); if (!more) { gs.gen_str(); } - gs.code.push(CODE_SVAR1 | (id->index << 8)); + gs.code.push( + CODE_SVAR1 | (id->get_index() << 8) + ); goto endstatement; + default: + break; } } gs.gen_str(idname.get(), true); @@ -1172,7 +1185,7 @@ noid: } gs.code.push(CODE_RESULT); } else { - switch (id->type) { + switch (id->get_type_raw()) { case ID_ALIAS: while (numargs < MaxArguments) { more = compilearg(gs, VAL_ANY, prevargs + numargs); @@ -1182,10 +1195,10 @@ noid: ++numargs; } gs.code.push( - (id->index < MaxArguments + (id->get_index() < MaxArguments ? CODE_CALLARG : CODE_CALL - ) | (numargs << 8) | (id->index << 13) + ) | (numargs << 8) | (id->get_index() << 13) ); break; case ID_COMMAND: { @@ -1406,13 +1419,14 @@ noid: } } gs.code.push( - comtype | cs_ret_code(rettype) | (id->index << 8) + comtype | cs_ret_code(rettype) | + (id->get_index() << 8) ); break; compilecomv: gs.code.push( comtype | cs_ret_code(rettype) | (numargs << 8) | - (id->index << 13) + (id->get_index() << 13) ); break; } @@ -1512,7 +1526,7 @@ compilecomv: } gs.code.push( CODE_COM | cs_ret_code(rettype) | - (id->index << 8) + (id->get_index() << 8) ); } } @@ -1541,7 +1555,7 @@ compilecomv: } if (!more) { gs.code.push( - (id->type == ID_AND + ((id->get_type_raw() == ID_AND) ? CODE_TRUE : CODE_FALSE ) | cs_ret_code(rettype) @@ -1580,10 +1594,10 @@ compilecomv: } gs.code.push( CODE_COMV | cs_ret_code(rettype) | - (numargs << 8) | (id->index << 13) + (numargs << 8) | (id->get_index() << 13) ); } else { - ostd::Uint32 op = id->type == ID_AND + ostd::Uint32 op = (id->get_type_raw() == ID_AND) ? CODE_JUMP_RESULT_FALSE : CODE_JUMP_RESULT_TRUE; gs.code.push(op); @@ -1604,29 +1618,29 @@ compilecomv: break; case ID_IVAR: if (!(more = compilearg(gs, VAL_INT, prevargs))) { - gs.code.push(CODE_PRINT | (id->index << 8)); - } else if (!(id->flags & IDF_HEX) || !( + gs.code.push(CODE_PRINT | (id->get_index() << 8)); + } else if (!(id->get_flags() & IDF_HEX) || !( more = compilearg(gs, VAL_INT, prevargs + 1) )) { - gs.code.push(CODE_IVAR1 | (id->index << 8)); + gs.code.push(CODE_IVAR1 | (id->get_index() << 8)); } else if (!( more = compilearg(gs, VAL_INT, prevargs + 2) )) { - gs.code.push(CODE_IVAR2 | (id->index << 8)); + gs.code.push(CODE_IVAR2 | (id->get_index() << 8)); } else { - gs.code.push(CODE_IVAR3 | (id->index << 8)); + gs.code.push(CODE_IVAR3 | (id->get_index() << 8)); } break; case ID_FVAR: if (!(more = compilearg(gs, VAL_FLOAT, prevargs))) { - gs.code.push(CODE_PRINT | (id->index << 8)); + gs.code.push(CODE_PRINT | (id->get_index() << 8)); } else { - gs.code.push(CODE_FVAR1 | (id->index << 8)); + gs.code.push(CODE_FVAR1 | (id->get_index() << 8)); } break; case ID_SVAR: if (!(more = compilearg(gs, VAL_CSTR, prevargs))) { - gs.code.push(CODE_PRINT | (id->index << 8)); + gs.code.push(CODE_PRINT | (id->get_index() << 8)); } else { do { ++numargs; @@ -1638,7 +1652,7 @@ compilecomv: if (numargs > 1) { gs.code.push(CODE_CONC | RET_STR | (numargs << 8)); } - gs.code.push(CODE_SVAR1 | (id->index << 8)); + gs.code.push(CODE_SVAR1 | (id->get_index() << 8)); } break; } diff --git a/cs_vm.cc b/cs_vm.cc index 3a02dd8..2176e5f 100644 --- a/cs_vm.cc +++ b/cs_vm.cc @@ -7,7 +7,7 @@ namespace cscript { static inline bool cs_has_cmd_cb(Ident *id) { - if ((id->type != ID_COMMAND) && (id->type < ID_LOCAL)) { + if (!id->is_command() && !id->is_special()) { return false; } Command *cb = static_cast(id); @@ -15,13 +15,13 @@ static inline bool cs_has_cmd_cb(Ident *id) { } static inline void cs_push_alias(Ident *id, IdentStack &st) { - if ((id->type == ID_ALIAS) && (id->index >= MaxArguments)) { + if (id->is_alias() && (id->get_index() >= MaxArguments)) { static_cast(id)->push_arg(null_value, st); } } static inline void cs_pop_alias(Ident *id) { - if ((id->type == ID_ALIAS) && (id->index >= MaxArguments)) { + if (id->is_alias() && (id->get_index() >= MaxArguments)) { static_cast(id)->pop_arg(); } } @@ -72,11 +72,11 @@ void cs_debug_alias(CsState &cs) { Ident *id = l->id; ++depth; if (depth < cs.dbgalias) { - ostd::err.writefln(" %d) %s", total - depth + 1, id->name); + ostd::err.writefln(" %d) %s", total - depth + 1, id->get_name()); } else if (l->next == &cs.noalias) { ostd::err.writefln( depth == cs.dbgalias ? " %d) %s" : " ..%d) %s", - total - depth + 1, id->name + total - depth + 1, id->get_name() ); } } @@ -458,7 +458,7 @@ static inline void cs_call_alias( int oldargs = cs.numargs; cs.numargs = callargs; int oldflags = cs.identflags; - cs.identflags |= a->flags&IDF_OVERRIDDEN; + cs.identflags |= a->get_flags()&IDF_OVERRIDDEN; IdentLink aliaslink = { a, cs.stack, (1<> 8]; - if (id->flags & IDF_UNKNOWN) { - cs_debug_code(cs, "unknown alias lookup: %s", id->name); + if (id->get_flags() & IDF_UNKNOWN) { + cs_debug_code(cs, "unknown alias lookup: %s", id->get_name()); } return static_cast(id); } static inline Alias *cs_get_lookuparg_id(CsState &cs, ostd::Uint32 op) { Ident *id = cs.identmap[op >> 8]; - if (!(cs.stack->usedargs&(1<index))) { + if (!(cs.stack->usedargs & (1 << id->get_index()))) { return nullptr; } return static_cast(id); @@ -520,29 +520,29 @@ static inline int cs_get_lookupu_type( } id = cs.get_ident(arg.s); if (id) { - switch(id->type) { - case ID_ALIAS: - if (id->flags & IDF_UNKNOWN) { + switch(id->get_type()) { + case IdentType::alias: + if (id->get_flags() & IDF_UNKNOWN) { break; } arg.cleanup(); if ( - (id->index < MaxArguments) && - !(cs.stack->usedargs & (1 << id->index)) + (id->get_index() < MaxArguments) && + !(cs.stack->usedargs & (1 << id->get_index())) ) { return ID_UNKNOWN; } return ID_ALIAS; - case ID_SVAR: + case IdentType::svar: arg.cleanup(); return ID_SVAR; - case ID_IVAR: + case IdentType::ivar: arg.cleanup(); return ID_IVAR; - case ID_FVAR: + case IdentType::fvar: arg.cleanup(); return ID_FVAR; - case ID_COMMAND: { + case IdentType::command: { arg.cleanup(); arg.set_null(); TaggedValue buf[MaxArguments]; @@ -940,9 +940,11 @@ static ostd::Uint32 const *runcode( continue; case CODE_IDENTARG: { Alias *a = static_cast(cs.identmap[op >> 8]); - if (!(cs.stack->usedargs & (1 << a->index))) { - a->push_arg(null_value, cs.stack->argstack[a->index], false); - cs.stack->usedargs |= 1 << a->index; + if (!(cs.stack->usedargs & (1 << a->get_index()))) { + a->push_arg( + null_value, cs.stack->argstack[a->get_index()], false + ); + cs.stack->usedargs |= 1 << a->get_index(); } args[numargs++].set_ident(a); continue; @@ -957,11 +959,14 @@ static ostd::Uint32 const *runcode( ) { id = cs.new_ident(ostd::ConstCharRange(arg.cstr, arg.len)); } - if (id->index < MaxArguments && !(cs.stack->usedargs & (1 << id->index))) { + if ( + id->get_index() < MaxArguments && + !(cs.stack->usedargs & (1 << id->get_index())) + ) { static_cast(id)->push_arg( - null_value, cs.stack->argstack[id->index], false + null_value, cs.stack->argstack[id->get_index()], false ); - cs.stack->usedargs |= 1 << id->index; + cs.stack->usedargs |= 1 << id->get_index(); } arg.cleanup(); arg.set_ident(id); @@ -1397,8 +1402,8 @@ static ostd::Uint32 const *runcode( result.force_null(); Ident *id = cs.identmap[op >> 13]; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs; - if (id->flags & IDF_UNKNOWN) { - cs_debug_code(cs, "unknown command: %s", id->name); + if (id->get_flags() & IDF_UNKNOWN) { + cs_debug_code(cs, "unknown command: %s", id->get_name()); free_args(args, numargs, offset); force_arg(result, op & CODE_RET_MASK); continue; @@ -1416,7 +1421,7 @@ static ostd::Uint32 const *runcode( result.force_null(); Ident *id = cs.identmap[op >> 13]; int callargs = (op >> 8) & 0x1F, offset = numargs - callargs; - if (!(cs.stack->usedargs & (1 << id->index))) { + if (!(cs.stack->usedargs & (1 << id->get_index()))) { free_args(args, numargs, offset); force_arg(result, op & CODE_RET_MASK); continue; @@ -1461,7 +1466,7 @@ noid: continue; } result.force_null(); - switch (id->type) { + switch (id->get_type_raw()) { default: if (!cs_has_cmd_cb(id)) { free_args(args, numargs, offset - 1); @@ -1531,8 +1536,8 @@ noid: case ID_ALIAS: { Alias *a = static_cast(id); if ( - a->index < MaxArguments && - !(cs.stack->usedargs & (1 << a->index)) + a->get_index() < MaxArguments && + !(cs.stack->usedargs & (1 << a->get_index())) ) { free_args(args, numargs, offset - 1); force_arg(result, op & CODE_RET_MASK); @@ -1572,7 +1577,6 @@ void CsState::run_ret(ostd::ConstCharRange code, TaggedValue &ret) { } } -/* TODO */ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) { int nargs = int(args.size()); ret.set_null(); @@ -1580,13 +1584,13 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) { if (rundepth > MaxRunDepth) { cs_debug_code(*this, "exceeded recursion limit"); } else if (id) { - switch (id->type) { + switch (id->get_type()) { default: if (!cs_has_cmd_cb(id)) { break; } /* fallthrough */ - case ID_COMMAND: + case IdentType::command: if (nargs < static_cast(id)->numargs) { TaggedValue buf[MaxArguments]; memcpy(buf, args.data(), args.size() * sizeof(TaggedValue)); @@ -1602,14 +1606,14 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) { } nargs = 0; break; - case ID_IVAR: + case IdentType::ivar: if (args.empty()) { print_var(static_cast(id)); } else { set_var_int_checked(static_cast(id), args); } break; - case ID_FVAR: + case IdentType::fvar: if (args.empty()) { print_var(static_cast(id)); } else { @@ -1618,7 +1622,7 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) { ); } break; - case ID_SVAR: + case IdentType::svar: if (args.empty()) { print_var(static_cast(id)); } else { @@ -1627,10 +1631,10 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) { ); } break; - case ID_ALIAS: { + case IdentType::alias: { Alias *a = static_cast(id); - if (a->index < MaxArguments) { - if (!(stack->usedargs & (1 << a->index))) { + if (a->get_index() < MaxArguments) { + if (!(stack->usedargs & (1 << a->get_index()))) { break; } } diff --git a/cs_vm.hh b/cs_vm.hh index be325ba..29a433f 100644 --- a/cs_vm.hh +++ b/cs_vm.hh @@ -205,10 +205,10 @@ struct GenState { void gen_ident(Ident *id) { code.push( - ((id->index < MaxArguments) + ((id->get_index() < MaxArguments) ? CODE_IDENTARG : CODE_IDENT - ) | (id->index << 8) + ) | (id->get_index() << 8) ); } diff --git a/cubescript.cc b/cubescript.cc index b4b8848..02eee03 100644 --- a/cubescript.cc +++ b/cubescript.cc @@ -39,7 +39,7 @@ bool cs_check_num(ostd::ConstCharRange s) { } Ident::Ident(IdentType tp, ostd::ConstCharRange nm, int fl): - type(int(tp)), flags(fl), name(nm) + p_name(nm), p_type(int(tp)), p_flags(fl) {} Var::Var(IdentType tp, ostd::ConstCharRange name, VarCb f, int fl): @@ -98,11 +98,11 @@ Command::Command( int tp, ostd::ConstCharRange name, ostd::ConstCharRange args, ostd::Uint32 amask, int nargs, CmdFunc f ): - Ident(IdentType::unknown, name, 0), + Ident(IdentType::command, name, 0), cargs(!args.empty() ? cs_dup_ostr(args) : nullptr), argmask(amask), numargs(nargs), cb_cftv(ostd::move(f)) { - type = tp; + p_type = tp; } bool Ident::is_alias() const { @@ -127,6 +127,10 @@ bool Ident::is_command() const { return get_type() == IdentType::command; } +bool Ident::is_special() const { + return get_type() == IdentType::special; +} + bool Ident::is_var() const { IdentType tp = get_type(); return (tp >= IdentType::ivar) && (tp <= IdentType::svar); @@ -221,11 +225,11 @@ CsState::CsState() { CsState::~CsState() { for (auto &p: idents.iter()) { Ident *i = p.second; - if (i->type == ID_ALIAS) { - Alias *a = static_cast(i); + Alias *a = i->get_alias(); + if (a) { a->force_null(); delete[] reinterpret_cast(a->code); - } else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) { + } else if (i->is_command() || i->is_special()) { delete[] static_cast(i)->cargs; } delete i; @@ -233,38 +237,40 @@ CsState::~CsState() { } void CsState::clear_override(Ident &id) { - if (!(id.flags & IDF_OVERRIDDEN)) { + if (!(id.get_flags() & IDF_OVERRIDDEN)) { return; } - switch (id.type) { - case ID_ALIAS: { + switch (id.get_type()) { + case IdentType::alias: { Alias &a = static_cast(id); a.val_v.cleanup(); a.clean_code(); a.val_v.set_str(""); break; } - case ID_IVAR: { + case IdentType::ivar: { Ivar &iv = static_cast(id); *iv.storage = iv.overrideval; iv.changed(); break; } - case ID_FVAR: { + case IdentType::fvar: { Fvar &fv = static_cast(id); *fv.storage = fv.overrideval; fv.changed(); break; } - case ID_SVAR: { + case IdentType::svar: { Svar &sv = static_cast(id); delete[] *sv.storage; *sv.storage = sv.overrideval; sv.changed(); break; } + default: + break; } - id.flags &= ~IDF_OVERRIDDEN; + id.p_flags &= ~IDF_OVERRIDDEN; } void CsState::clear_overrides() { @@ -273,6 +279,15 @@ void CsState::clear_overrides() { } } +Ident *CsState::add_ident(Ident *id) { + if (!id) { + return nullptr; + } + idents[id->get_name()] = id; + id->p_index = identmap.size(); + return identmap.push(id); +} + Ident *CsState::new_ident(ostd::ConstCharRange name, int flags) { Ident *id = get_ident(name); if (!id) { @@ -314,8 +329,8 @@ bool CsState::reset_var(ostd::ConstCharRange name) { if (!id) { return false; } - if (id->flags & IDF_READONLY) { - cs_debug_code(*this, "variable %s is read only", id->name); + if (id->get_flags() & IDF_READONLY) { + cs_debug_code(*this, "variable %s is read only", id->get_name()); return false; } clear_override(*id); @@ -332,28 +347,29 @@ void CsState::touch_var(ostd::ConstCharRange name) { void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) { Ident *id = get_ident(name); if (id) { - switch (id->type) { - case ID_ALIAS: { + switch (id->get_type()) { + case IdentType::alias: { Alias *a = static_cast(id); - if (a->index < MaxArguments) { + if (a->get_index() < MaxArguments) { a->set_arg(*this, v); } else { a->set_alias(*this, v); } return; } - case ID_IVAR: + case IdentType::ivar: set_var_int_checked(static_cast(id), v.get_int()); break; - case ID_FVAR: + case IdentType::fvar: set_var_float_checked(static_cast(id), v.get_float()); break; - case ID_SVAR: + case IdentType::svar: set_var_str_checked(static_cast(id), v.get_str()); break; default: cs_debug_code( - *this, "cannot redefine builtin %s with an alias", id->name + *this, "cannot redefine builtin %s with an alias", + id->get_name() ); break; } @@ -368,32 +384,32 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) { void CsState::print_var_int(Ivar *iv, CsInt i) { if (i < 0) { - writefln("%s = %d", iv->name, i); + writefln("%s = %d", iv->get_name(), i); return; } - if (iv->flags & IDF_HEX) { + if (iv->get_flags() & IDF_HEX) { if (iv->maxval == 0xFFFFFF) { writefln( - "%s = 0x%.6X (%d, %d, %d)", iv->name, + "%s = 0x%.6X (%d, %d, %d)", iv->get_name(), i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF ); } else { - writefln("%s = 0x%X", iv->name, i); + writefln("%s = 0x%X", iv->get_name(), i); } } else { - writefln("%s = %d", iv->name, i); + writefln("%s = %d", iv->get_name(), i); } } void CsState::print_var_float(Fvar *fv, CsFloat f) { - writefln("%s = %s", fv->name, floatstr(f)); + writefln("%s = %s", fv->get_name(), floatstr(f)); } void CsState::print_var_str(Svar *sv, ostd::ConstCharRange s) { if (ostd::find(s, '"').empty()) { - writefln("%s = \"%s\"", sv->name, s); + writefln("%s = \"%s\"", sv->get_name(), s); } else { - writefln("%s = [%s]", sv->name, s); + writefln("%s = [%s]", sv->get_name(), s); } } @@ -695,7 +711,7 @@ void Alias::push_arg(TaggedValue const &v, IdentStack &st, bool um) { set_value(v); clean_code(); if (um) { - flags &= ~IDF_UNKNOWN; + p_flags &= ~IDF_UNKNOWN; } } @@ -728,13 +744,13 @@ void Alias::redo_arg(IdentStack const &st) { } void Alias::set_arg(CsState &cs, TaggedValue &v) { - if (cs.stack->usedargs & (1 << index)) { + if (cs.stack->usedargs & (1 << get_index())) { val_v.cleanup(); set_value(v); clean_code(); } else { - push_arg(v, cs.stack->argstack[index], false); - cs.stack->usedargs |= 1 << index; + push_arg(v, cs.stack->argstack[get_index()], false); + cs.stack->usedargs |= 1 << get_index(); } } @@ -742,35 +758,49 @@ void Alias::set_alias(CsState &cs, TaggedValue &v) { val_v.cleanup(); set_value(v); clean_code(); - flags = (flags & cs.identflags) | cs.identflags; + p_flags = (p_flags & cs.identflags) | cs.identflags; } IdentType Ident::get_type() const { - if (type > ID_ALIAS) { - return IdentType::unknown; + if (p_type > ID_ALIAS) { + return IdentType::special; } - return IdentType(type); + return IdentType(p_type); +} + +ostd::ConstCharRange Ident::get_name() const { + return p_name; +} + +int Ident::get_flags() const { + return p_flags; +} + +int Ident::get_index() const { + return p_index; } template -bool cs_override_var(CsState &cs, Var *v, SF sf, RF rf, CF cf) { - if ((cs.identflags & IDF_OVERRIDDEN) || (v->flags & IDF_OVERRIDE)) { - if (v->flags & IDF_PERSIST) { +static inline bool cs_override_var( + CsState &cs, Var *v, int &vflags, SF sf, RF rf, CF cf +) { + if ((cs.identflags & IDF_OVERRIDDEN) || (vflags & IDF_OVERRIDE)) { + if (vflags & IDF_PERSIST) { cs_debug_code( - cs, "cannot override persistent variable '%s'", v->name + cs, "cannot override persistent variable '%s'", v->get_name() ); return false; } - if (!(v->flags & IDF_OVERRIDDEN)) { + if (!(vflags & IDF_OVERRIDDEN)) { sf(); - v->flags |= IDF_OVERRIDDEN; + vflags |= IDF_OVERRIDDEN; } else { cf(); } } else { - if (v->flags & IDF_OVERRIDDEN) { + if (vflags & IDF_OVERRIDDEN) { rf(); - v->flags &= ~IDF_OVERRIDDEN; + vflags &= ~IDF_OVERRIDDEN; } cf(); } @@ -786,7 +816,7 @@ void CsState::set_var_int( } Ivar *iv = static_cast(id); bool success = cs_override_var( - *this, iv, + *this, iv, iv->p_flags, [&iv]() { iv->overrideval = *iv->storage; }, []() {}, []() {} ); @@ -812,7 +842,7 @@ void CsState::set_var_float( } Fvar *fv = static_cast(id); bool success = cs_override_var( - *this, fv, + *this, fv, fv->p_flags, [&fv]() { fv->overrideval = *fv->storage; }, []() {}, []() {} ); @@ -838,7 +868,7 @@ void CsState::set_var_str( } Svar *sv = static_cast(id); bool success = cs_override_var( - *this, sv, + *this, sv, sv->p_flags, [&sv]() { sv->overrideval = *sv->storage; }, [&sv]() { delete[] sv->overrideval; }, [&sv]() { delete[] *sv->storage; } @@ -914,7 +944,10 @@ CsState::get_alias_val(ostd::ConstCharRange name) { if (!a) { return ostd::nothing; } - if ((a->index < MaxArguments) && !(stack->usedargs & (1 << a->index))) { + if ( + (a->get_index() < MaxArguments) && + !(stack->usedargs & (1 << a->get_index())) + ) { return ostd::nothing; } return ostd::move(a->val_v.get_str()); @@ -930,25 +963,25 @@ CsInt cs_clamp_var(CsState &cs, Ivar *iv, CsInt v) { } cs_debug_code( cs, - (iv->flags & IDF_HEX) + (iv->get_flags() & IDF_HEX) ? ( (iv->minval <= 255) ? "valid range for '%s' is %d..0x%X" : "valid range for '%s' is 0x%X..0x%X" ) : "valid range for '%s' is %d..%d", - iv->name, iv->minval, iv->maxval + iv->get_name(), iv->minval, iv->maxval ); return v; } void CsState::set_var_int_checked(Ivar *iv, CsInt v) { - if (iv->flags & IDF_READONLY) { - cs_debug_code(*this, "variable '%s' is read only", iv->name); + if (iv->get_flags() & IDF_READONLY) { + cs_debug_code(*this, "variable '%s' is read only", iv->get_name()); return; } bool success = cs_override_var( - *this, iv, + *this, iv, iv->p_flags, [&iv]() { iv->overrideval = *iv->storage; }, []() {}, []() {} ); @@ -964,7 +997,7 @@ void CsState::set_var_int_checked(Ivar *iv, CsInt v) { void CsState::set_var_int_checked(Ivar *iv, TvalRange args) { CsInt v = args[0].force_int(); - if ((iv->flags & IDF_HEX) && (args.size() > 1)) { + if ((iv->get_flags() & IDF_HEX) && (args.size() > 1)) { v = (v << 16) | (args[1].force_int() << 8); if (args.size() > 2) { v |= args[2].force_int(); @@ -989,12 +1022,12 @@ CsFloat cs_clamp_fvar(CsState &cs, Fvar *fv, CsFloat v) { } void CsState::set_var_float_checked(Fvar *fv, CsFloat v) { - if (fv->flags & IDF_READONLY) { - cs_debug_code(*this, "variable '%s' is read only", fv->name); + if (fv->get_flags() & IDF_READONLY) { + cs_debug_code(*this, "variable '%s' is read only", fv->get_name()); return; } bool success = cs_override_var( - *this, fv, + *this, fv, fv->p_flags, [&fv]() { fv->overrideval = *fv->storage; }, []() {}, []() {} ); @@ -1009,12 +1042,12 @@ void CsState::set_var_float_checked(Fvar *fv, CsFloat v) { } void CsState::set_var_str_checked(Svar *sv, ostd::ConstCharRange v) { - if (sv->flags & IDF_READONLY) { - cs_debug_code(*this, "variable '%s' is read only", sv->name); + if (sv->get_flags() & IDF_READONLY) { + cs_debug_code(*this, "variable '%s' is read only", sv->get_name()); return; } bool success = cs_override_var( - *this, sv, + *this, sv, sv->p_flags, [&sv]() { sv->overrideval = *sv->storage; }, [&sv]() { delete[] sv->overrideval; }, [&sv]() { delete[] *sv->storage; } @@ -1283,7 +1316,7 @@ void cs_init_lib_base(CsState &cs) { Ident *id = args[0].get_ident(); TaggedValue &v = args[1]; Bytecode *code = args[2].get_code(); - if (!id->is_alias() || (id->index < MaxArguments)) { + if (!id->is_alias() || (id->get_index() < MaxArguments)) { return; } Alias *a = static_cast(id); @@ -1423,7 +1456,7 @@ void cs_init_lib_base(CsState &cs) { cs_add_command(cs, "push", "rTe", [&cs](TvalRange args, TaggedValue &res) { Ident *id = args[0].get_ident(); - if (!id->is_alias() || (id->index < MaxArguments)) { + if (!id->is_alias() || (id->get_index() < MaxArguments)) { return; } Alias *a = static_cast(id); diff --git a/cubescript.hh b/cubescript.hh index 95e24ab..b24408a 100644 --- a/cubescript.hh +++ b/cubescript.hh @@ -168,8 +168,7 @@ struct IdentStack { struct CsState; enum class IdentType { - unknown = -1, - ivar, fvar, svar, command, alias + ivar = 0, fvar, svar, command, alias, special }; struct Var; @@ -179,18 +178,19 @@ struct Svar; struct Alias; struct OSTD_EXPORT Ident { - int type; /* ID_something */ - ostd::ushort flags; - int index = -1; - ostd::String name; + friend struct CsState; IdentType get_type() const; + ostd::ConstCharRange get_name() const; + int get_flags() const; + int get_index() const; bool is_alias() const; Alias *get_alias(); Alias const *get_alias() const; bool is_command() const; + bool is_special() const; bool is_var() const; Var *get_var(); @@ -208,8 +208,21 @@ struct OSTD_EXPORT Ident { Svar *get_svar(); Svar const *get_svar() const; + int get_type_raw() const { + return p_type; + } + protected: Ident(IdentType tp, ostd::ConstCharRange name, int flags = 0); + + ostd::String p_name; + /* represents the IdentType above, but internally it has a wider variety + * of values, so it's an int here (maps to an internal enum) + */ + int p_type, p_flags; + +private: + int p_index = -1; }; using VarCb = ostd::Function; @@ -327,15 +340,7 @@ struct OSTD_EXPORT CsState { void clear_override(Ident &id); void clear_overrides(); - Ident *add_ident(Ident *id) { - if (!id) { - return nullptr; - } - idents[id->name] = id; - id->index = identmap.size(); - return identmap.push(id); - } - + Ident *add_ident(Ident *id); Ident *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN); Ident *force_ident(TaggedValue &v);