allow for arbitrarily sized CsInt/CsFloat

master
Daniel Kolesa 2016-09-09 17:43:23 +02:00
parent 9b292188c8
commit f1039148b0
7 changed files with 131 additions and 48 deletions

View File

@ -40,6 +40,7 @@ src/cubescript.o: include/cubescript/cubescript.hh include/cubescript/cubescript
src/cs_gen.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_vm.hh src/cs_util.hh src/cs_gen.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_vm.hh src/cs_util.hh
src/cs_vm.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_vm.hh src/cs_util.hh src/cs_vm.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_vm.hh src/cs_util.hh
src/cs_val.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_vm.hh src/cs_util.hh src/cs_val.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_vm.hh src/cs_util.hh
src/cs_util.o: include/cubescript/cubescript_conf.hh src/cs_util.hh
src/lib_str.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/lib_str.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh
src/lib_math.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/lib_math.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh
src/lib_list.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_util.hh src/lib_list.o: include/cubescript/cubescript.hh include/cubescript/cubescript_conf.hh src/cs_util.hh

View File

@ -741,15 +741,19 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) {
args[numargs++].set_null(); args[numargs++].set_null();
continue; continue;
case CsCodeVal | CsRetInt: case CsCodeVal | CsRetInt:
args[numargs++].set_int(CsInt(*code++)); args[numargs++].set_int(
*reinterpret_cast<CsInt const *>(code)
);
code += CsTypeStorageSize<CsInt>;
continue; continue;
case CsCodeValInt | CsRetInt: case CsCodeValInt | CsRetInt:
args[numargs++].set_int(CsInt(op) >> 8); args[numargs++].set_int(CsInt(op) >> 8);
continue; continue;
case CsCodeVal | CsRetFloat: case CsCodeVal | CsRetFloat:
args[numargs++].set_float( args[numargs++].set_float(
*reinterpret_cast<CsFloat const *>(code++) *reinterpret_cast<CsFloat const *>(code)
); );
code += CsTypeStorageSize<CsFloat>;
continue; continue;
case CsCodeValInt | CsRetFloat: case CsCodeValInt | CsRetFloat:
args[numargs++].set_float(CsFloat(CsInt(op) >> 8)); args[numargs++].set_float(CsFloat(CsInt(op) >> 8));

View File

@ -82,6 +82,10 @@ enum {
CsRetFloat = CsValFloat << CsCodeRet, CsRetFloat = CsValFloat << CsCodeRet,
}; };
template<typename T>
constexpr ostd::Size CsTypeStorageSize =
(sizeof(T) - 1) / sizeof(ostd::Uint32) + 1;
struct CsErrorException { struct CsErrorException {
CsString errmsg; CsString errmsg;
CsErrorException() = delete; CsErrorException() = delete;
@ -166,8 +170,13 @@ struct GenState {
if (i >= -0x800000 && i <= 0x7FFFFF) { if (i >= -0x800000 && i <= 0x7FFFFF) {
code.push(CsCodeValInt | CsRetInt | (i << 8)); code.push(CsCodeValInt | CsRetInt | (i << 8));
} else { } else {
union {
CsInt i;
ostd::Uint32 u[CsTypeStorageSize<CsInt>];
} c;
c.i = i;
code.push(CsCodeVal | CsRetInt); code.push(CsCodeVal | CsRetInt);
code.push(i); code.push_n(c.u, CsTypeStorageSize<CsInt>);
} }
} }
@ -179,11 +188,11 @@ struct GenState {
} else { } else {
union { union {
CsFloat f; CsFloat f;
ostd::Uint32 u; ostd::Uint32 u[CsTypeStorageSize<CsFloat>];
} c; } c;
c.f = f; c.f = f;
code.push(CsCodeVal | CsRetFloat); code.push(CsCodeVal | CsRetFloat);
code.push(c.u); code.push_n(c.u, CsTypeStorageSize<CsFloat>);
} }
} }
@ -221,7 +230,7 @@ struct GenState {
} }
}; };
CsString intstr(int v); CsString intstr(CsInt v);
CsString floatstr(CsFloat v); CsString floatstr(CsFloat v);
bool cs_check_num(ostd::ConstCharRange s); bool cs_check_num(ostd::ConstCharRange s);

