float operator fixes + encapsulation

master
Daniel Kolesa 2015-08-13 21:48:03 +01:00
parent 634c52b168
commit c684239bf0
2 changed files with 54 additions and 49 deletions

View File

@ -118,7 +118,7 @@ Ident::Ident(int t, ostd::ConstCharRange n, int flags)
stack(nullptr) { stack(nullptr) {
} }
Ident::Ident(int t, ostd::ConstCharRange n, const TaggedValue &v, int flags) Ident::Ident(int t, ostd::ConstCharRange n, const TaggedValue &v, int flags)
: type(t), valtype(v.type), flags(flags), name(n), code(nullptr), : type(t), valtype(v.get_type()), flags(flags), name(n), code(nullptr),
stack(nullptr) { stack(nullptr) {
val = v; val = v;
} }
@ -270,7 +270,7 @@ Ident *CsState::new_ident(ostd::ConstCharRange name, int flags) {
} }
Ident *CsState::force_ident(TaggedValue &v) { Ident *CsState::force_ident(TaggedValue &v) {
switch (v.type) { switch (v.get_type()) {
case VAL_IDENT: case VAL_IDENT:
return v.id; return v.id;
case VAL_MACRO: case VAL_MACRO:
@ -388,7 +388,7 @@ void CsState::print_var(Ident *id) {
} }
inline void TaggedValue::cleanup() { inline void TaggedValue::cleanup() {
switch (type) { switch (get_type()) {
case VAL_STR: case VAL_STR:
delete[] s; delete[] s;
break; break;
@ -399,14 +399,14 @@ inline void TaggedValue::cleanup() {
} }
inline void TaggedValue::force_null() { inline void TaggedValue::force_null() {
if (type == VAL_NULL) return; if (get_type() == VAL_NULL) return;
cleanup(); cleanup();
set_null(); set_null();
} }
inline float TaggedValue::force_float() { inline float TaggedValue::force_float() {
float rf = 0.0f; float rf = 0.0f;
switch (type) { switch (get_type()) {
case VAL_INT: case VAL_INT:
rf = i; rf = i;
break; break;
@ -425,7 +425,7 @@ inline float TaggedValue::force_float() {
inline int TaggedValue::force_int() { inline int TaggedValue::force_int() {
int ri = 0; int ri = 0;
switch (type) { switch (get_type()) {
case VAL_FLOAT: case VAL_FLOAT:
ri = f; ri = f;
break; break;
@ -444,7 +444,7 @@ inline int TaggedValue::force_int() {
inline ostd::ConstCharRange TaggedValue::force_str() { inline ostd::ConstCharRange TaggedValue::force_str() {
const char *rs = ""; const char *rs = "";
switch (type) { switch (get_type()) {
case VAL_FLOAT: case VAL_FLOAT:
rs = floatstr(f); rs = floatstr(f);
break; break;
@ -464,7 +464,7 @@ inline ostd::ConstCharRange TaggedValue::force_str() {
} }
inline void TaggedValue::force(int type) { inline void TaggedValue::force(int type) {
switch (type) { switch (get_type()) {
case RET_STR: case RET_STR:
if (type != VAL_STR) force_str(); if (type != VAL_STR) force_str();
break; break;
@ -492,7 +492,7 @@ static inline int cs_get_int(const IdentValue &v, int type) {
} }
inline int TaggedValue::get_int() const { inline int TaggedValue::get_int() const {
return cs_get_int(*this, type); return cs_get_int(*this, get_type());
} }
inline int Ident::get_int() const { inline int Ident::get_int() const {
@ -514,7 +514,7 @@ static inline float cs_get_float(const IdentValue &v, int type) {
} }
inline float TaggedValue::get_float() const { inline float TaggedValue::get_float() const {
return cs_get_float(*this, type); return cs_get_float(*this, get_type());
} }
inline float Ident::get_float() const { inline float Ident::get_float() const {
@ -536,7 +536,7 @@ static inline ostd::ConstCharRange cs_get_str(const IdentValue &v, int type) {
} }
inline ostd::ConstCharRange TaggedValue::get_str() const { inline ostd::ConstCharRange TaggedValue::get_str() const {
return cs_get_str(*this, type); return cs_get_str(*this, get_type());
} }
inline ostd::ConstCharRange Ident::get_str() const { inline ostd::ConstCharRange Ident::get_str() const {
@ -563,7 +563,7 @@ static inline void cs_get_val(const IdentValue &v, int type, TaggedValue &r) {
} }
inline void TaggedValue::get_val(TaggedValue &r) const { inline void TaggedValue::get_val(TaggedValue &r) const {
cs_get_val(*this, type, r); cs_get_val(*this, get_type(), r);
} }
inline void Ident::get_val(TaggedValue &r) const { inline void Ident::get_val(TaggedValue &r) const {
@ -995,7 +995,7 @@ static void cs_init_lib_base_var(CsState &cs) {
if (id->type != ID_ALIAS || id->index < MAX_ARGUMENTS) return; if (id->type != ID_ALIAS || id->index < MAX_ARGUMENTS) return;
IdentStack stack; IdentStack stack;
id->push_arg(*v, stack); id->push_arg(*v, stack);
v->type = VAL_NULL; v->set_null();
cs.run_ret(code); cs.run_ret(code);
id->pop_arg(); id->pop_arg();
}); });
@ -1009,7 +1009,7 @@ static void cs_init_lib_base_var(CsState &cs) {
cs.add_command("alias", "sT", [](CsState &cs, const char *name, cs.add_command("alias", "sT", [](CsState &cs, const char *name,
TaggedValue *v) { TaggedValue *v) {
cs.set_alias(name, *v); cs.set_alias(name, *v);
v->type = VAL_NULL; v->set_null();
}); });
cs.add_command("getvarmin", "s", [](CsState &cs, const char *name) { cs.add_command("getvarmin", "s", [](CsState &cs, const char *name) {
@ -1070,7 +1070,7 @@ static char *conc(ostd::Vector<char> &buf, TaggedValue *v, int n, bool space, co
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
const char *s = ""; const char *s = "";
int len = 0; int len = 0;
switch (v[i].type) { switch (v[i].get_type()) {
case VAL_INT: case VAL_INT:
s = intstr(v[i].i); s = intstr(v[i].i);
break; break;
@ -1100,7 +1100,7 @@ static char *conc(TaggedValue *v, int n, bool space, const char *prefix, int pre
static int vlen[MAX_ARGUMENTS]; static int vlen[MAX_ARGUMENTS];
static char numbuf[3 * 256]; static char numbuf[3 * 256];
int len = prefixlen, numlen = 0, i = 0; int len = prefixlen, numlen = 0, i = 0;
for (; i < n; i++) switch (v[i].type) { for (; i < n; i++) switch (v[i].get_type()) {
case VAL_MACRO: case VAL_MACRO:
len += (vlen[i] = v[i].code[-1] >> 8); len += (vlen[i] = v[i].code[-1] >> 8);
break; break;
@ -1132,7 +1132,7 @@ overflow:
if (space && i) buf[offset++] = ' '; if (space && i) buf[offset++] = ' ';
} }
for (ostd::Size j = 0; j < ostd::Size(i); ++j) { for (ostd::Size j = 0; j < ostd::Size(i); ++j) {
if (v[j].type == VAL_INT || v[j].type == VAL_FLOAT) { if (v[j].get_type() == VAL_INT || v[j].get_type() == VAL_FLOAT) {
memcpy(&buf[offset], &numbuf[numoffset], vlen[j]); memcpy(&buf[offset], &numbuf[numoffset], vlen[j]);
numoffset += vlen[j]; numoffset += vlen[j];
} else if (vlen[j]) memcpy(&buf[offset], v[j].s, vlen[j]); } else if (vlen[j]) memcpy(&buf[offset], v[j].s, vlen[j]);
@ -1471,7 +1471,7 @@ static inline bool cs_get_bool(ostd::ConstCharRange s) {
} }
static inline bool cs_get_bool(const TaggedValue &v) { static inline bool cs_get_bool(const TaggedValue &v) {
switch (v.type) { switch (v.get_type()) {
case VAL_FLOAT: case VAL_FLOAT:
return v.f != 0; return v.f != 0;
case VAL_INT: case VAL_INT:
@ -2375,7 +2375,7 @@ ostd::Uint32 *CsState::compile(ostd::ConstCharRange str) {
} }
static inline const ostd::Uint32 *forcecode(CsState &cs, TaggedValue &v) { static inline const ostd::Uint32 *forcecode(CsState &cs, TaggedValue &v) {
if (v.type != VAL_CODE) { if (v.get_type() != VAL_CODE) {
GenState gs(cs); GenState gs(cs);
gs.code.reserve(64); gs.code.reserve(64);
gs.gen_main(v.get_str()); gs.gen_main(v.get_str());
@ -2386,7 +2386,7 @@ static inline const ostd::Uint32 *forcecode(CsState &cs, TaggedValue &v) {
} }
static inline void forcecond(CsState &cs, TaggedValue &v) { static inline void forcecond(CsState &cs, TaggedValue &v) {
switch (v.type) { switch (v.get_type()) {
case VAL_STR: case VAL_STR:
case VAL_MACRO: case VAL_MACRO:
case VAL_CSTR: case VAL_CSTR:
@ -2753,7 +2753,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
ostd::Uint32 len = op >> 8; ostd::Uint32 len = op >> 8;
result.cleanup(); result.cleanup();
--numargs; --numargs;
if (args[numargs].type == VAL_CODE) { if (args[numargs].get_type() == VAL_CODE) {
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];
@ -2764,7 +2764,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
ostd::Uint32 len = op >> 8; ostd::Uint32 len = op >> 8;
result.cleanup(); result.cleanup();
--numargs; --numargs;
if (args[numargs].type == VAL_CODE) { if (args[numargs].get_type() == VAL_CODE) {
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];
@ -2867,7 +2867,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
case CODE_COMPILE: { case CODE_COMPILE: {
TaggedValue &arg = args[numargs - 1]; TaggedValue &arg = args[numargs - 1];
GenState gs(cs); GenState gs(cs);
switch (arg.type) { switch (arg.get_type()) {
case VAL_INT: case VAL_INT:
gs.code.reserve(8); gs.code.reserve(8);
gs.code.push(CODE_START); gs.code.push(CODE_START);
@ -2902,7 +2902,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
} }
case CODE_COND: { case CODE_COND: {
TaggedValue &arg = args[numargs - 1]; TaggedValue &arg = args[numargs - 1];
switch (arg.type) { switch (arg.get_type()) {
case VAL_STR: case VAL_STR:
case VAL_MACRO: case VAL_MACRO:
case VAL_CSTR: case VAL_CSTR:
@ -2932,7 +2932,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
} }
case CODE_IDENTU: { case CODE_IDENTU: {
TaggedValue &arg = args[numargs - 1]; TaggedValue &arg = args[numargs - 1];
Ident *id = arg.type == VAL_STR || arg.type == VAL_MACRO || arg.type == VAL_CSTR ? cs.new_ident(arg.cstr) : cs.dummy; Ident *id = arg.get_type() == VAL_STR || arg.get_type() == VAL_MACRO || arg.get_type() == VAL_CSTR ? cs.new_ident(arg.cstr) : cs.dummy;
if (id->index < MAX_ARGUMENTS && !(cs.stack->usedargs & (1 << id->index))) { if (id->index < MAX_ARGUMENTS && !(cs.stack->usedargs & (1 << id->index))) {
id->push_arg(null_value, cs.stack->argstack[id->index], false); id->push_arg(null_value, cs.stack->argstack[id->index], false);
cs.stack->usedargs |= 1 << id->index; cs.stack->usedargs |= 1 << id->index;
@ -2945,7 +2945,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
case CODE_LOOKUPU|RET_STR: case CODE_LOOKUPU|RET_STR:
#define LOOKUPU(aval, sval, ival, fval, nval) { \ #define LOOKUPU(aval, sval, ival, fval, nval) { \
TaggedValue &arg = args[numargs-1]; \ TaggedValue &arg = args[numargs-1]; \
if(arg.type != VAL_STR && arg.type != VAL_MACRO && arg.type != VAL_CSTR) continue; \ if(arg.get_type() != VAL_STR && arg.get_type() != VAL_MACRO && arg.get_type() != VAL_CSTR) continue; \
Ident *id = cs.idents.at(arg.s); \ Ident *id = cs.idents.at(arg.s); \
if(id) switch(id->type) \ if(id) switch(id->type) \
{ \ { \
@ -3254,7 +3254,7 @@ static const ostd::Uint32 *runcode(CsState &cs, const ostd::Uint32 *code, Tagged
case CODE_CALLU|RET_INT: { case CODE_CALLU|RET_INT: {
int callargs = op >> 8, offset = numargs - callargs; int callargs = op >> 8, offset = numargs - callargs;
TaggedValue &idarg = args[offset - 1]; TaggedValue &idarg = args[offset - 1];
if (idarg.type != VAL_STR && idarg.type != VAL_MACRO && idarg.type != VAL_CSTR) { if (idarg.get_type() != VAL_STR && idarg.get_type() != VAL_MACRO && idarg.get_type() != VAL_CSTR) {
litval: litval:
result.cleanup(); result.cleanup();
result = idarg; result = idarg;
@ -3387,7 +3387,7 @@ void CsState::run_ret(Ident *id, ostd::PointerRange<TaggedValue> args,
ostd::String CsState::run_str(const ostd::Uint32 *code) { ostd::String CsState::run_str(const ostd::Uint32 *code) {
TaggedValue result; TaggedValue result;
runcode(*this, code, result); runcode(*this, code, result);
if (result.type == VAL_NULL) return ostd::String(); if (result.get_type() == VAL_NULL) return ostd::String();
result.force_str(); result.force_str();
ostd::String ret(result.s); ostd::String ret(result.s);
delete[] result.s; delete[] result.s;
@ -3398,7 +3398,7 @@ ostd::String CsState::run_str(ostd::ConstCharRange code) {
TaggedValue result; TaggedValue result;
/* FIXME range */ /* FIXME range */
run_ret(code, result); run_ret(code, result);
if (result.type == VAL_NULL) return ostd::String(); if (result.get_type() == VAL_NULL) return ostd::String();
result.force_str(); result.force_str();
ostd::String ret(result.s); ostd::String ret(result.s);
delete[] result.s; delete[] result.s;
@ -3408,7 +3408,7 @@ ostd::String CsState::run_str(ostd::ConstCharRange code) {
ostd::String CsState::run_str(Ident *id, ostd::PointerRange<TaggedValue> args) { ostd::String CsState::run_str(Ident *id, ostd::PointerRange<TaggedValue> args) {
TaggedValue result; TaggedValue result;
run_ret(id, args, result); run_ret(id, args, result);
if (result.type == VAL_NULL) return nullptr; if (result.get_type() == VAL_NULL) return nullptr;
result.force_str(); result.force_str();
ostd::String ret(result.s); ostd::String ret(result.s);
delete[] result.s; delete[] result.s;
@ -3551,7 +3551,7 @@ void init_lib_base(CsState &cs) {
cs.add_command("result", "T", [](CsState &cs, TaggedValue *v) { cs.add_command("result", "T", [](CsState &cs, TaggedValue *v) {
*cs.result = *v; *cs.result = *v;
v->type = VAL_NULL; v->set_null();
}, ID_RESULT); }, ID_RESULT);
cs.add_command("!", "t", [](CsState &cs, TaggedValue *a) { cs.add_command("!", "t", [](CsState &cs, TaggedValue *a) {
@ -3564,7 +3564,7 @@ void init_lib_base(CsState &cs) {
cs.result->set_int(1); cs.result->set_int(1);
else for (int i = 0; i < numargs; ++i) { else for (int i = 0; i < numargs; ++i) {
if (i) cs.result->cleanup(); if (i) cs.result->cleanup();
if (args[i].type == VAL_CODE) if (args[i].get_type() == VAL_CODE)
cs.run_ret(args[i].code); cs.run_ret(args[i].code);
else else
*cs.result = args[i]; *cs.result = args[i];
@ -3578,7 +3578,7 @@ void init_lib_base(CsState &cs) {
cs.result->set_int(0); cs.result->set_int(0);
else for (int i = 0; i < numargs; ++i) { else for (int i = 0; i < numargs; ++i) {
if (i) cs.result->cleanup(); if (i) cs.result->cleanup();
if (args[i].type == VAL_CODE) if (args[i].get_type() == VAL_CODE)
cs.run_ret(args[i].code); cs.run_ret(args[i].code);
else else
*cs.result = args[i]; *cs.result = args[i];
@ -3620,15 +3620,15 @@ void init_lib_base(CsState &cs) {
}); });
CS_CMD_CASE("case", "i", int, args[0].get_int(), CS_CMD_CASE("case", "i", int, args[0].get_int(),
((args[i].type == VAL_NULL) || ((args[i].get_type() == VAL_NULL) ||
(args[i].get_int() == val))); (args[i].get_int() == val)));
CS_CMD_CASE("casef", "f", float, args[0].get_float(), CS_CMD_CASE("casef", "f", float, args[0].get_float(),
((args[i].type == VAL_NULL) || ((args[i].get_type() == VAL_NULL) ||
(args[i].get_float() == val))); (args[i].get_float() == val)));
CS_CMD_CASE("cases", "s", ostd::ConstCharRange, args[0].get_str(), CS_CMD_CASE("cases", "s", ostd::ConstCharRange, args[0].get_str(),
((args[i].type == VAL_NULL) || ((args[i].get_type() == VAL_NULL) ||
(args[i].get_str() == val))); (args[i].get_str() == val)));
#undef CS_CMD_CASE #undef CS_CMD_CASE
@ -3640,7 +3640,7 @@ void init_lib_base(CsState &cs) {
if (cs_get_bool(*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->set_null();
cs.run_ret(code); cs.run_ret(code);
id->pop_arg(); id->pop_arg();
} }
@ -4572,7 +4572,7 @@ void init_lib_math(CsState &cs) {
CS_CMD_MATH(#name "f", f, float, val = val op val2, initval, unaryop) CS_CMD_MATH(#name "f", f, float, val = val op val2, initval, unaryop)
#define CS_CMD_MATHF(name, initval, unaryop) \ #define CS_CMD_MATHF(name, initval, unaryop) \
CS_CMD_MATHIN(name, name, initval, unaryop) CS_CMD_MATHFN(name, name, initval, unaryop)
CS_CMD_MATHI(+, 0, {}); CS_CMD_MATHI(+, 0, {});
CS_CMD_MATHI(*, 1, {}); CS_CMD_MATHI(*, 1, {});

View File

@ -94,44 +94,46 @@ struct IdentValue {
}; };
struct TaggedValue: IdentValue { struct TaggedValue: IdentValue {
int type; int get_type() const {
return p_type;
}
void set_int(int val) { void set_int(int val) {
type = VAL_INT; p_type = VAL_INT;
i = val; i = val;
} }
void set_float(float val) { void set_float(float val) {
type = VAL_FLOAT; p_type = VAL_FLOAT;
f = val; f = val;
} }
void set_str(char *val) { void set_str(char *val) {
type = VAL_STR; p_type = VAL_STR;
s = val; s = val;
} }
void set_null() { void set_null() {
type = VAL_NULL; p_type = VAL_NULL;
i = 0; i = 0;
} }
void set_code(const ostd::Uint32 *val) { void set_code(const ostd::Uint32 *val) {
type = VAL_CODE; p_type = VAL_CODE;
code = val; code = val;
} }
void set_macro(const ostd::Uint32 *val) { void set_macro(const ostd::Uint32 *val) {
type = VAL_MACRO; p_type = VAL_MACRO;
code = val; code = val;
} }
void set_cstr(const char *val) { void set_cstr(const char *val) {
type = VAL_CSTR; p_type = VAL_CSTR;
cstr = val; cstr = val;
} }
void set_ident(Ident *val) { void set_ident(Ident *val) {
type = VAL_IDENT; p_type = VAL_IDENT;
id = val; id = val;
} }
void set(TaggedValue &tv) { void set(TaggedValue &tv) {
*this = tv; *this = tv;
tv.type = VAL_NULL; tv.p_type = VAL_NULL;
} }
ostd::ConstCharRange get_str() const; ostd::ConstCharRange get_str() const;
@ -146,6 +148,9 @@ struct TaggedValue: IdentValue {
void force(int type); void force(int type);
void cleanup(); void cleanup();
private:
int p_type;
}; };
struct IdentStack { struct IdentStack {
@ -229,7 +234,7 @@ struct Ident {
} }
void set_value(const TaggedValue &v) { void set_value(const TaggedValue &v) {
valtype = v.type; valtype = v.get_type();
val = v; val = v;
} }