more fixes

master
Daniel Kolesa 2015-08-12 02:54:13 +01:00
parent d81b166544
commit 372b1055c5
1 changed files with 39 additions and 28 deletions

View File

@ -13,6 +13,11 @@ static inline int parseint(const char *s) {
return int(strtoul(s, nullptr, 0)); return int(strtoul(s, nullptr, 0));
} }
static inline int cs_parse_int(ostd::ConstCharRange s) {
if (s.empty()) return 0;
return parseint(s.data());
}
static inline float parsefloat(const char *s) static inline float parsefloat(const char *s)
{ {
/* not all platforms (windows) can parse hexadecimal integers via strtod */ /* not all platforms (windows) can parse hexadecimal integers via strtod */
@ -21,6 +26,11 @@ static inline float parsefloat(const char *s)
return val || end==s || (*end!='x' && *end!='X') ? float(val) : float(parseint(s)); return val || end==s || (*end!='x' && *end!='X') ? float(val) : float(parseint(s));
} }
static inline float cs_parse_float(ostd::ConstCharRange s) {
if (s.empty()) return 0.0f;
return parsefloat(s.data());
}
static inline void intformat(char *buf, int v, int len = 20) { static inline void intformat(char *buf, int v, int len = 20) {
snprintf(buf, len, "%d", v); snprintf(buf, len, "%d", v);
} }
@ -1266,7 +1276,7 @@ struct GenState {
} }
void gen_int(ostd::ConstCharRange word) { void gen_int(ostd::ConstCharRange word) {
gen_int(!word.empty() ? parseint(word.data()) : 0); gen_int(cs_parse_int(word));
} }
void gen_float(float f = 0.0f) { void gen_float(float f = 0.0f) {
@ -1284,7 +1294,7 @@ struct GenState {
} }
void gen_float(ostd::ConstCharRange word) { void gen_float(ostd::ConstCharRange word) {
gen_float(!word.empty() ? parsefloat(word.data()) : 0.0f); gen_float(cs_parse_float(word));
} }
void gen_ident(Ident *id) { void gen_ident(Ident *id) {
@ -1404,41 +1414,42 @@ static ostd::Uint32 emptyblock[VAL_ANY][2] = {
{ CODE_START + 0x100, CODE_EXIT | RET_STR } { CODE_START + 0x100, CODE_EXIT | RET_STR }
}; };
static inline bool getbool(const char *s) { static inline bool cs_get_bool(ostd::ConstCharRange s) {
switch (s[0]) { if (s.empty())
return false;
switch (s.front()) {
case '+': case '+':
case '-': case '-':
switch (s[1]) { switch (s[1]) {
case '0': case '0':
break; break;
case '.': case '.':
return !isdigit(s[2]) || parsefloat(s) != 0; return !isdigit(s[2]) || (cs_parse_float(s) != 0);
default: default:
return true; return true;
} }
/* fallthrough */ /* fallthrough */
case '0': { case '0': {
char *end; char *end;
int val = int(strtoul((char *)s, &end, 0)); int val = int(strtoul(s.data(), &end, 0));
if (val) return true; if (val) return true;
switch (*end) { switch (*end) {
case 'e': case 'e':
case '.': case '.':
return parsefloat(s) != 0; return (cs_parse_float(s) != 0);
default: default:
return false; return false;
} }
} }
case '.': case '.':
return !isdigit(s[1]) || parsefloat(s) != 0; return !isdigit(s[1]) || (cs_parse_float(s) != 0);
case '\0': case '\0':
return false; return false;
default:
return true;
} }
return true;
} }
static inline bool getbool(const TaggedValue &v) { static inline bool cs_get_bool(const TaggedValue &v) {
switch (v.type) { switch (v.type) {
case VAL_FLOAT: case VAL_FLOAT:
return v.f != 0; return v.f != 0;
@ -1447,7 +1458,7 @@ static inline bool getbool(const TaggedValue &v) {
case VAL_STR: case VAL_STR:
case VAL_MACRO: case VAL_MACRO:
case VAL_CSTR: case VAL_CSTR:
return getbool(v.s); return cs_get_bool(v.s);
default: default:
return false; return false;
} }
@ -2631,10 +2642,10 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
#define RETPOP(op, val) \ #define RETPOP(op, val) \
RETOP(op, { --numargs; val; args[numargs].cleanup(); }) RETOP(op, { --numargs; val; args[numargs].cleanup(); })
RETPOP(CODE_NOT | RET_STR, result.set_str(cs_dup_ostr(getbool(args[numargs]) ? "0" : "1"))) RETPOP(CODE_NOT | RET_STR, result.set_str(cs_dup_ostr(cs_get_bool(args[numargs]) ? "0" : "1")))
case CODE_NOT|RET_NULL: case CODE_NOT|RET_NULL:
RETPOP(CODE_NOT | RET_INT, result.set_int(getbool(args[numargs]) ? 0 : 1)) RETPOP(CODE_NOT | RET_INT, result.set_int(cs_get_bool(args[numargs]) ? 0 : 1))
RETPOP(CODE_NOT | RET_FLOAT, result.set_float(getbool(args[numargs]) ? 0.0f : 1.0f)) RETPOP(CODE_NOT | RET_FLOAT, result.set_float(cs_get_bool(args[numargs]) ? 0.0f : 1.0f))
case CODE_POP: case CODE_POP:
args[--numargs].cleanup(); args[--numargs].cleanup();
@ -2707,13 +2718,13 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
} }
case CODE_JUMP_TRUE: { case CODE_JUMP_TRUE: {
ostd::Uint32 len = op >> 8; ostd::Uint32 len = op >> 8;
if (getbool(args[--numargs])) code += len; if (cs_get_bool(args[--numargs])) code += len;
args[numargs].cleanup(); args[numargs].cleanup();
continue; continue;
} }
case CODE_JUMP_FALSE: { case CODE_JUMP_FALSE: {
ostd::Uint32 len = op >> 8; ostd::Uint32 len = op >> 8;
if (!getbool(args[--numargs])) code += len; if (!cs_get_bool(args[--numargs])) code += len;
args[numargs].cleanup(); args[numargs].cleanup();
continue; continue;
} }
@ -2725,7 +2736,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
runcode(cs, args[numargs].code, result); runcode(cs, args[numargs].code, result);
args[numargs].cleanup(); args[numargs].cleanup();
} else result = args[numargs]; } else result = args[numargs];
if (getbool(result)) code += len; if (cs_get_bool(result)) code += len;
continue; continue;
} }
case CODE_JUMP_RESULT_FALSE: { case CODE_JUMP_RESULT_FALSE: {
@ -2736,7 +2747,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
runcode(cs, args[numargs].code, result); runcode(cs, args[numargs].code, result);
args[numargs].cleanup(); args[numargs].cleanup();
} else result = args[numargs]; } else result = args[numargs];
if (!getbool(result)) code += len; if (!cs_get_bool(result)) code += len;
continue; continue;
} }
@ -3438,7 +3449,7 @@ float CsState::run_float(Ident *id, ostd::PointerRange<TaggedValue> args) {
bool CsState::run_bool(const ostd::Uint32 *code) { bool CsState::run_bool(const ostd::Uint32 *code) {
TaggedValue result; TaggedValue result;
runcode(*this, code, result); runcode(*this, code, result);
bool b = getbool(result); bool b = cs_get_bool(result);
result.cleanup(); result.cleanup();
return b; return b;
} }
@ -3446,7 +3457,7 @@ bool CsState::run_bool(const ostd::Uint32 *code) {
bool CsState::run_bool(ostd::ConstCharRange code) { bool CsState::run_bool(ostd::ConstCharRange code) {
TaggedValue result; TaggedValue result;
run_ret(code, result); run_ret(code, result);
bool b = getbool(result); bool b = cs_get_bool(result);
result.cleanup(); result.cleanup();
return b; return b;
} }
@ -3454,7 +3465,7 @@ bool CsState::run_bool(ostd::ConstCharRange code) {
bool CsState::run_bool(Ident *id, ostd::PointerRange<TaggedValue> args) { bool CsState::run_bool(Ident *id, ostd::PointerRange<TaggedValue> args) {
TaggedValue result; TaggedValue result;
run_ret(id, args, result); run_ret(id, args, result);
bool b = getbool(result); bool b = cs_get_bool(result);
result.cleanup(); result.cleanup();
return b; return b;
} }
@ -3514,7 +3525,7 @@ void init_lib_base(CsState &cs) {
cs.add_command("if", "tee", [](CsState &cs, TaggedValue *cond, cs.add_command("if", "tee", [](CsState &cs, TaggedValue *cond,
ostd::Uint32 *t, ostd::Uint32 *f) { ostd::Uint32 *t, ostd::Uint32 *f) {
cs.run_ret(getbool(*cond) ? t : f); cs.run_ret(cs_get_bool(*cond) ? t : f);
}, ID_IF); }, ID_IF);
cs.add_command("result", "T", [](CsState &cs, TaggedValue *v) { cs.add_command("result", "T", [](CsState &cs, TaggedValue *v) {
@ -3523,7 +3534,7 @@ void init_lib_base(CsState &cs) {
}, ID_RESULT); }, ID_RESULT);
cs.add_command("!", "t", [](CsState &cs, TaggedValue *a) { cs.add_command("!", "t", [](CsState &cs, TaggedValue *a) {
cs.result->set_int(!getbool(*a)); cs.result->set_int(!cs_get_bool(*a));
}, ID_NOT); }, ID_NOT);
cs.add_command("&&", "E1V", [](CsState &cs, TaggedValue *args, cs.add_command("&&", "E1V", [](CsState &cs, TaggedValue *args,
@ -3536,7 +3547,7 @@ void init_lib_base(CsState &cs) {
cs.run_ret(args[i].code); cs.run_ret(args[i].code);
else else
*cs.result = args[i]; *cs.result = args[i];
if (!getbool(*cs.result)) break; if (!cs_get_bool(*cs.result)) break;
} }
}, ID_AND); }, ID_AND);
@ -3550,13 +3561,13 @@ void init_lib_base(CsState &cs) {
cs.run_ret(args[i].code); cs.run_ret(args[i].code);
else else
*cs.result = args[i]; *cs.result = args[i];
if (getbool(*cs.result)) break; if (cs_get_bool(*cs.result)) break;
} }
}, ID_OR); }, ID_OR);
cs.add_command("?", "tTT", [](CsState &cs, TaggedValue *cond, cs.add_command("?", "tTT", [](CsState &cs, TaggedValue *cond,
TaggedValue *t, TaggedValue *f) { TaggedValue *t, TaggedValue *f) {
cs.result->set(*(getbool(*cond) ? t : f)); cs.result->set(*(cs_get_bool(*cond) ? t : f));
}); });
cs.add_command("cond", "ee2V", [](CsState &cs, TaggedValue *args, cs.add_command("cond", "ee2V", [](CsState &cs, TaggedValue *args,
@ -3605,7 +3616,7 @@ void init_lib_base(CsState &cs) {
TaggedValue *v, ostd::Uint32 *code) { TaggedValue *v, ostd::Uint32 *code) {
if ((id->type != ID_ALIAS) || (id->index < MAX_ARGUMENTS)) if ((id->type != ID_ALIAS) || (id->index < MAX_ARGUMENTS))
return; return;
if (getbool(*v)) { if (cs_get_bool(*v)) {
IdentStack stack; IdentStack stack;
id->push_arg(*v, stack); id->push_arg(*v, stack);
v->type = VAL_NULL; v->type = VAL_NULL;