View File

@ -4,15 +4,15 @@
namespace cscript { namespace cscript {
CsString intstr(CsInt v) { CsString intstr(CsInt v) {
char buf[256]; auto app = ostd::appender<CsString>();
snprintf(buf, sizeof(buf), IntFormat, v); cscript::util::format_int(app, v);
return static_cast<char const *>(buf); return ostd::move(app.get());
} }
CsString floatstr(CsFloat v) { CsString floatstr(CsFloat v) {
char buf[256]; auto app = ostd::appender<CsString>();
snprintf(buf, sizeof(buf), v == CsInt(v) ? RoundFloatFormat : FloatFormat, v); cscript::util::format_float(app, v);
return static_cast<char const *>(buf); return ostd::move(app.get());
} }
bool cs_check_num(ostd::ConstCharRange s) { bool cs_check_num(ostd::ConstCharRange s) {

View File

@ -167,8 +167,8 @@ void cs_init_lib_list(CsState &cs) {
count = args[2].get_int(), count = args[2].get_int(),
numargs = args[2].get_int(); numargs = args[2].get_int();
CsInt offset = ostd::max(skip, 0), CsInt offset = ostd::max(skip, CsInt(0)),
len = (numargs >= 3) ? ostd::max(count, 0) : -1; len = (numargs >= 3) ? ostd::max(count, CsInt(0)) : -1;
util::ListParser p(args[0].get_strr()); util::ListParser p(args[0].get_strr());
for (CsInt i = 0; i < offset; ++i) { for (CsInt i = 0; i < offset; ++i) {
@ -442,8 +442,8 @@ void cs_init_lib_list(CsState &cs) {
}); });
cs.new_command("listsplice", "ssii", [](CsValueRange args, CsValue &res) { cs.new_command("listsplice", "ssii", [](CsValueRange args, CsValue &res) {
CsInt offset = ostd::max(args[2].get_int(), 0); CsInt offset = ostd::max(args[2].get_int(), CsInt(0));
CsInt len = ostd::max(args[3].get_int(), 0); CsInt len = ostd::max(args[3].get_int(), CsInt(0));
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
ostd::ConstCharRange vals = args[1].get_strr(); ostd::ConstCharRange vals = args[1].get_strr();
char const *list = s.data(); char const *list = s.data();

View File

@ -1,7 +1,8 @@
#include <limits.h> #include <limits.h>
#include <math.h>
#include <ostd/functional.hh> /* c++ versions for overloaded math */
#include <stdlib.h>
#include <math.h>
#include "cubescript/cubescript.hh" #include "cubescript/cubescript.hh"
@ -71,45 +72,110 @@ static inline void cs_cmpop(CsValueRange args, CsValue &res, F cmp) {
res.set_int(CsInt(val)); res.set_int(CsInt(val));
} }
/* overloads for various float types */
inline auto cs_sin(float f) { return sinf(f); }
inline auto cs_sin(double f) { return sin(f); }
inline auto cs_sin(long double f) { return sinl(f); }
inline auto cs_cos(float f) { return cosf(f); }
inline auto cs_cos(double f) { return cos(f); }
inline auto cs_cos(long double f) { return cosl(f); }
inline auto cs_tan(float f) { return tanf(f); }
inline auto cs_tan(double f) { return tan(f); }
inline auto cs_tan(long double f) { return tanl(f); }
inline auto cs_asin(float f) { return asinf(f); }
inline auto cs_asin(double f) { return asin(f); }
inline auto cs_asin(long double f) { return asinl(f); }
inline auto cs_acos(float f) { return acosf(f); }
inline auto cs_acos(double f) { return acos(f); }
inline auto cs_acos(long double f) { return acosl(f); }
inline auto cs_atan(float f) { return atanf(f); }
inline auto cs_atan(double f) { return atan(f); }
inline auto cs_atan(long double f) { return atanl(f); }
inline auto cs_atan2(float f, float f2) { return atan2f(f, f2); }
inline auto cs_atan2(double f, double f2) { return atan2(f, f2); }
inline auto cs_atan2(long double f, long double f2) { return atan2l(f, f2); }
inline auto cs_sqrt(float f) { return sqrtf(f); }
inline auto cs_sqrt(double f) { return sqrt(f); }
inline auto cs_sqrt(long double f) { return sqrtl(f); }
inline auto cs_log(float f) { return logf(f); }
inline auto cs_log(double f) { return log(f); }
inline auto cs_log(long double f) { return logl(f); }
inline auto cs_log10(float f) { return log10f(f); }
inline auto cs_log10(double f) { return log10(f); }
inline auto cs_log10(long double f) { return log10l(f); }
inline auto cs_exp(float f) { return expf(f); }
inline auto cs_exp(double f) { return exp(f); }
inline auto cs_exp(long double f) { return expl(f); }
inline int cs_abs(int i) { return abs(i); }
inline long cs_abs(long i) { return labs(i); }
inline long long cs_abs(long long i) { return llabs(i); }
inline auto cs_abs(float f) { return fabsf(f); }
inline auto cs_abs(double f) { return fabs(f); }
inline auto cs_abs(long double f) { return fabsl(f); }
inline auto cs_floor(float f) { return floorf(f); }
inline auto cs_floor(double f) { return floor(f); }
inline auto cs_floor(long double f) { return floorl(f); }
inline auto cs_ceil(float f) { return ceilf(f); }
inline auto cs_ceil(double f) { return ceil(f); }
inline auto cs_ceil(long double f) { return ceill(f); }
inline auto cs_fmod(float f, float f2) { return fmodf(f, f2); }
inline auto cs_fmod(double f, double f2) { return fmod(f, f2); }
inline auto cs_fmod(long double f, long double f2) { return fmodl(f, f2); }
void cs_init_lib_math(CsState &cs) { void cs_init_lib_math(CsState &cs) {
cs.new_command("sin", "f", [](CsValueRange args, CsValue &res) { cs.new_command("sin", "f", [](CsValueRange args, CsValue &res) {
res.set_float(sin(args[0].get_float() * RAD)); res.set_float(cs_sin(args[0].get_float() * RAD));
}); });
cs.new_command("cos", "f", [](CsValueRange args, CsValue &res) { cs.new_command("cos", "f", [](CsValueRange args, CsValue &res) {
res.set_float(cos(args[0].get_float() * RAD)); res.set_float(cs_cos(args[0].get_float() * RAD));
}); });
cs.new_command("tan", "f", [](CsValueRange args, CsValue &res) { cs.new_command("tan", "f", [](CsValueRange args, CsValue &res) {
res.set_float(tan(args[0].get_float() * RAD)); res.set_float(cs_tan(args[0].get_float() * RAD));
}); });
cs.new_command("asin", "f", [](CsValueRange args, CsValue &res) { cs.new_command("asin", "f", [](CsValueRange args, CsValue &res) {
res.set_float(asin(args[0].get_float()) / RAD); res.set_float(cs_asin(args[0].get_float()) / RAD);
}); });
cs.new_command("acos", "f", [](CsValueRange args, CsValue &res) { cs.new_command("acos", "f", [](CsValueRange args, CsValue &res) {
res.set_float(acos(args[0].get_float()) / RAD); res.set_float(cs_acos(args[0].get_float()) / RAD);
}); });
cs.new_command("atan", "f", [](CsValueRange args, CsValue &res) { cs.new_command("atan", "f", [](CsValueRange args, CsValue &res) {
res.set_float(atan(args[0].get_float()) / RAD); res.set_float(cs_atan(args[0].get_float()) / RAD);
}); });
cs.new_command("atan2", "ff", [](CsValueRange args, CsValue &res) { cs.new_command("atan2", "ff", [](CsValueRange args, CsValue &res) {
res.set_float(atan2(args[0].get_float(), args[1].get_float()) / RAD); res.set_float(cs_atan2(args[0].get_float(), args[1].get_float()) / RAD);
}); });
cs.new_command("sqrt", "f", [](CsValueRange args, CsValue &res) { cs.new_command("sqrt", "f", [](CsValueRange args, CsValue &res) {
res.set_float(sqrt(args[0].get_float())); res.set_float(cs_sqrt(args[0].get_float()));
}); });
cs.new_command("loge", "f", [](CsValueRange args, CsValue &res) { cs.new_command("loge", "f", [](CsValueRange args, CsValue &res) {
res.set_float(log(args[0].get_float())); res.set_float(cs_log(args[0].get_float()));
}); });
cs.new_command("log2", "f", [](CsValueRange args, CsValue &res) { cs.new_command("log2", "f", [](CsValueRange args, CsValue &res) {
res.set_float(log(args[0].get_float()) / M_LN2); res.set_float(cs_log(args[0].get_float()) / M_LN2);
}); });
cs.new_command("log10", "f", [](CsValueRange args, CsValue &res) { cs.new_command("log10", "f", [](CsValueRange args, CsValue &res) {
res.set_float(log10(args[0].get_float())); res.set_float(cs_log10(args[0].get_float()));
}); });
cs.new_command("exp", "f", [](CsValueRange args, CsValue &res) { cs.new_command("exp", "f", [](CsValueRange args, CsValue &res) {
res.set_float(exp(args[0].get_float())); res.set_float(cs_exp(args[0].get_float()));
}); });
cs.new_command("min", "i1V", [](CsValueRange args, CsValue &res) { cs.new_command("min", "i1V", [](CsValueRange args, CsValue &res) {
@ -142,29 +208,29 @@ void cs_init_lib_math(CsState &cs) {
}); });
cs.new_command("abs", "i", [](CsValueRange args, CsValue &res) { cs.new_command("abs", "i", [](CsValueRange args, CsValue &res) {
res.set_int(abs(args[0].get_int())); res.set_int(cs_abs(args[0].get_int()));
}); });
cs.new_command("absf", "f", [](CsValueRange args, CsValue &res) { cs.new_command("absf", "f", [](CsValueRange args, CsValue &res) {
res.set_float(fabs(args[0].get_float())); res.set_float(cs_abs(args[0].get_float()));
}); });
cs.new_command("floor", "f", [](CsValueRange args, CsValue &res) { cs.new_command("floor", "f", [](CsValueRange args, CsValue &res) {
res.set_float(floor(args[0].get_float())); res.set_float(cs_floor(args[0].get_float()));
}); });
cs.new_command("ceil", "f", [](CsValueRange args, CsValue &res) { cs.new_command("ceil", "f", [](CsValueRange args, CsValue &res) {
res.set_float(ceil(args[0].get_float())); res.set_float(cs_ceil(args[0].get_float()));
}); });
cs.new_command("round", "ff", [](CsValueRange args, CsValue &res) { cs.new_command("round", "ff", [](CsValueRange args, CsValue &res) {
double step = args[1].get_float(); CsFloat step = args[1].get_float();
double r = args[0].get_float(); CsFloat r = args[0].get_float();
if (step > 0) { if (step > 0) {
r += step * ((r < 0) ? -0.5 : 0.5); r += step * ((r < 0) ? -0.5 : 0.5);
r -= fmod(r, step); r -= cs_fmod(r, step);
} else { } else {
r = (r < 0) ? ceil(r - 0.5) : floor(r + 0.5); r = (r < 0) ? cs_ceil(r - 0.5) : cs_floor(r + 0.5);
} }
res.set_float(CsFloat(r)); res.set_float(r);
}); });
cs.new_command("+", "i1V", [](CsValueRange args, CsValue &res) { cs.new_command("+", "i1V", [](CsValueRange args, CsValue &res) {
@ -244,7 +310,7 @@ void cs_init_lib_math(CsState &cs) {
cs_mathop<CsInt>( cs_mathop<CsInt>(
args, res, 0, [](CsInt val1, CsInt val2) { args, res, 0, [](CsInt val1, CsInt val2) {
return (val2 < CsInt(sizeof(CsInt) * CHAR_BIT)) return (val2 < CsInt(sizeof(CsInt) * CHAR_BIT))
? (val1 << ostd::max(val2, 0)) ? (val1 << ostd::max(val2, CsInt(0)))
: 0; : 0;
}, CsMathNoop<CsInt>() }, CsMathNoop<CsInt>()
); );
@ -253,7 +319,7 @@ void cs_init_lib_math(CsState &cs) {
cs_mathop<CsInt>( cs_mathop<CsInt>(
args, res, 0, [](CsInt val1, CsInt val2) { args, res, 0, [](CsInt val1, CsInt val2) {
return val1 >> ostd::clamp( return val1 >> ostd::clamp(
val2, 0, CsInt(sizeof(CsInt) * CHAR_BIT) val2, CsInt(0), CsInt(sizeof(CsInt) * CHAR_BIT)
); );
}, CsMathNoop<CsInt>() }, CsMathNoop<CsInt>()
); );
@ -281,7 +347,7 @@ void cs_init_lib_math(CsState &cs) {
if (val2) { if (val2) {
return val1 / val2; return val1 / val2;
} }
return 0; return CsInt(0);
}, CsMathNoop<CsInt>() }, CsMathNoop<CsInt>()
); );
}); });
@ -291,7 +357,7 @@ void cs_init_lib_math(CsState &cs) {
if (val2) { if (val2) {
return val1 % val2; return val1 % val2;
} }
return 0; return CsInt(0);
}, CsMathNoop<CsInt>() }, CsMathNoop<CsInt>()
); );
}); });

View File

@ -142,7 +142,8 @@ void cs_init_lib_string(CsState &cs) {
cs.new_command("tohex", "ii", [](CsValueRange args, CsValue &res) { cs.new_command("tohex", "ii", [](CsValueRange args, CsValue &res) {
auto r = ostd::appender<CsVector<char>>(); auto r = ostd::appender<CsVector<char>>();
ostd::format( ostd::format(
r, "0x%.*X", ostd::max(args[1].get_int(), 1), args[0].get_int() r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)),
args[0].get_int()
); );
r.put('\0'); r.put('\0');
ostd::Size len = r.size() - 1; ostd::Size len = r.size() - 1;
@ -153,10 +154,12 @@ void cs_init_lib_string(CsState &cs) {
ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange s = args[0].get_strr();
CsInt start = args[1].get_int(), count = args[2].get_int(); CsInt start = args[1].get_int(), count = args[2].get_int();
CsInt numargs = args[3].get_int(); CsInt numargs = args[3].get_int();
CsInt len = CsInt(s.size()), offset = ostd::clamp(start, 0, len); CsInt len = CsInt(s.size()), offset = ostd::clamp(start, CsInt(0), len);
res.set_str(ostd::ConstCharRange( res.set_str(ostd::ConstCharRange(
&s[offset], &s[offset],
(numargs >= 3) ? ostd::clamp(count, 0, len - offset) : (len - offset) (numargs >= 3)
? ostd::clamp(count, CsInt(0), len - offset)
: (len - offset)
)); ));
}); });
@ -233,8 +236,8 @@ void cs_init_lib_string(CsState &cs) {
count = args[3].get_int(); count = args[3].get_int();
CsInt slen = CsInt(s.size()), CsInt slen = CsInt(s.size()),
vlen = CsInt(vals.size()); vlen = CsInt(vals.size());
CsInt offset = ostd::clamp(skip, 0, slen), CsInt offset = ostd::clamp(skip, CsInt(0), slen),
len = ostd::clamp(count, 0, slen - offset); len = ostd::clamp(count, CsInt(0), slen - offset);
char *p = new char[slen - len + vlen + 1]; char *p = new char[slen - len + vlen + 1];
if (offset) { if (offset) {
memcpy(p, s.data(), offset); memcpy(p, s.data(), offset);