forked from OctaForge/libcubescript
clean up Ident interface
parent
f0f5fbc1ba
commit
f3b3751f76
126
cs_gen.cc
126
cs_gen.cc
|
@ -422,11 +422,11 @@ static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) {
|
||||||
lookupid:
|
lookupid:
|
||||||
Ident *id = gs.cs.new_ident(lookup.get());
|
Ident *id = gs.cs.new_ident(lookup.get());
|
||||||
if (id) {
|
if (id) {
|
||||||
switch (id->type) {
|
switch (id->get_type()) {
|
||||||
case ID_IVAR:
|
case IdentType::ivar:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
CODE_IVAR | cs_ret_code(ltype, RET_INT) |
|
CODE_IVAR | cs_ret_code(ltype, RET_INT) |
|
||||||
(id->index << 8)
|
(id->get_index() << 8)
|
||||||
);
|
);
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
|
@ -440,10 +440,10 @@ lookupid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case ID_FVAR:
|
case IdentType::fvar:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
CODE_FVAR | cs_ret_code(ltype, RET_FLOAT) |
|
CODE_FVAR | cs_ret_code(ltype, RET_FLOAT) |
|
||||||
(id->index << 8)
|
(id->get_index() << 8)
|
||||||
);
|
);
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
|
@ -457,7 +457,7 @@ lookupid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case ID_SVAR:
|
case IdentType::svar:
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
return;
|
return;
|
||||||
|
@ -466,51 +466,53 @@ lookupid:
|
||||||
case VAL_CODE:
|
case VAL_CODE:
|
||||||
case VAL_IDENT:
|
case VAL_IDENT:
|
||||||
case VAL_COND:
|
case VAL_COND:
|
||||||
gs.code.push(CODE_SVARM | (id->index << 8));
|
gs.code.push(
|
||||||
|
CODE_SVARM | (id->get_index() << 8)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
CODE_SVAR | cs_ret_code(ltype, RET_STR) |
|
CODE_SVAR | cs_ret_code(ltype, RET_STR) |
|
||||||
(id->index << 8)
|
(id->get_index() << 8)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
case ID_ALIAS:
|
case IdentType::alias:
|
||||||
switch (ltype) {
|
switch (ltype) {
|
||||||
case VAL_POP:
|
case VAL_POP:
|
||||||
return;
|
return;
|
||||||
case VAL_CANY:
|
case VAL_CANY:
|
||||||
case VAL_COND:
|
case VAL_COND:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->index < MaxArguments
|
(id->get_index() < MaxArguments
|
||||||
? CODE_LOOKUPMARG
|
? CODE_LOOKUPMARG
|
||||||
: CODE_LOOKUPM
|
: CODE_LOOKUPM
|
||||||
) | (id->index << 8)
|
) | (id->get_index() << 8)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case VAL_CSTR:
|
case VAL_CSTR:
|
||||||
case VAL_CODE:
|
case VAL_CODE:
|
||||||
case VAL_IDENT:
|
case VAL_IDENT:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->index < MaxArguments
|
(id->get_index() < MaxArguments
|
||||||
? CODE_LOOKUPMARG
|
? CODE_LOOKUPMARG
|
||||||
: CODE_LOOKUPM
|
: CODE_LOOKUPM
|
||||||
) | RET_STR | (id->index << 8)
|
) | RET_STR | (id->get_index() << 8)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->index < MaxArguments
|
(id->get_index() < MaxArguments
|
||||||
? CODE_LOOKUPARG
|
? CODE_LOOKUPARG
|
||||||
: CODE_LOOKUP
|
: CODE_LOOKUP
|
||||||
) | cs_ret_code(ltype, RET_STR) |
|
) | cs_ret_code(ltype, RET_STR) |
|
||||||
(id->index << 8)
|
(id->get_index() << 8)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
case ID_COMMAND: {
|
case IdentType::command: {
|
||||||
int comtype = CODE_COM, numargs = 0;
|
int comtype = CODE_COM, numargs = 0;
|
||||||
if (prevargs >= MaxResults) {
|
if (prevargs >= MaxResults) {
|
||||||
gs.code.push(CODE_ENTER);
|
gs.code.push(CODE_ENTER);
|
||||||
|
@ -578,7 +580,7 @@ lookupid:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
comtype | cs_ret_code(ltype) | (id->index << 8)
|
comtype | cs_ret_code(ltype) | (id->get_index() << 8)
|
||||||
);
|
);
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(prevargs >= MaxResults
|
(prevargs >= MaxResults
|
||||||
|
@ -590,7 +592,7 @@ lookupid:
|
||||||
compilecomv:
|
compilecomv:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
comtype | cs_ret_code(ltype) | (numargs << 8) |
|
comtype | cs_ret_code(ltype) | (numargs << 8) |
|
||||||
(id->index << 13)
|
(id->get_index() << 13)
|
||||||
);
|
);
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(prevargs >= MaxResults
|
(prevargs >= MaxResults
|
||||||
|
@ -740,24 +742,26 @@ static bool compileblocksub(GenState &gs, int prevargs) {
|
||||||
lookupid:
|
lookupid:
|
||||||
Ident *id = gs.cs.new_ident(lookup.get());
|
Ident *id = gs.cs.new_ident(lookup.get());
|
||||||
if (id) {
|
if (id) {
|
||||||
switch (id->type) {
|
switch (id->get_type()) {
|
||||||
case ID_IVAR:
|
case IdentType::ivar:
|
||||||
gs.code.push(CODE_IVAR | (id->index << 8));
|
gs.code.push(CODE_IVAR | (id->get_index() << 8));
|
||||||
goto done;
|
goto done;
|
||||||
case ID_FVAR:
|
case IdentType::fvar:
|
||||||
gs.code.push(CODE_FVAR | (id->index << 8));
|
gs.code.push(CODE_FVAR | (id->get_index() << 8));
|
||||||
goto done;
|
goto done;
|
||||||
case ID_SVAR:
|
case IdentType::svar:
|
||||||
gs.code.push(CODE_SVARM | (id->index << 8));
|
gs.code.push(CODE_SVARM | (id->get_index() << 8));
|
||||||
goto done;
|
goto done;
|
||||||
case ID_ALIAS:
|
case IdentType::alias:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->index < MaxArguments
|
(id->get_index() < MaxArguments
|
||||||
? CODE_LOOKUPMARG
|
? CODE_LOOKUPMARG
|
||||||
: CODE_LOOKUPM
|
: CODE_LOOKUPM
|
||||||
) | (id->index << 8)
|
) | (id->get_index() << 8)
|
||||||
);
|
);
|
||||||
goto done;
|
goto done;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.gen_str(lookup.get(), true);
|
gs.gen_str(lookup.get(), true);
|
||||||
|
@ -1091,39 +1095,48 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
||||||
if (idname) {
|
if (idname) {
|
||||||
Ident *id = gs.cs.new_ident(idname.get());
|
Ident *id = gs.cs.new_ident(idname.get());
|
||||||
if (id) {
|
if (id) {
|
||||||
switch (id->type) {
|
switch (id->get_type()) {
|
||||||
case ID_ALIAS:
|
case IdentType::alias:
|
||||||
more = compilearg(gs, VAL_ANY, prevargs);
|
more = compilearg(gs, VAL_ANY, prevargs);
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gen_str();
|
gs.gen_str();
|
||||||
}
|
}
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->index < MaxArguments
|
(id->get_index() < MaxArguments
|
||||||
? CODE_ALIASARG
|
? CODE_ALIASARG
|
||||||
: CODE_ALIAS) | (id->index << 8)
|
: CODE_ALIAS
|
||||||
|
) | (id->get_index() << 8)
|
||||||
);
|
);
|
||||||
goto endstatement;
|
goto endstatement;
|
||||||
case ID_IVAR:
|
case IdentType::ivar:
|
||||||
more = compilearg(gs, VAL_INT, prevargs);
|
more = compilearg(gs, VAL_INT, prevargs);
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gen_int();
|
gs.gen_int();
|
||||||
}
|
}
|
||||||
gs.code.push(CODE_IVAR1 | (id->index << 8));
|
gs.code.push(
|
||||||
|
CODE_IVAR1 | (id->get_index() << 8)
|
||||||
|
);
|
||||||
goto endstatement;
|
goto endstatement;
|
||||||
case ID_FVAR:
|
case IdentType::fvar:
|
||||||
more = compilearg(gs, VAL_FLOAT, prevargs);
|
more = compilearg(gs, VAL_FLOAT, prevargs);
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gen_float();
|
gs.gen_float();
|
||||||
}
|
}
|
||||||
gs.code.push(CODE_FVAR1 | (id->index << 8));
|
gs.code.push(
|
||||||
|
CODE_FVAR1 | (id->get_index() << 8)
|
||||||
|
);
|
||||||
goto endstatement;
|
goto endstatement;
|
||||||
case ID_SVAR:
|
case IdentType::svar:
|
||||||
more = compilearg(gs, VAL_CSTR, prevargs);
|
more = compilearg(gs, VAL_CSTR, prevargs);
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.gen_str();
|
gs.gen_str();
|
||||||
}
|
}
|
||||||
gs.code.push(CODE_SVAR1 | (id->index << 8));
|
gs.code.push(
|
||||||
|
CODE_SVAR1 | (id->get_index() << 8)
|
||||||
|
);
|
||||||
goto endstatement;
|
goto endstatement;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.gen_str(idname.get(), true);
|
gs.gen_str(idname.get(), true);
|
||||||
|
@ -1172,7 +1185,7 @@ noid:
|
||||||
}
|
}
|
||||||
gs.code.push(CODE_RESULT);
|
gs.code.push(CODE_RESULT);
|
||||||
} else {
|
} else {
|
||||||
switch (id->type) {
|
switch (id->get_type_raw()) {
|
||||||
case ID_ALIAS:
|
case ID_ALIAS:
|
||||||
while (numargs < MaxArguments) {
|
while (numargs < MaxArguments) {
|
||||||
more = compilearg(gs, VAL_ANY, prevargs + numargs);
|
more = compilearg(gs, VAL_ANY, prevargs + numargs);
|
||||||
|
@ -1182,10 +1195,10 @@ noid:
|
||||||
++numargs;
|
++numargs;
|
||||||
}
|
}
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->index < MaxArguments
|
(id->get_index() < MaxArguments
|
||||||
? CODE_CALLARG
|
? CODE_CALLARG
|
||||||
: CODE_CALL
|
: CODE_CALL
|
||||||
) | (numargs << 8) | (id->index << 13)
|
) | (numargs << 8) | (id->get_index() << 13)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case ID_COMMAND: {
|
case ID_COMMAND: {
|
||||||
|
@ -1406,13 +1419,14 @@ noid:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
comtype | cs_ret_code(rettype) | (id->index << 8)
|
comtype | cs_ret_code(rettype) |
|
||||||
|
(id->get_index() << 8)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
compilecomv:
|
compilecomv:
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
comtype | cs_ret_code(rettype) | (numargs << 8) |
|
comtype | cs_ret_code(rettype) | (numargs << 8) |
|
||||||
(id->index << 13)
|
(id->get_index() << 13)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1512,7 +1526,7 @@ compilecomv:
|
||||||
}
|
}
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
CODE_COM | cs_ret_code(rettype) |
|
CODE_COM | cs_ret_code(rettype) |
|
||||||
(id->index << 8)
|
(id->get_index() << 8)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1541,7 +1555,7 @@ compilecomv:
|
||||||
}
|
}
|
||||||
if (!more) {
|
if (!more) {
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
(id->type == ID_AND
|
((id->get_type_raw() == ID_AND)
|
||||||
? CODE_TRUE
|
? CODE_TRUE
|
||||||
: CODE_FALSE
|
: CODE_FALSE
|
||||||
) | cs_ret_code(rettype)
|
) | cs_ret_code(rettype)
|
||||||
|
@ -1580,10 +1594,10 @@ compilecomv:
|
||||||
}
|
}
|
||||||
gs.code.push(
|
gs.code.push(
|
||||||
CODE_COMV | cs_ret_code(rettype) |
|
CODE_COMV | cs_ret_code(rettype) |
|
||||||
(numargs << 8) | (id->index << 13)
|
(numargs << 8) | (id->get_index() << 13)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ostd::Uint32 op = id->type == ID_AND
|
ostd::Uint32 op = (id->get_type_raw() == ID_AND)
|
||||||
? CODE_JUMP_RESULT_FALSE
|
? CODE_JUMP_RESULT_FALSE
|
||||||
: CODE_JUMP_RESULT_TRUE;
|
: CODE_JUMP_RESULT_TRUE;
|
||||||
gs.code.push(op);
|
gs.code.push(op);
|
||||||
|
@ -1604,29 +1618,29 @@ compilecomv:
|
||||||
break;
|
break;
|
||||||
case ID_IVAR:
|
case ID_IVAR:
|
||||||
if (!(more = compilearg(gs, VAL_INT, prevargs))) {
|
if (!(more = compilearg(gs, VAL_INT, prevargs))) {
|
||||||
gs.code.push(CODE_PRINT | (id->index << 8));
|
gs.code.push(CODE_PRINT | (id->get_index() << 8));
|
||||||
} else if (!(id->flags & IDF_HEX) || !(
|
} else if (!(id->get_flags() & IDF_HEX) || !(
|
||||||
more = compilearg(gs, VAL_INT, prevargs + 1)
|
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 (!(
|
} else if (!(
|
||||||
more = compilearg(gs, VAL_INT, prevargs + 2)
|
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 {
|
} else {
|
||||||
gs.code.push(CODE_IVAR3 | (id->index << 8));
|
gs.code.push(CODE_IVAR3 | (id->get_index() << 8));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_FVAR:
|
case ID_FVAR:
|
||||||
if (!(more = compilearg(gs, VAL_FLOAT, prevargs))) {
|
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 {
|
} else {
|
||||||
gs.code.push(CODE_FVAR1 | (id->index << 8));
|
gs.code.push(CODE_FVAR1 | (id->get_index() << 8));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_SVAR:
|
case ID_SVAR:
|
||||||
if (!(more = compilearg(gs, VAL_CSTR, prevargs))) {
|
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 {
|
} else {
|
||||||
do {
|
do {
|
||||||
++numargs;
|
++numargs;
|
||||||
|
@ -1638,7 +1652,7 @@ compilecomv:
|
||||||
if (numargs > 1) {
|
if (numargs > 1) {
|
||||||
gs.code.push(CODE_CONC | RET_STR | (numargs << 8));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
82
cs_vm.cc
82
cs_vm.cc
|
@ -7,7 +7,7 @@
|
||||||
namespace cscript {
|
namespace cscript {
|
||||||
|
|
||||||
static inline bool cs_has_cmd_cb(Ident *id) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
Command *cb = static_cast<Command *>(id);
|
Command *cb = static_cast<Command *>(id);
|
||||||
|
@ -15,13 +15,13 @@ static inline bool cs_has_cmd_cb(Ident *id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cs_push_alias(Ident *id, IdentStack &st) {
|
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<Alias *>(id)->push_arg(null_value, st);
|
static_cast<Alias *>(id)->push_arg(null_value, st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cs_pop_alias(Ident *id) {
|
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<Alias *>(id)->pop_arg();
|
static_cast<Alias *>(id)->pop_arg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,11 +72,11 @@ void cs_debug_alias(CsState &cs) {
|
||||||
Ident *id = l->id;
|
Ident *id = l->id;
|
||||||
++depth;
|
++depth;
|
||||||
if (depth < cs.dbgalias) {
|
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) {
|
} else if (l->next == &cs.noalias) {
|
||||||
ostd::err.writefln(
|
ostd::err.writefln(
|
||||||
depth == cs.dbgalias ? " %d) %s" : " ..%d) %s",
|
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;
|
int oldargs = cs.numargs;
|
||||||
cs.numargs = callargs;
|
cs.numargs = callargs;
|
||||||
int oldflags = cs.identflags;
|
int oldflags = cs.identflags;
|
||||||
cs.identflags |= a->flags&IDF_OVERRIDDEN;
|
cs.identflags |= a->get_flags()&IDF_OVERRIDDEN;
|
||||||
IdentLink aliaslink = {
|
IdentLink aliaslink = {
|
||||||
a, cs.stack, (1<<callargs)-1, argstack
|
a, cs.stack, (1<<callargs)-1, argstack
|
||||||
};
|
};
|
||||||
|
@ -494,15 +494,15 @@ static thread_local int rundepth = 0;
|
||||||
|
|
||||||
static inline Alias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) {
|
static inline Alias *cs_get_lookup_id(CsState &cs, ostd::Uint32 op) {
|
||||||
Ident *id = cs.identmap[op >> 8];
|
Ident *id = cs.identmap[op >> 8];
|
||||||
if (id->flags & IDF_UNKNOWN) {
|
if (id->get_flags() & IDF_UNKNOWN) {
|
||||||
cs_debug_code(cs, "unknown alias lookup: %s", id->name);
|
cs_debug_code(cs, "unknown alias lookup: %s", id->get_name());
|
||||||
}
|
}
|
||||||
return static_cast<Alias *>(id);
|
return static_cast<Alias *>(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Alias *cs_get_lookuparg_id(CsState &cs, ostd::Uint32 op) {
|
static inline Alias *cs_get_lookuparg_id(CsState &cs, ostd::Uint32 op) {
|
||||||
Ident *id = cs.identmap[op >> 8];
|
Ident *id = cs.identmap[op >> 8];
|
||||||
if (!(cs.stack->usedargs&(1<<id->index))) {
|
if (!(cs.stack->usedargs & (1 << id->get_index()))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return static_cast<Alias *>(id);
|
return static_cast<Alias *>(id);
|
||||||
|
@ -520,29 +520,29 @@ static inline int cs_get_lookupu_type(
|
||||||
}
|
}
|
||||||
id = cs.get_ident(arg.s);
|
id = cs.get_ident(arg.s);
|
||||||
if (id) {
|
if (id) {
|
||||||
switch(id->type) {
|
switch(id->get_type()) {
|
||||||
case ID_ALIAS:
|
case IdentType::alias:
|
||||||
if (id->flags & IDF_UNKNOWN) {
|
if (id->get_flags() & IDF_UNKNOWN) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
arg.cleanup();
|
arg.cleanup();
|
||||||
if (
|
if (
|
||||||
(id->index < MaxArguments) &&
|
(id->get_index() < MaxArguments) &&
|
||||||
!(cs.stack->usedargs & (1 << id->index))
|
!(cs.stack->usedargs & (1 << id->get_index()))
|
||||||
) {
|
) {
|
||||||
return ID_UNKNOWN;
|
return ID_UNKNOWN;
|
||||||
}
|
}
|
||||||
return ID_ALIAS;
|
return ID_ALIAS;
|
||||||
case ID_SVAR:
|
case IdentType::svar:
|
||||||
arg.cleanup();
|
arg.cleanup();
|
||||||
return ID_SVAR;
|
return ID_SVAR;
|
||||||
case ID_IVAR:
|
case IdentType::ivar:
|
||||||
arg.cleanup();
|
arg.cleanup();
|
||||||
return ID_IVAR;
|
return ID_IVAR;
|
||||||
case ID_FVAR:
|
case IdentType::fvar:
|
||||||
arg.cleanup();
|
arg.cleanup();
|
||||||
return ID_FVAR;
|
return ID_FVAR;
|
||||||
case ID_COMMAND: {
|
case IdentType::command: {
|
||||||
arg.cleanup();
|
arg.cleanup();
|
||||||
arg.set_null();
|
arg.set_null();
|
||||||
TaggedValue buf[MaxArguments];
|
TaggedValue buf[MaxArguments];
|
||||||
|
@ -940,9 +940,11 @@ static ostd::Uint32 const *runcode(
|
||||||
continue;
|
continue;
|
||||||
case CODE_IDENTARG: {
|
case CODE_IDENTARG: {
|
||||||
Alias *a = static_cast<Alias *>(cs.identmap[op >> 8]);
|
Alias *a = static_cast<Alias *>(cs.identmap[op >> 8]);
|
||||||
if (!(cs.stack->usedargs & (1 << a->index))) {
|
if (!(cs.stack->usedargs & (1 << a->get_index()))) {
|
||||||
a->push_arg(null_value, cs.stack->argstack[a->index], false);
|
a->push_arg(
|
||||||
cs.stack->usedargs |= 1 << a->index;
|
null_value, cs.stack->argstack[a->get_index()], false
|
||||||
|
);
|
||||||
|
cs.stack->usedargs |= 1 << a->get_index();
|
||||||
}
|
}
|
||||||
args[numargs++].set_ident(a);
|
args[numargs++].set_ident(a);
|
||||||
continue;
|
continue;
|
||||||
|
@ -957,11 +959,14 @@ static ostd::Uint32 const *runcode(
|
||||||
) {
|
) {
|
||||||
id = cs.new_ident(ostd::ConstCharRange(arg.cstr, arg.len));
|
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<Alias *>(id)->push_arg(
|
static_cast<Alias *>(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.cleanup();
|
||||||
arg.set_ident(id);
|
arg.set_ident(id);
|
||||||
|
@ -1397,8 +1402,8 @@ static ostd::Uint32 const *runcode(
|
||||||
result.force_null();
|
result.force_null();
|
||||||
Ident *id = cs.identmap[op >> 13];
|
Ident *id = cs.identmap[op >> 13];
|
||||||
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
||||||
if (id->flags & IDF_UNKNOWN) {
|
if (id->get_flags() & IDF_UNKNOWN) {
|
||||||
cs_debug_code(cs, "unknown command: %s", id->name);
|
cs_debug_code(cs, "unknown command: %s", id->get_name());
|
||||||
free_args(args, numargs, offset);
|
free_args(args, numargs, offset);
|
||||||
force_arg(result, op & CODE_RET_MASK);
|
force_arg(result, op & CODE_RET_MASK);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1416,7 +1421,7 @@ static ostd::Uint32 const *runcode(
|
||||||
result.force_null();
|
result.force_null();
|
||||||
Ident *id = cs.identmap[op >> 13];
|
Ident *id = cs.identmap[op >> 13];
|
||||||
int callargs = (op >> 8) & 0x1F, offset = numargs - callargs;
|
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);
|
free_args(args, numargs, offset);
|
||||||
force_arg(result, op & CODE_RET_MASK);
|
force_arg(result, op & CODE_RET_MASK);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1461,7 +1466,7 @@ noid:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result.force_null();
|
result.force_null();
|
||||||
switch (id->type) {
|
switch (id->get_type_raw()) {
|
||||||
default:
|
default:
|
||||||
if (!cs_has_cmd_cb(id)) {
|
if (!cs_has_cmd_cb(id)) {
|
||||||
free_args(args, numargs, offset - 1);
|
free_args(args, numargs, offset - 1);
|
||||||
|
@ -1531,8 +1536,8 @@ noid:
|
||||||
case ID_ALIAS: {
|
case ID_ALIAS: {
|
||||||
Alias *a = static_cast<Alias *>(id);
|
Alias *a = static_cast<Alias *>(id);
|
||||||
if (
|
if (
|
||||||
a->index < MaxArguments &&
|
a->get_index() < MaxArguments &&
|
||||||
!(cs.stack->usedargs & (1 << a->index))
|
!(cs.stack->usedargs & (1 << a->get_index()))
|
||||||
) {
|
) {
|
||||||
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);
|
||||||
|
@ -1572,7 +1577,6 @@ void CsState::run_ret(ostd::ConstCharRange code, TaggedValue &ret) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO */
|
|
||||||
void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
||||||
int nargs = int(args.size());
|
int nargs = int(args.size());
|
||||||
ret.set_null();
|
ret.set_null();
|
||||||
|
@ -1580,13 +1584,13 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
||||||
if (rundepth > MaxRunDepth) {
|
if (rundepth > MaxRunDepth) {
|
||||||
cs_debug_code(*this, "exceeded recursion limit");
|
cs_debug_code(*this, "exceeded recursion limit");
|
||||||
} else if (id) {
|
} else if (id) {
|
||||||
switch (id->type) {
|
switch (id->get_type()) {
|
||||||
default:
|
default:
|
||||||
if (!cs_has_cmd_cb(id)) {
|
if (!cs_has_cmd_cb(id)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case ID_COMMAND:
|
case IdentType::command:
|
||||||
if (nargs < static_cast<Command *>(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));
|
||||||
|
@ -1602,14 +1606,14 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
||||||
}
|
}
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
break;
|
break;
|
||||||
case ID_IVAR:
|
case IdentType::ivar:
|
||||||
if (args.empty()) {
|
if (args.empty()) {
|
||||||
print_var(static_cast<Ivar *>(id));
|
print_var(static_cast<Ivar *>(id));
|
||||||
} else {
|
} else {
|
||||||
set_var_int_checked(static_cast<Ivar *>(id), args);
|
set_var_int_checked(static_cast<Ivar *>(id), args);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_FVAR:
|
case IdentType::fvar:
|
||||||
if (args.empty()) {
|
if (args.empty()) {
|
||||||
print_var(static_cast<Fvar *>(id));
|
print_var(static_cast<Fvar *>(id));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1618,7 +1622,7 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_SVAR:
|
case IdentType::svar:
|
||||||
if (args.empty()) {
|
if (args.empty()) {
|
||||||
print_var(static_cast<Svar *>(id));
|
print_var(static_cast<Svar *>(id));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1627,10 +1631,10 @@ void CsState::run_ret(Ident *id, TvalRange args, TaggedValue &ret) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_ALIAS: {
|
case IdentType::alias: {
|
||||||
Alias *a = static_cast<Alias *>(id);
|
Alias *a = static_cast<Alias *>(id);
|
||||||
if (a->index < MaxArguments) {
|
if (a->get_index() < MaxArguments) {
|
||||||
if (!(stack->usedargs & (1 << a->index))) {
|
if (!(stack->usedargs & (1 << a->get_index()))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
cs_vm.hh
4
cs_vm.hh
|
@ -205,10 +205,10 @@ struct GenState {
|
||||||
|
|
||||||
void gen_ident(Ident *id) {
|
void gen_ident(Ident *id) {
|
||||||
code.push(
|
code.push(
|
||||||
((id->index < MaxArguments)
|
((id->get_index() < MaxArguments)
|
||||||
? CODE_IDENTARG
|
? CODE_IDENTARG
|
||||||
: CODE_IDENT
|
: CODE_IDENT
|
||||||
) | (id->index << 8)
|
) | (id->get_index() << 8)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
161
cubescript.cc
161
cubescript.cc
|
@ -39,7 +39,7 @@ bool cs_check_num(ostd::ConstCharRange s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ident::Ident(IdentType tp, ostd::ConstCharRange nm, int fl):
|
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):
|
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,
|
int tp, ostd::ConstCharRange name, ostd::ConstCharRange args,
|
||||||
ostd::Uint32 amask, int nargs, CmdFunc f
|
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),
|
cargs(!args.empty() ? cs_dup_ostr(args) : nullptr),
|
||||||
argmask(amask), numargs(nargs), cb_cftv(ostd::move(f))
|
argmask(amask), numargs(nargs), cb_cftv(ostd::move(f))
|
||||||
{
|
{
|
||||||
type = tp;
|
p_type = tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Ident::is_alias() const {
|
bool Ident::is_alias() const {
|
||||||
|
@ -127,6 +127,10 @@ bool Ident::is_command() const {
|
||||||
return get_type() == IdentType::command;
|
return get_type() == IdentType::command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Ident::is_special() const {
|
||||||
|
return get_type() == IdentType::special;
|
||||||
|
}
|
||||||
|
|
||||||
bool Ident::is_var() const {
|
bool Ident::is_var() const {
|
||||||
IdentType tp = get_type();
|
IdentType tp = get_type();
|
||||||
return (tp >= IdentType::ivar) && (tp <= IdentType::svar);
|
return (tp >= IdentType::ivar) && (tp <= IdentType::svar);
|
||||||
|
@ -221,11 +225,11 @@ CsState::CsState() {
|
||||||
CsState::~CsState() {
|
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) {
|
Alias *a = i->get_alias();
|
||||||
Alias *a = static_cast<Alias *>(i);
|
if (a) {
|
||||||
a->force_null();
|
a->force_null();
|
||||||
delete[] reinterpret_cast<ostd::Uint32 *>(a->code);
|
delete[] reinterpret_cast<ostd::Uint32 *>(a->code);
|
||||||
} else if (i->type == ID_COMMAND || i->type >= ID_LOCAL) {
|
} else if (i->is_command() || i->is_special()) {
|
||||||
delete[] static_cast<Command *>(i)->cargs;
|
delete[] static_cast<Command *>(i)->cargs;
|
||||||
}
|
}
|
||||||
delete i;
|
delete i;
|
||||||
|
@ -233,38 +237,40 @@ CsState::~CsState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsState::clear_override(Ident &id) {
|
void CsState::clear_override(Ident &id) {
|
||||||
if (!(id.flags & IDF_OVERRIDDEN)) {
|
if (!(id.get_flags() & IDF_OVERRIDDEN)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (id.type) {
|
switch (id.get_type()) {
|
||||||
case ID_ALIAS: {
|
case IdentType::alias: {
|
||||||
Alias &a = static_cast<Alias &>(id);
|
Alias &a = static_cast<Alias &>(id);
|
||||||
a.val_v.cleanup();
|
a.val_v.cleanup();
|
||||||
a.clean_code();
|
a.clean_code();
|
||||||
a.val_v.set_str("");
|
a.val_v.set_str("");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_IVAR: {
|
case IdentType::ivar: {
|
||||||
Ivar &iv = static_cast<Ivar &>(id);
|
Ivar &iv = static_cast<Ivar &>(id);
|
||||||
*iv.storage = iv.overrideval;
|
*iv.storage = iv.overrideval;
|
||||||
iv.changed();
|
iv.changed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_FVAR: {
|
case IdentType::fvar: {
|
||||||
Fvar &fv = static_cast<Fvar &>(id);
|
Fvar &fv = static_cast<Fvar &>(id);
|
||||||
*fv.storage = fv.overrideval;
|
*fv.storage = fv.overrideval;
|
||||||
fv.changed();
|
fv.changed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ID_SVAR: {
|
case IdentType::svar: {
|
||||||
Svar &sv = static_cast<Svar &>(id);
|
Svar &sv = static_cast<Svar &>(id);
|
||||||
delete[] *sv.storage;
|
delete[] *sv.storage;
|
||||||
*sv.storage = sv.overrideval;
|
*sv.storage = sv.overrideval;
|
||||||
sv.changed();
|
sv.changed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
id.flags &= ~IDF_OVERRIDDEN;
|
id.p_flags &= ~IDF_OVERRIDDEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsState::clear_overrides() {
|
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 *CsState::new_ident(ostd::ConstCharRange name, int flags) {
|
||||||
Ident *id = get_ident(name);
|
Ident *id = get_ident(name);
|
||||||
if (!id) {
|
if (!id) {
|
||||||
|
@ -314,8 +329,8 @@ bool CsState::reset_var(ostd::ConstCharRange name) {
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (id->flags & IDF_READONLY) {
|
if (id->get_flags() & IDF_READONLY) {
|
||||||
cs_debug_code(*this, "variable %s is read only", id->name);
|
cs_debug_code(*this, "variable %s is read only", id->get_name());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
clear_override(*id);
|
clear_override(*id);
|
||||||
|
@ -332,28 +347,29 @@ void CsState::touch_var(ostd::ConstCharRange name) {
|
||||||
void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
|
void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
|
||||||
Ident *id = get_ident(name);
|
Ident *id = get_ident(name);
|
||||||
if (id) {
|
if (id) {
|
||||||
switch (id->type) {
|
switch (id->get_type()) {
|
||||||
case ID_ALIAS: {
|
case IdentType::alias: {
|
||||||
Alias *a = static_cast<Alias *>(id);
|
Alias *a = static_cast<Alias *>(id);
|
||||||
if (a->index < MaxArguments) {
|
if (a->get_index() < MaxArguments) {
|
||||||
a->set_arg(*this, v);
|
a->set_arg(*this, v);
|
||||||
} else {
|
} else {
|
||||||
a->set_alias(*this, v);
|
a->set_alias(*this, v);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ID_IVAR:
|
case IdentType::ivar:
|
||||||
set_var_int_checked(static_cast<Ivar *>(id), v.get_int());
|
set_var_int_checked(static_cast<Ivar *>(id), v.get_int());
|
||||||
break;
|
break;
|
||||||
case ID_FVAR:
|
case IdentType::fvar:
|
||||||
set_var_float_checked(static_cast<Fvar *>(id), v.get_float());
|
set_var_float_checked(static_cast<Fvar *>(id), v.get_float());
|
||||||
break;
|
break;
|
||||||
case ID_SVAR:
|
case IdentType::svar:
|
||||||
set_var_str_checked(static_cast<Svar *>(id), v.get_str());
|
set_var_str_checked(static_cast<Svar *>(id), v.get_str());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cs_debug_code(
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -368,32 +384,32 @@ void CsState::set_alias(ostd::ConstCharRange name, TaggedValue &v) {
|
||||||
|
|
||||||
void CsState::print_var_int(Ivar *iv, CsInt i) {
|
void CsState::print_var_int(Ivar *iv, CsInt i) {
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
writefln("%s = %d", iv->name, i);
|
writefln("%s = %d", iv->get_name(), i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (iv->flags & IDF_HEX) {
|
if (iv->get_flags() & IDF_HEX) {
|
||||||
if (iv->maxval == 0xFFFFFF) {
|
if (iv->maxval == 0xFFFFFF) {
|
||||||
writefln(
|
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
|
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
writefln("%s = 0x%X", iv->name, i);
|
writefln("%s = 0x%X", iv->get_name(), i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
writefln("%s = %d", iv->name, i);
|
writefln("%s = %d", iv->get_name(), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsState::print_var_float(Fvar *fv, CsFloat f) {
|
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) {
|
void CsState::print_var_str(Svar *sv, ostd::ConstCharRange s) {
|
||||||
if (ostd::find(s, '"').empty()) {
|
if (ostd::find(s, '"').empty()) {
|
||||||
writefln("%s = \"%s\"", sv->name, s);
|
writefln("%s = \"%s\"", sv->get_name(), s);
|
||||||
} else {
|
} 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);
|
set_value(v);
|
||||||
clean_code();
|
clean_code();
|
||||||
if (um) {
|
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) {
|
void Alias::set_arg(CsState &cs, TaggedValue &v) {
|
||||||
if (cs.stack->usedargs & (1 << index)) {
|
if (cs.stack->usedargs & (1 << get_index())) {
|
||||||
val_v.cleanup();
|
val_v.cleanup();
|
||||||
set_value(v);
|
set_value(v);
|
||||||
clean_code();
|
clean_code();
|
||||||
} else {
|
} else {
|
||||||
push_arg(v, cs.stack->argstack[index], false);
|
push_arg(v, cs.stack->argstack[get_index()], false);
|
||||||
cs.stack->usedargs |= 1 << index;
|
cs.stack->usedargs |= 1 << get_index();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,35 +758,49 @@ void Alias::set_alias(CsState &cs, TaggedValue &v) {
|
||||||
val_v.cleanup();
|
val_v.cleanup();
|
||||||
set_value(v);
|
set_value(v);
|
||||||
clean_code();
|
clean_code();
|
||||||
flags = (flags & cs.identflags) | cs.identflags;
|
p_flags = (p_flags & cs.identflags) | cs.identflags;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentType Ident::get_type() const {
|
IdentType Ident::get_type() const {
|
||||||
if (type > ID_ALIAS) {
|
if (p_type > ID_ALIAS) {
|
||||||
return IdentType::unknown;
|
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<typename SF, typename RF, typename CF>
|
template<typename SF, typename RF, typename CF>
|
||||||
bool cs_override_var(CsState &cs, Var *v, SF sf, RF rf, CF cf) {
|
static inline bool cs_override_var(
|
||||||
if ((cs.identflags & IDF_OVERRIDDEN) || (v->flags & IDF_OVERRIDE)) {
|
CsState &cs, Var *v, int &vflags, SF sf, RF rf, CF cf
|
||||||
if (v->flags & IDF_PERSIST) {
|
) {
|
||||||
|
if ((cs.identflags & IDF_OVERRIDDEN) || (vflags & IDF_OVERRIDE)) {
|
||||||
|
if (vflags & IDF_PERSIST) {
|
||||||
cs_debug_code(
|
cs_debug_code(
|
||||||
cs, "cannot override persistent variable '%s'", v->name
|
cs, "cannot override persistent variable '%s'", v->get_name()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(v->flags & IDF_OVERRIDDEN)) {
|
if (!(vflags & IDF_OVERRIDDEN)) {
|
||||||
sf();
|
sf();
|
||||||
v->flags |= IDF_OVERRIDDEN;
|
vflags |= IDF_OVERRIDDEN;
|
||||||
} else {
|
} else {
|
||||||
cf();
|
cf();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (v->flags & IDF_OVERRIDDEN) {
|
if (vflags & IDF_OVERRIDDEN) {
|
||||||
rf();
|
rf();
|
||||||
v->flags &= ~IDF_OVERRIDDEN;
|
vflags &= ~IDF_OVERRIDDEN;
|
||||||
}
|
}
|
||||||
cf();
|
cf();
|
||||||
}
|
}
|
||||||
|
@ -786,7 +816,7 @@ void CsState::set_var_int(
|
||||||
}
|
}
|
||||||
Ivar *iv = static_cast<Ivar *>(id);
|
Ivar *iv = static_cast<Ivar *>(id);
|
||||||
bool success = cs_override_var(
|
bool success = cs_override_var(
|
||||||
*this, iv,
|
*this, iv, iv->p_flags,
|
||||||
[&iv]() { iv->overrideval = *iv->storage; },
|
[&iv]() { iv->overrideval = *iv->storage; },
|
||||||
[]() {}, []() {}
|
[]() {}, []() {}
|
||||||
);
|
);
|
||||||
|
@ -812,7 +842,7 @@ void CsState::set_var_float(
|
||||||
}
|
}
|
||||||
Fvar *fv = static_cast<Fvar *>(id);
|
Fvar *fv = static_cast<Fvar *>(id);
|
||||||
bool success = cs_override_var(
|
bool success = cs_override_var(
|
||||||
*this, fv,
|
*this, fv, fv->p_flags,
|
||||||
[&fv]() { fv->overrideval = *fv->storage; },
|
[&fv]() { fv->overrideval = *fv->storage; },
|
||||||
[]() {}, []() {}
|
[]() {}, []() {}
|
||||||
);
|
);
|
||||||
|
@ -838,7 +868,7 @@ void CsState::set_var_str(
|
||||||
}
|
}
|
||||||
Svar *sv = static_cast<Svar *>(id);
|
Svar *sv = static_cast<Svar *>(id);
|
||||||
bool success = cs_override_var(
|
bool success = cs_override_var(
|
||||||
*this, sv,
|
*this, sv, sv->p_flags,
|
||||||
[&sv]() { sv->overrideval = *sv->storage; },
|
[&sv]() { sv->overrideval = *sv->storage; },
|
||||||
[&sv]() { delete[] sv->overrideval; },
|
[&sv]() { delete[] sv->overrideval; },
|
||||||
[&sv]() { delete[] *sv->storage; }
|
[&sv]() { delete[] *sv->storage; }
|
||||||
|
@ -914,7 +944,10 @@ CsState::get_alias_val(ostd::ConstCharRange name) {
|
||||||
if (!a) {
|
if (!a) {
|
||||||
return ostd::nothing;
|
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::nothing;
|
||||||
}
|
}
|
||||||
return ostd::move(a->val_v.get_str());
|
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_debug_code(
|
||||||
cs,
|
cs,
|
||||||
(iv->flags & IDF_HEX)
|
(iv->get_flags() & IDF_HEX)
|
||||||
? (
|
? (
|
||||||
(iv->minval <= 255)
|
(iv->minval <= 255)
|
||||||
? "valid range for '%s' is %d..0x%X"
|
? "valid range for '%s' is %d..0x%X"
|
||||||
: "valid range for '%s' is 0x%X..0x%X"
|
: "valid range for '%s' is 0x%X..0x%X"
|
||||||
)
|
)
|
||||||
: "valid range for '%s' is %d..%d",
|
: "valid range for '%s' is %d..%d",
|
||||||
iv->name, iv->minval, iv->maxval
|
iv->get_name(), iv->minval, iv->maxval
|
||||||
);
|
);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CsState::set_var_int_checked(Ivar *iv, CsInt v) {
|
void CsState::set_var_int_checked(Ivar *iv, CsInt v) {
|
||||||
if (iv->flags & IDF_READONLY) {
|
if (iv->get_flags() & IDF_READONLY) {
|
||||||
cs_debug_code(*this, "variable '%s' is read only", iv->name);
|
cs_debug_code(*this, "variable '%s' is read only", iv->get_name());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool success = cs_override_var(
|
bool success = cs_override_var(
|
||||||
*this, iv,
|
*this, iv, iv->p_flags,
|
||||||
[&iv]() { iv->overrideval = *iv->storage; },
|
[&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) {
|
void CsState::set_var_int_checked(Ivar *iv, TvalRange args) {
|
||||||
CsInt v = args[0].force_int();
|
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);
|
v = (v << 16) | (args[1].force_int() << 8);
|
||||||
if (args.size() > 2) {
|
if (args.size() > 2) {
|
||||||
v |= args[2].force_int();
|
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) {
|
void CsState::set_var_float_checked(Fvar *fv, CsFloat v) {
|
||||||
if (fv->flags & IDF_READONLY) {
|
if (fv->get_flags() & IDF_READONLY) {
|
||||||
cs_debug_code(*this, "variable '%s' is read only", fv->name);
|
cs_debug_code(*this, "variable '%s' is read only", fv->get_name());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool success = cs_override_var(
|
bool success = cs_override_var(
|
||||||
*this, fv,
|
*this, fv, fv->p_flags,
|
||||||
[&fv]() { fv->overrideval = *fv->storage; },
|
[&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) {
|
void CsState::set_var_str_checked(Svar *sv, ostd::ConstCharRange v) {
|
||||||
if (sv->flags & IDF_READONLY) {
|
if (sv->get_flags() & IDF_READONLY) {
|
||||||
cs_debug_code(*this, "variable '%s' is read only", sv->name);
|
cs_debug_code(*this, "variable '%s' is read only", sv->get_name());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool success = cs_override_var(
|
bool success = cs_override_var(
|
||||||
*this, sv,
|
*this, sv, sv->p_flags,
|
||||||
[&sv]() { sv->overrideval = *sv->storage; },
|
[&sv]() { sv->overrideval = *sv->storage; },
|
||||||
[&sv]() { delete[] sv->overrideval; },
|
[&sv]() { delete[] sv->overrideval; },
|
||||||
[&sv]() { delete[] *sv->storage; }
|
[&sv]() { delete[] *sv->storage; }
|
||||||
|
@ -1283,7 +1316,7 @@ void cs_init_lib_base(CsState &cs) {
|
||||||
Ident *id = args[0].get_ident();
|
Ident *id = args[0].get_ident();
|
||||||
TaggedValue &v = args[1];
|
TaggedValue &v = args[1];
|
||||||
Bytecode *code = args[2].get_code();
|
Bytecode *code = args[2].get_code();
|
||||||
if (!id->is_alias() || (id->index < MaxArguments)) {
|
if (!id->is_alias() || (id->get_index() < MaxArguments)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Alias *a = static_cast<Alias *>(id);
|
Alias *a = static_cast<Alias *>(id);
|
||||||
|
@ -1423,7 +1456,7 @@ void cs_init_lib_base(CsState &cs) {
|
||||||
|
|
||||||
cs_add_command(cs, "push", "rTe", [&cs](TvalRange args, TaggedValue &res) {
|
cs_add_command(cs, "push", "rTe", [&cs](TvalRange args, TaggedValue &res) {
|
||||||
Ident *id = args[0].get_ident();
|
Ident *id = args[0].get_ident();
|
||||||
if (!id->is_alias() || (id->index < MaxArguments)) {
|
if (!id->is_alias() || (id->get_index() < MaxArguments)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Alias *a = static_cast<Alias *>(id);
|
Alias *a = static_cast<Alias *>(id);
|
||||||
|
|
|
@ -168,8 +168,7 @@ struct IdentStack {
|
||||||
struct CsState;
|
struct CsState;
|
||||||
|
|
||||||
enum class IdentType {
|
enum class IdentType {
|
||||||
unknown = -1,
|
ivar = 0, fvar, svar, command, alias, special
|
||||||
ivar, fvar, svar, command, alias
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Var;
|
struct Var;
|
||||||
|
@ -179,18 +178,19 @@ struct Svar;
|
||||||
struct Alias;
|
struct Alias;
|
||||||
|
|
||||||
struct OSTD_EXPORT Ident {
|
struct OSTD_EXPORT Ident {
|
||||||
int type; /* ID_something */
|
friend struct CsState;
|
||||||
ostd::ushort flags;
|
|
||||||
int index = -1;
|
|
||||||
ostd::String name;
|
|
||||||
|
|
||||||
IdentType get_type() const;
|
IdentType get_type() const;
|
||||||
|
ostd::ConstCharRange get_name() const;
|
||||||
|
int get_flags() const;
|
||||||
|
int get_index() const;
|
||||||
|
|
||||||
bool is_alias() const;
|
bool is_alias() const;
|
||||||
Alias *get_alias();
|
Alias *get_alias();
|
||||||
Alias const *get_alias() const;
|
Alias const *get_alias() const;
|
||||||
|
|
||||||
bool is_command() const;
|
bool is_command() const;
|
||||||
|
bool is_special() const;
|
||||||
|
|
||||||
bool is_var() const;
|
bool is_var() const;
|
||||||
Var *get_var();
|
Var *get_var();
|
||||||
|
@ -208,8 +208,21 @@ struct OSTD_EXPORT Ident {
|
||||||
Svar *get_svar();
|
Svar *get_svar();
|
||||||
Svar const *get_svar() const;
|
Svar const *get_svar() const;
|
||||||
|
|
||||||
|
int get_type_raw() const {
|
||||||
|
return p_type;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Ident(IdentType tp, ostd::ConstCharRange name, int flags = 0);
|
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<void(Ident &)>;
|
using VarCb = ostd::Function<void(Ident &)>;
|
||||||
|
@ -327,15 +340,7 @@ struct OSTD_EXPORT CsState {
|
||||||
void clear_override(Ident &id);
|
void clear_override(Ident &id);
|
||||||
void clear_overrides();
|
void clear_overrides();
|
||||||
|
|
||||||
Ident *add_ident(Ident *id) {
|
Ident *add_ident(Ident *id);
|
||||||
if (!id) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
idents[id->name] = id;
|
|
||||||
id->index = identmap.size();
|
|
||||||
return identmap.push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ident *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN);
|
Ident *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN);
|
||||||
Ident *force_ident(TaggedValue &v);
|
Ident *force_ident(TaggedValue &v);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue