blueloveTH 2 лет назад
Родитель
Сommit
efb2385f3e
4 измененных файлов с 40 добавлено и 23 удалено
  1. 33 17
      src/common.h
  2. 2 2
      src/lexer.h
  3. 4 4
      src/pocketpy.h
  4. 1 0
      src/vm.h

+ 33 - 17
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<i64>(std::stoi(__VA_ARGS__))
-#define S_TO_FLOAT(...) static_cast<f64>(std::stof(__VA_ARGS__))
-#else
-typedef int64_t i64;
-typedef double f64;
-#define S_TO_INT(...) static_cast<i64>(std::stoll(__VA_ARGS__))
-#define S_TO_FLOAT(...) static_cast<f64>(std::stod(__VA_ARGS__))
-#endif
-
 namespace pkpy{
 
 namespace std = ::std;
 
+template <size_t T>
+struct NumberTraits;
+
+template <>
+struct NumberTraits<4> {
+	using int_t = int32_t;
+	using float_t = float;
+
+	template<typename... Args>
+	static int_t stoi(Args&&... args) { return std::stoi(std::forward<Args>(args)...); }
+	template<typename... Args>
+	static float_t stof(Args&&... args) { return std::stof(std::forward<Args>(args)...); }
+};
+
+template <>
+struct NumberTraits<8> {
+	using int_t = int64_t;
+	using float_t = double;
+
+	template<typename... Args>
+	static int_t stoi(Args&&... args) { return std::stoll(std::forward<Args>(args)...); }
+	template<typename... Args>
+	static float_t stof(Args&&... args) { return std::stod(std::forward<Args>(args)...); }
+};
+
+using Number = NumberTraits<sizeof(void*)>;
+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<f64>::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<float>::is_iec559);
-static_assert(std::numeric_limits<double>::is_iec559);
-
 struct PyObject;
 #define BITS(p) (reinterpret_cast<i64>(p))
 inline bool is_tagged(PyObject* p) noexcept { return (BITS(p) & 0b11) != 0b00; }

+ 2 - 2
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();
             }

+ 4 - 4
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*);

+ 1 - 0
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);