From f1039148b051a0c5bfe5289fa98b2ae5676fe840 Mon Sep 17 00:00:00 2001 From: q66 Date: Fri, 9 Sep 2016 17:43:23 +0200 Subject: [PATCH] allow for arbitrarily sized CsInt/CsFloat --- Makefile | 1 + src/cs_vm.cc | 8 +++- src/cs_vm.hh | 17 +++++-- src/cubescript.cc | 12 ++--- src/lib_list.cc | 8 ++-- src/lib_math.cc | 120 +++++++++++++++++++++++++++++++++++----------- src/lib_str.cc | 13 +++-- 7 files changed, 131 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 71d48b63..4fec8dd5 100644 --- a/Makefile +++ b/Makefile @@ -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_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_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_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 diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 9bbfbcd1..e42c79a2 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -741,15 +741,19 @@ static ostd::Uint32 *runcode(CsState &cs, ostd::Uint32 *code, CsValue &result) { args[numargs++].set_null(); continue; case CsCodeVal | CsRetInt: - args[numargs++].set_int(CsInt(*code++)); + args[numargs++].set_int( + *reinterpret_cast(code) + ); + code += CsTypeStorageSize; continue; case CsCodeValInt | CsRetInt: args[numargs++].set_int(CsInt(op) >> 8); continue; case CsCodeVal | CsRetFloat: args[numargs++].set_float( - *reinterpret_cast(code++) + *reinterpret_cast(code) ); + code += CsTypeStorageSize; continue; case CsCodeValInt | CsRetFloat: args[numargs++].set_float(CsFloat(CsInt(op) >> 8)); diff --git a/src/cs_vm.hh b/src/cs_vm.hh index aadc52a9..4e538187 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -82,6 +82,10 @@ enum { CsRetFloat = CsValFloat << CsCodeRet, }; +template +constexpr ostd::Size CsTypeStorageSize = + (sizeof(T) - 1) / sizeof(ostd::Uint32) + 1; + struct CsErrorException { CsString errmsg; CsErrorException() = delete; @@ -166,8 +170,13 @@ struct GenState { if (i >= -0x800000 && i <= 0x7FFFFF) { code.push(CsCodeValInt | CsRetInt | (i << 8)); } else { + union { + CsInt i; + ostd::Uint32 u[CsTypeStorageSize]; + } c; + c.i = i; code.push(CsCodeVal | CsRetInt); - code.push(i); + code.push_n(c.u, CsTypeStorageSize); } } @@ -179,11 +188,11 @@ struct GenState { } else { union { CsFloat f; - ostd::Uint32 u; + ostd::Uint32 u[CsTypeStorageSize]; } c; c.f = f; code.push(CsCodeVal | CsRetFloat); - code.push(c.u); + code.push_n(c.u, CsTypeStorageSize); } } @@ -221,7 +230,7 @@ struct GenState { } }; -CsString intstr(int v); +CsString intstr(CsInt v); CsString floatstr(CsFloat v); bool cs_check_num(ostd::ConstCharRange s); diff --git a/src/cubescript.cc b/src/cubescript.cc index 31ce3529..b15ec1ee 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -4,15 +4,15 @@ namespace cscript { CsString intstr(CsInt v) { - char buf[256]; - snprintf(buf, sizeof(buf), IntFormat, v); - return static_cast(buf); + auto app = ostd::appender(); + cscript::util::format_int(app, v); + return ostd::move(app.get()); } CsString floatstr(CsFloat v) { - char buf[256]; - snprintf(buf, sizeof(buf), v == CsInt(v) ? RoundFloatFormat : FloatFormat, v); - return static_cast(buf); + auto app = ostd::appender(); + cscript::util::format_float(app, v); + return ostd::move(app.get()); } bool cs_check_num(ostd::ConstCharRange s) { diff --git a/src/lib_list.cc b/src/lib_list.cc index 8856de2c..31529e8f 100644 --- a/src/lib_list.cc +++ b/src/lib_list.cc @@ -167,8 +167,8 @@ void cs_init_lib_list(CsState &cs) { count = args[2].get_int(), numargs = args[2].get_int(); - CsInt offset = ostd::max(skip, 0), - len = (numargs >= 3) ? ostd::max(count, 0) : -1; + CsInt offset = ostd::max(skip, CsInt(0)), + len = (numargs >= 3) ? ostd::max(count, CsInt(0)) : -1; util::ListParser p(args[0].get_strr()); 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) { - CsInt offset = ostd::max(args[2].get_int(), 0); - CsInt len = ostd::max(args[3].get_int(), 0); + CsInt offset = ostd::max(args[2].get_int(), CsInt(0)); + CsInt len = ostd::max(args[3].get_int(), CsInt(0)); ostd::ConstCharRange s = args[0].get_strr(); ostd::ConstCharRange vals = args[1].get_strr(); char const *list = s.data(); diff --git a/src/lib_math.cc b/src/lib_math.cc index d5be1877..8b5887ae 100644 --- a/src/lib_math.cc +++ b/src/lib_math.cc @@ -1,7 +1,8 @@ #include -#include -#include +/* c++ versions for overloaded math */ +#include +#include #include "cubescript/cubescript.hh" @@ -71,45 +72,110 @@ static inline void cs_cmpop(CsValueRange args, CsValue &res, F cmp) { 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) { 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { - 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) { @@ -142,29 +208,29 @@ void cs_init_lib_math(CsState &cs) { }); 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) { - 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) { - 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) { - 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) { - double step = args[1].get_float(); - double r = args[0].get_float(); + CsFloat step = args[1].get_float(); + CsFloat r = args[0].get_float(); if (step > 0) { r += step * ((r < 0) ? -0.5 : 0.5); - r -= fmod(r, step); + r -= cs_fmod(r, step); } 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) { @@ -244,7 +310,7 @@ void cs_init_lib_math(CsState &cs) { cs_mathop( args, res, 0, [](CsInt val1, CsInt val2) { return (val2 < CsInt(sizeof(CsInt) * CHAR_BIT)) - ? (val1 << ostd::max(val2, 0)) + ? (val1 << ostd::max(val2, CsInt(0))) : 0; }, CsMathNoop() ); @@ -253,7 +319,7 @@ void cs_init_lib_math(CsState &cs) { cs_mathop( args, res, 0, [](CsInt val1, CsInt val2) { return val1 >> ostd::clamp( - val2, 0, CsInt(sizeof(CsInt) * CHAR_BIT) + val2, CsInt(0), CsInt(sizeof(CsInt) * CHAR_BIT) ); }, CsMathNoop() ); @@ -281,7 +347,7 @@ void cs_init_lib_math(CsState &cs) { if (val2) { return val1 / val2; } - return 0; + return CsInt(0); }, CsMathNoop() ); }); @@ -291,7 +357,7 @@ void cs_init_lib_math(CsState &cs) { if (val2) { return val1 % val2; } - return 0; + return CsInt(0); }, CsMathNoop() ); }); diff --git a/src/lib_str.cc b/src/lib_str.cc index 2d94f313..689d507b 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -142,7 +142,8 @@ void cs_init_lib_string(CsState &cs) { cs.new_command("tohex", "ii", [](CsValueRange args, CsValue &res) { auto r = ostd::appender>(); 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'); ostd::Size len = r.size() - 1; @@ -153,10 +154,12 @@ void cs_init_lib_string(CsState &cs) { ostd::ConstCharRange s = args[0].get_strr(); CsInt start = args[1].get_int(), count = args[2].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( &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(); CsInt slen = CsInt(s.size()), vlen = CsInt(vals.size()); - CsInt offset = ostd::clamp(skip, 0, slen), - len = ostd::clamp(count, 0, slen - offset); + CsInt offset = ostd::clamp(skip, CsInt(0), slen), + len = ostd::clamp(count, CsInt(0), slen - offset); char *p = new char[slen - len + vlen + 1]; if (offset) { memcpy(p, s.data(), offset);