diff --git a/src/common.h b/src/common.h index 7b0101c0..7ce26c34 100644 --- a/src/common.h +++ b/src/common.h @@ -67,22 +67,43 @@ #endif -#if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__) -typedef int32_t i64; -typedef float f64; -#define S_TO_INT(...) static_cast(std::stoi(__VA_ARGS__)) -#define S_TO_FLOAT(...) static_cast(std::stof(__VA_ARGS__)) -#else -typedef int64_t i64; -typedef double f64; -#define S_TO_INT(...) static_cast(std::stoll(__VA_ARGS__)) -#define S_TO_FLOAT(...) static_cast(std::stod(__VA_ARGS__)) -#endif - namespace pkpy{ namespace std = ::std; +template +struct NumberTraits; + +template <> +struct NumberTraits<4> { + using int_t = int32_t; + using float_t = float; + + template + static int_t stoi(Args&&... args) { return std::stoi(std::forward(args)...); } + template + static float_t stof(Args&&... args) { return std::stof(std::forward(args)...); } +}; + +template <> +struct NumberTraits<8> { + using int_t = int64_t; + using float_t = double; + + template + static int_t stoi(Args&&... args) { return std::stoll(std::forward(args)...); } + template + static float_t stof(Args&&... args) { return std::stod(std::forward(args)...); } +}; + +using Number = NumberTraits; +using i64 = Number::int_t; +using f64 = Number::float_t; + +static_assert(sizeof(i64) == sizeof(void*)); +static_assert(sizeof(f64) == sizeof(void*)); +static_assert(std::numeric_limits::is_iec559); + struct Dummy { }; struct DummyInstance { }; struct DummyModule { }; @@ -110,11 +131,6 @@ struct Type { inline const float kInstAttrLoadFactor = 0.67f; inline const float kTypeAttrLoadFactor = 0.5f; -static_assert(sizeof(i64) == sizeof(int*)); -static_assert(sizeof(f64) == sizeof(int*)); -static_assert(std::numeric_limits::is_iec559); -static_assert(std::numeric_limits::is_iec559); - struct PyObject; #define BITS(p) (reinterpret_cast(p)) inline bool is_tagged(PyObject* p) noexcept { return (BITS(p) & 0b11) != 0b00; } diff --git a/src/lexer.h b/src/lexer.h index 11d17575..31b6c839 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -347,9 +347,9 @@ struct Lexer { if (m[1].matched) base = 16; if (m[2].matched) { if(base == 16) SyntaxError("hex literal should not contain a dot"); - add_token(TK("@num"), S_TO_FLOAT(m[0], &size)); + add_token(TK("@num"), Number::stof(m[0], &size)); } else { - add_token(TK("@num"), S_TO_INT(m[0], &size, base)); + add_token(TK("@num"), Number::stoi(m[0], &size, base)); } if (size != m.length()) FATAL_ERROR(); } diff --git a/src/pocketpy.h b/src/pocketpy.h index 4311600d..ee7a3999 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -246,7 +246,7 @@ inline void init_builtins(VM* _vm) { const Str& s = CAST(Str&, args[0]); try{ size_t parsed = 0; - i64 val = S_TO_INT(s.str(), &parsed, 10); + i64 val = Number::stoi(s.str(), &parsed, 10); if(parsed != s.length()) throw std::invalid_argument(""); return VAR(val); }catch(std::invalid_argument&){ @@ -293,7 +293,7 @@ inline void init_builtins(VM* _vm) { if(s == "inf") return VAR(INFINITY); if(s == "-inf") return VAR(-INFINITY); try{ - f64 val = S_TO_FLOAT(s.str()); + f64 val = Number::stof(s.str()); return VAR(val); }catch(std::invalid_argument&){ vm->ValueError("invalid literal for float(): '" + s + "'"); @@ -930,8 +930,8 @@ extern "C" { return strdup(ss.str().c_str()); } - typedef i64 (*f_int_t)(char*); - typedef f64 (*f_float_t)(char*); + typedef pkpy::i64 (*f_int_t)(char*); + typedef pkpy::f64 (*f_float_t)(char*); typedef bool (*f_bool_t)(char*); typedef char* (*f_str_t)(char*); typedef void (*f_None_t)(char*); diff --git a/src/vm.h b/src/vm.h index 37899ad4..34d05cdc 100644 --- a/src/vm.h +++ b/src/vm.h @@ -573,6 +573,7 @@ inline i64 VM::hash(PyObject* obj){ return x; } if (is_non_tagged_type(obj, tp_type)) return BITS(obj); + if (is_non_tagged_type(obj, tp_iterator)) return BITS(obj); if (is_non_tagged_type(obj, tp_bool)) return _CAST(bool, obj) ? 1 : 0; if (is_float(obj)){ f64 val = CAST(f64, obj);