use a strongly typed enum for CsValue type

master
Daniel Kolesa 2016-08-30 22:30:40 +01:00
parent 5e1d4c3f39
commit 9a95347709
4 changed files with 175 additions and 133 deletions

View File

@ -163,15 +163,17 @@ static inline ostd::Uint32 *forcecode(CsState &cs, CsValue &v) {
static inline void forcecond(CsState &cs, CsValue &v) {
switch (v.get_type()) {
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
if (!v.get_strr().empty()) {
forcecode(cs, v);
} else {
v.set_int(0);
}
break;
default:
break;
}
}
@ -185,17 +187,17 @@ static ostd::Uint32 emptyblock[VAL_ANY][2] = {
static inline void force_arg(CsValue &v, int type) {
switch (type) {
case RET_STR:
if (v.get_type() != VAL_STR) {
if (v.get_type() != CsValueType::string) {
v.force_str();
}
break;
case RET_INT:
if (v.get_type() != VAL_INT) {
if (v.get_type() != CsValueType::integer) {
v.force_int();
}
break;
case RET_FLOAT:
if (v.get_type() != VAL_FLOAT) {
if (v.get_type() != CsValueType::number) {
v.force_float();
}
break;
@ -255,17 +257,17 @@ static ostd::Uint32 *skipcode(
void CsValue::copy_arg(CsValue &r) const {
r.cleanup();
switch (get_type()) {
case VAL_INT:
case VAL_FLOAT:
case VAL_IDENT:
case CsValueType::integer:
case CsValueType::number:
case CsValueType::ident:
r = *this;
break;
case VAL_STR:
case VAL_CSTR:
case VAL_MACRO:
case CsValueType::string:
case CsValueType::cstring:
case CsValueType::macro:
r.set_str(ostd::ConstCharRange(p_s, p_len));
break;
case VAL_CODE: {
case CsValueType::code: {
ostd::Uint32 *bcode = reinterpret_cast<ostd::Uint32 *>(r.get_code());
ostd::Uint32 *end = skipcode(bcode);
ostd::Uint32 *dst = new ostd::Uint32[end - bcode + 1];
@ -511,9 +513,9 @@ static inline int cs_get_lookupu_type(
CsState &cs, CsValue &arg, CsIdent *&id, ostd::Uint32 op
) {
if (
arg.get_type() != VAL_STR &&
arg.get_type() != VAL_MACRO &&
arg.get_type() != VAL_CSTR
arg.get_type() != CsValueType::string &&
arg.get_type() != CsValueType::macro &&
arg.get_type() != CsValueType::cstring
) {
return -2; /* default case */
}
@ -733,7 +735,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
ostd::Uint32 len = op >> 8;
result.cleanup();
--numargs;
if (args[numargs].get_type() == VAL_CODE) {
if (args[numargs].get_type() == CsValueType::code) {
cs.run_ret(args[numargs].get_code(), result);
args[numargs].cleanup();
} else {
@ -748,7 +750,7 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
ostd::Uint32 len = op >> 8;
result.cleanup();
--numargs;
if (args[numargs].get_type() == VAL_CODE) {
if (args[numargs].get_type() == CsValueType::code) {
cs.run_ret(args[numargs].get_code(), result);
args[numargs].cleanup();
} else {
@ -876,23 +878,23 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
CsValue &arg = args[numargs - 1];
GenState gs(cs);
switch (arg.get_type()) {
case VAL_INT:
case CsValueType::integer:
gs.code.reserve(8);
gs.code.push(CODE_START);
gs.gen_int(arg.get_int());
gs.code.push(CODE_RESULT);
gs.code.push(CODE_EXIT);
break;
case VAL_FLOAT:
case CsValueType::number:
gs.code.reserve(8);
gs.code.push(CODE_START);
gs.gen_float(arg.get_float());
gs.code.push(CODE_RESULT);
gs.code.push(CODE_EXIT);
break;
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
gs.code.reserve(64);
gs.gen_main(arg.get_strr());
arg.cleanup();
@ -913,9 +915,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
case CODE_COND: {
CsValue &arg = args[numargs - 1];
switch (arg.get_type()) {
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR: {
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring: {
ostd::ConstCharRange s = arg.get_strr();
if (!s.empty()) {
GenState gs(cs);
@ -930,6 +932,8 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
}
break;
}
default:
break;
}
continue;
}
@ -952,9 +956,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
CsValue &arg = args[numargs - 1];
CsIdent *id = cs.identmap[DummyIdx];
if (
arg.get_type() == VAL_STR ||
arg.get_type() == VAL_MACRO ||
arg.get_type() == VAL_CSTR
arg.get_type() == CsValueType::string ||
arg.get_type() == CsValueType::macro ||
arg.get_type() == CsValueType::cstring
) {
id = cs.new_ident(arg.get_strr());
}
@ -1450,9 +1454,9 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
int callargs = op >> 8, offset = numargs - callargs;
CsValue &idarg = args[offset - 1];
if (
idarg.get_type() != VAL_STR &&
idarg.get_type() != VAL_MACRO &&
idarg.get_type() != VAL_CSTR
idarg.get_type() != CsValueType::string &&
idarg.get_type() != CsValueType::macro &&
idarg.get_type() != CsValueType::cstring
) {
litval:
result.cleanup();
@ -1553,7 +1557,7 @@ noid:
force_arg(result, op & CODE_RET_MASK);
continue;
}
if (a->val_v.get_type() == VAL_NULL) {
if (a->val_v.get_type() == CsValueType::null) {
goto noid;
}
idarg.cleanup();
@ -1648,7 +1652,7 @@ void CsState::run_ret(CsIdent *id, CsValueRange args, CsValue &ret) {
break;
}
}
if (a->val_v.get_type() == VAL_NULL) {
if (a->val_v.get_type() == CsValueType::null) {
break;
}
cs_call_alias(

View File

@ -22,6 +22,21 @@ enum {
ID_LOCAL, ID_DO, ID_DOARGS, ID_IF, ID_RESULT, ID_NOT, ID_AND, ID_OR
};
enum {
VAL_NULL = 0, VAL_INT, VAL_FLOAT, VAL_STR,
VAL_ANY, VAL_CODE, VAL_MACRO, VAL_IDENT, VAL_CSTR,
VAL_CANY, VAL_WORD, VAL_POP, VAL_COND
};
static const int cs_valtypet[] = {
VAL_NULL, VAL_INT, VAL_FLOAT, VAL_STR,
VAL_CSTR, VAL_CODE, VAL_MACRO, VAL_IDENT
};
static inline int cs_vtype_to_int(CsValueType v) {
return cs_valtypet[int(v)];
}
struct Command: CsIdent {
char *cargs;
ostd::Uint32 argmask;

View File

@ -351,16 +351,18 @@ CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) {
CsIdent *CsState::force_ident(CsValue &v) {
switch (v.get_type()) {
case VAL_IDENT:
case CsValueType::ident:
return v.get_ident();
case VAL_MACRO:
case VAL_CSTR:
case VAL_STR: {
case CsValueType::macro:
case CsValueType::cstring:
case CsValueType::string: {
CsIdent *id = new_ident(v.get_strr());
v.cleanup();
v.set_ident(id);
return id;
}
default:
break;
}
v.cleanup();
v.set_ident(identmap[DummyIdx]);
@ -480,29 +482,32 @@ void CsState::print_var(CsVar *v) {
void CsValue::cleanup() {
switch (get_type()) {
case VAL_STR:
case CsValueType::string:
delete[] p_s;
break;
case VAL_CODE:
case CsValueType::code: {
ostd::Uint32 *bcode = reinterpret_cast<ostd::Uint32 *>(p_code);
if (bcode[-1] == CODE_START) {
delete[] bcode;
}
break;
}
default:
break;
}
}
int CsValue::get_type() const {
CsValueType CsValue::get_type() const {
return p_type;
}
void CsValue::set_int(CsInt val) {
p_type = VAL_INT;
p_type = CsValueType::integer;
p_i = val;
}
void CsValue::set_float(CsFloat val) {
p_type = VAL_FLOAT;
p_type = CsValueType::number;
p_f = val;
}
@ -520,46 +525,46 @@ void CsValue::set_str(CsString val) {
}
void CsValue::set_null() {
p_type = VAL_NULL;
p_type = CsValueType::null;
p_code = nullptr;
}
void CsValue::set_code(CsBytecode *val) {
p_type = VAL_CODE;
p_type = CsValueType::code;
p_code = val;
}
void CsValue::set_cstr(ostd::ConstCharRange val) {
p_type = VAL_CSTR;
p_type = CsValueType::cstring;
p_len = val.size();
p_cstr = val.data();
}
void CsValue::set_mstr(ostd::CharRange val) {
p_type = VAL_STR;
p_type = CsValueType::string;
p_len = val.size();
p_s = val.data();
}
void CsValue::set_ident(CsIdent *val) {
p_type = VAL_IDENT;
p_type = CsValueType::ident;
p_id = val;
}
void CsValue::set_macro(ostd::ConstCharRange val) {
p_type = VAL_MACRO;
p_type = CsValueType::macro;
p_len = val.size();
p_cstr = val.data();
}
void CsValue::set(CsValue &tv) {
*this = tv;
tv.p_type = VAL_NULL;
tv.p_type = CsValueType::null;
}
void CsValue::force_null() {
if (get_type() == VAL_NULL) {
if (get_type() == CsValueType::null) {
return;
}
cleanup();
@ -569,16 +574,18 @@ void CsValue::force_null() {
CsFloat CsValue::force_float() {
CsFloat rf = 0.0f;
switch (get_type()) {
case VAL_INT:
case CsValueType::integer:
rf = p_i;
break;
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
rf = cs_parse_float(ostd::ConstCharRange(p_s, p_len));
break;
case VAL_FLOAT:
case CsValueType::number:
return p_f;
default:
break;
}
cleanup();
set_float(rf);
@ -588,16 +595,18 @@ CsFloat CsValue::force_float() {
CsInt CsValue::force_int() {
CsInt ri = 0;
switch (get_type()) {
case VAL_FLOAT:
case CsValueType::number:
ri = p_f;
break;
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
ri = cs_parse_int(ostd::ConstCharRange(p_s, p_len));
break;
case VAL_INT:
case CsValueType::integer:
return p_i;
default:
break;
}
cleanup();
set_int(ri);
@ -607,18 +616,20 @@ CsInt CsValue::force_int() {
ostd::ConstCharRange CsValue::force_str() {
CsString rs;
switch (get_type()) {
case VAL_FLOAT:
case CsValueType::number:
rs = ostd::move(floatstr(p_f));
break;
case VAL_INT:
case CsValueType::integer:
rs = ostd::move(intstr(p_i));
break;
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::macro:
case CsValueType::cstring:
rs = ostd::ConstCharRange(p_s, p_len);
break;
case VAL_STR:
case CsValueType::string:
return ostd::ConstCharRange(p_s, p_len);
default:
break;
}
cleanup();
set_str(ostd::move(rs));
@ -627,41 +638,45 @@ ostd::ConstCharRange CsValue::force_str() {
CsInt CsValue::get_int() const {
switch (get_type()) {
case VAL_FLOAT:
case CsValueType::number:
return CsInt(p_f);
case VAL_INT:
case CsValueType::integer:
return p_i;
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
return cs_parse_int(ostd::ConstCharRange(p_s, p_len));
default:
break;
}
return 0;
}
CsFloat CsValue::get_float() const {
switch (get_type()) {
case VAL_FLOAT:
case CsValueType::number:
return p_f;
case VAL_INT:
case CsValueType::integer:
return CsFloat(p_i);
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
return cs_parse_float(ostd::ConstCharRange(p_s, p_len));
default:
break;
}
return 0.0f;
}
CsBytecode *CsValue::get_code() const {
if (get_type() != VAL_CODE) {
if (get_type() != CsValueType::code) {
return nullptr;
}
return p_code;
}
CsIdent *CsValue::get_ident() const {
if (get_type() != VAL_IDENT) {
if (get_type() != CsValueType::ident) {
return nullptr;
}
return p_id;
@ -669,23 +684,25 @@ CsIdent *CsValue::get_ident() const {
CsString CsValue::get_str() const {
switch (get_type()) {
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
return ostd::ConstCharRange(p_s, p_len);
case VAL_INT:
return intstr(p_i);
case VAL_FLOAT:
return floatstr(p_f);
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
return ostd::ConstCharRange(p_s, p_len);
case CsValueType::integer:
return intstr(p_i);
case CsValueType::number:
return floatstr(p_f);
default:
break;
}
return CsString("");
}
ostd::ConstCharRange CsValue::get_strr() const {
switch (get_type()) {
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
return ostd::ConstCharRange(p_s, p_len);
default:
break;
@ -695,16 +712,15 @@ ostd::ConstCharRange CsValue::get_strr() const {
void CsValue::get_val(CsValue &r) const {
switch (get_type()) {
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR: {
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
r.set_str(ostd::ConstCharRange(p_s, p_len));
break;
}
case VAL_INT:
case CsValueType::integer:
r.set_int(p_i);
break;
case VAL_FLOAT:
case CsValueType::number:
r.set_float(p_f);
break;
default:
@ -723,7 +739,7 @@ OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code) {
}
bool CsValue::code_is_empty() const {
if (get_type() != VAL_CODE) {
if (get_type() != CsValueType::code) {
return true;
}
return cscript::cs_code_is_empty(p_code);
@ -748,13 +764,13 @@ static inline bool cs_get_bool(ostd::ConstCharRange s) {
bool CsValue::get_bool() const {
switch (get_type()) {
case VAL_FLOAT:
case CsValueType::number:
return p_f != 0;
case VAL_INT:
case CsValueType::integer:
return p_i != 0;
case VAL_STR:
case VAL_MACRO:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::macro:
case CsValueType::cstring:
return cs_get_bool(ostd::ConstCharRange(p_s, p_len));
default:
return false;
@ -763,17 +779,17 @@ bool CsValue::get_bool() const {
void CsAlias::get_cstr(CsValue &v) const {
switch (val_v.get_type()) {
case VAL_MACRO:
case CsValueType::macro:
v.set_macro(val_v.get_strr());
break;
case VAL_STR:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::cstring:
v.set_cstr(val_v.get_strr());
break;
case VAL_INT:
case CsValueType::integer:
v.set_str(ostd::move(intstr(val_v.get_int())));
break;
case VAL_FLOAT:
case CsValueType::number:
v.set_str(ostd::move(floatstr(val_v.get_float())));
break;
default:
@ -784,17 +800,17 @@ void CsAlias::get_cstr(CsValue &v) const {
void CsAlias::get_cval(CsValue &v) const {
switch (val_v.get_type()) {
case VAL_MACRO:
case CsValueType::macro:
v.set_macro(val_v.get_strr());
break;
case VAL_STR:
case VAL_CSTR:
case CsValueType::string:
case CsValueType::cstring:
v.set_cstr(val_v.get_strr());
break;
case VAL_INT:
case CsValueType::integer:
v.set_int(val_v.get_int());
break;
case VAL_FLOAT:
case CsValueType::number:
v.set_float(val_v.get_float());
break;
default:
@ -1389,7 +1405,10 @@ void cs_init_lib_base(CsState &cs) {
cs_add_command(cs, "case", "ite2V", [&cs](CsValueRange args, CsValue &res) {
CsInt val = args[0].get_int();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if ((args[i].get_type() == VAL_NULL) || (args[i].get_int() == val)) {
if (
(args[i].get_type() == CsValueType::null) ||
(args[i].get_int() == val)
) {
cs.run_ret(args[i + 1].get_code(), res);
return;
}
@ -1399,7 +1418,10 @@ void cs_init_lib_base(CsState &cs) {
cs_add_command(cs, "casef", "fte2V", [&cs](CsValueRange args, CsValue &res) {
CsFloat val = args[0].get_float();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if ((args[i].get_type() == VAL_NULL) || (args[i].get_float() == val)) {
if (
(args[i].get_type() == CsValueType::null) ||
(args[i].get_float() == val)
) {
cs.run_ret(args[i + 1].get_code(), res);
return;
}
@ -1409,7 +1431,10 @@ void cs_init_lib_base(CsState &cs) {
cs_add_command(cs, "cases", "ste2V", [&cs](CsValueRange args, CsValue &res) {
CsString val = args[0].get_str();
for (ostd::Size i = 1; (i + 1) < args.size(); i += 2) {
if ((args[i].get_type() == VAL_NULL) || (args[i].get_str() == val)) {
if (
(args[i].get_type() == CsValueType::null) ||
(args[i].get_str() == val)
) {
cs.run_ret(args[i + 1].get_code(), res);
return;
}

View File

@ -20,12 +20,6 @@
namespace cscript {
enum {
VAL_NULL = 0, VAL_INT, VAL_FLOAT, VAL_STR,
VAL_ANY, VAL_CODE, VAL_MACRO, VAL_IDENT, VAL_CSTR,
VAL_CANY, VAL_WORD, VAL_POP, VAL_COND
};
enum {
IDF_PERSIST = 1 << 0,
IDF_OVERRIDE = 1 << 1,
@ -66,8 +60,12 @@ OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code);
struct CsIdent;
enum class CsValueType {
null = 0, integer, number, string, cstring, code, macro, ident
};
struct OSTD_EXPORT CsValue {
int get_type() const;
CsValueType get_type() const;
void set_int(CsInt val);
void set_float(CsFloat val);
@ -103,15 +101,15 @@ struct OSTD_EXPORT CsValue {
private:
union {
CsInt p_i; /* ID_IVAR, VAL_INT */
CsFloat p_f; /* ID_FVAR, VAL_FLOAT */
CsBytecode *p_code; /* VAL_CODE */
CsIdent *p_id; /* VAL_IDENT */
char *p_s; /* ID_SVAR, VAL_STR */
char const *p_cstr; /* VAL_CSTR */
CsInt p_i;
CsFloat p_f;
CsBytecode *p_code;
CsIdent *p_id;
char *p_s;
char const *p_cstr;
};
ostd::Size p_len;
int p_type;
CsValueType p_type;
};
using CsValueRange = ostd::PointerRange<CsValue>;
@ -624,7 +622,7 @@ namespace util {
for (ostd::Size i = 0; i < vals.size(); ++i) {
auto s = ostd::appender<CsString>();
switch (vals[i].get_type()) {
case VAL_INT: {
case CsValueType::integer: {
auto r = format_int(
ostd::forward<R>(writer), vals[i].get_int()
);
@ -633,7 +631,7 @@ namespace util {
}
break;
}
case VAL_FLOAT: {
case CsValueType::number: {
auto r = format_float(
ostd::forward<R>(writer), vals[i].get_float()
);
@ -642,9 +640,9 @@ namespace util {
}
break;
}
case VAL_STR:
case VAL_CSTR:
case VAL_MACRO: {
case CsValueType::string:
case CsValueType::cstring:
case CsValueType::macro: {
auto sv = vals[i].get_strr();
ret += writer.put_n(sv.data(), sv.size());
break;