瀏覽代碼

`CAST(f64, x)` accept `i64` now

BLUELOVETH 2 年之前
父節點
當前提交
4cb6241598
共有 4 個文件被更改,包括 31 次插入32 次删除
  1. 1 1
      include/pocketpy/obj.h
  2. 21 17
      include/pocketpy/vm.h
  3. 4 4
      src/linalg.cpp
  4. 5 10
      src/vm.cpp

+ 1 - 1
include/pocketpy/obj.h

@@ -223,7 +223,7 @@ __T _py_cast(VM* vm, PyObject* obj) {
 #define CAST(T, x) py_cast<T>(vm, x)
 #define CAST(T, x) py_cast<T>(vm, x)
 #define _CAST(T, x) _py_cast<T>(vm, x)
 #define _CAST(T, x) _py_cast<T>(vm, x)
 
 
-#define CAST_F(x) vm->num_to_float(x)
+#define CAST_F(x) py_cast<f64>(vm, x)
 #define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value)
 #define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value)
 
 
 /*****************************************************************/
 /*****************************************************************/

+ 21 - 17
include/pocketpy/vm.h

@@ -382,10 +382,7 @@ public:
         check_type(obj, tp_int);    // if failed, redirect to check_type to raise TypeError
         check_type(obj, tp_int);    // if failed, redirect to check_type to raise TypeError
     }
     }
 
 
-    void check_float(PyObject* obj){
-        if(is_float(obj)) return;
-        check_type(obj, tp_float);  // if failed, redirect to check_type to raise TypeError
-    }
+    void check_int_or_float(PyObject* obj);
 
 
     PyObject* _t(Type t){
     PyObject* _t(Type t){
         return _all_types[t.index].obj;
         return _all_types[t.index].obj;
@@ -433,7 +430,6 @@ public:
     PyObject* vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
     PyObject* vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
     CodeObject_ compile(Str source, Str filename, CompileMode mode, bool unknown_global_scope=false);
     CodeObject_ compile(Str source, Str filename, CompileMode mode, bool unknown_global_scope=false);
     PyObject* py_negate(PyObject* obj);
     PyObject* py_negate(PyObject* obj);
-    f64 num_to_float(PyObject* obj);
     bool py_bool(PyObject* obj);
     bool py_bool(PyObject* obj);
     i64 py_hash(PyObject* obj);
     i64 py_hash(PyObject* obj);
     PyObject* py_list(PyObject*);
     PyObject* py_list(PyObject*);
@@ -498,24 +494,32 @@ PY_CAST_INT(unsigned long)
 PY_CAST_INT(unsigned long long)
 PY_CAST_INT(unsigned long long)
 
 
 template<> inline float py_cast<float>(VM* vm, PyObject* obj){
 template<> inline float py_cast<float>(VM* vm, PyObject* obj){
-    vm->check_float(obj);
-    i64 bits = PK_BITS(obj) & Number::c1;
-    return BitsCvt(bits)._float;
+    if(is_float(obj)){
+        i64 bits = PK_BITS(obj) & Number::c1;
+        return BitsCvt(bits)._float;
+    }
+    if(is_int(obj)){
+        return (float)_py_cast<i64>(vm, obj);
+    }
+    vm->check_int_or_float(obj);       // error!
+    return 0;
 }
 }
 template<> inline float _py_cast<float>(VM* vm, PyObject* obj){
 template<> inline float _py_cast<float>(VM* vm, PyObject* obj){
-    PK_UNUSED(vm);
-    i64 bits = PK_BITS(obj) & Number::c1;
-    return BitsCvt(bits)._float;
+    return py_cast<float>(vm, obj);
 }
 }
 template<> inline double py_cast<double>(VM* vm, PyObject* obj){
 template<> inline double py_cast<double>(VM* vm, PyObject* obj){
-    vm->check_float(obj);
-    i64 bits = PK_BITS(obj) & Number::c1;
-    return BitsCvt(bits)._float;
+    if(is_float(obj)){
+        i64 bits = PK_BITS(obj) & Number::c1;
+        return BitsCvt(bits)._float;
+    }
+    if(is_int(obj)){
+        return (float)_py_cast<i64>(vm, obj);
+    }
+    vm->check_int_or_float(obj);       // error!
+    return 0;
 }
 }
 template<> inline double _py_cast<double>(VM* vm, PyObject* obj){
 template<> inline double _py_cast<double>(VM* vm, PyObject* obj){
-    PK_UNUSED(vm);
-    i64 bits = PK_BITS(obj) & Number::c1;
-    return BitsCvt(bits)._float;
+    return py_cast<double>(vm, obj);
 }
 }
 
 
 
 

+ 4 - 4
src/linalg.cpp

@@ -18,7 +18,7 @@ namespace pkpy{
 #define BIND_VEC_FLOAT_OP(D, name, op)  \
 #define BIND_VEC_FLOAT_OP(D, name, op)  \
         vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){          \
         vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){          \
             PyVec##D& self = _CAST(PyVec##D&, args[0]);                     \
             PyVec##D& self = _CAST(PyVec##D&, args[0]);                     \
-            f64 other = vm->num_to_float(args[1]);                          \
+            f64 other = CAST(f64, args[1]);                                 \
             return VAR(self op other);                                      \
             return VAR(self op other);                                      \
         });
         });
 
 
@@ -41,7 +41,7 @@ namespace pkpy{
             return VAR(self.name);                                          \
             return VAR(self.name);                                          \
         }, [](VM* vm, ArgsView args){                                       \
         }, [](VM* vm, ArgsView args){                                       \
             PyVec##D& self = _CAST(PyVec##D&, args[0]);                     \
             PyVec##D& self = _CAST(PyVec##D&, args[0]);                     \
-            self.name = vm->num_to_float(args[1]);                          \
+            self.name = CAST(f64, args[1]);                                 \
             return vm->None;                                                \
             return vm->None;                                                \
         }));
         }));
 
 
@@ -72,7 +72,7 @@ namespace pkpy{
 
 
         vm->bind_method<1>(type, "rotate", [](VM* vm, ArgsView args){
         vm->bind_method<1>(type, "rotate", [](VM* vm, ArgsView args){
             Vec2 self = _CAST(PyVec2&, args[0]);
             Vec2 self = _CAST(PyVec2&, args[0]);
-            float radian = vm->num_to_float(args[1]);
+            float radian = CAST(f64, args[1]);
             float cr = cosf(radian);
             float cr = cosf(radian);
             float sr = sinf(radian);
             float sr = sinf(radian);
             Mat3x3 rotate(cr,   -sr,  0.0f,
             Mat3x3 rotate(cr,   -sr,  0.0f,
@@ -289,7 +289,7 @@ namespace pkpy{
             return VAR(self.field);                                         \
             return VAR(self.field);                                         \
         }, [](VM* vm, ArgsView args){                                       \
         }, [](VM* vm, ArgsView args){                                       \
             PyMat3x3& self = _CAST(PyMat3x3&, args[0]);                     \
             PyMat3x3& self = _CAST(PyMat3x3&, args[0]);                     \
-            self.field = vm->num_to_float(args[1]);                         \
+            self.field = CAST(f64, args[1]);                                \
             return vm->None;                                                \
             return vm->None;                                                \
         }));
         }));
 
 

+ 5 - 10
src/vm.cpp

@@ -278,17 +278,12 @@ PyObject* VM::py_negate(PyObject* obj){
     return call_method(obj, __neg__);
     return call_method(obj, __neg__);
 }
 }
 
 
-f64 VM::num_to_float(PyObject* obj){
-    if(is_float(obj)){
-        return _CAST(f64, obj);
-    } else if (is_int(obj)){
-        return (f64)_CAST(i64, obj);
-    }
-    TypeError("expected 'int' or 'float', got " + OBJ_NAME(_t(obj)).escape());
-    return 0;
+void VM::check_int_or_float(PyObject *obj){
+    if(!is_tagged(obj)){
+        TypeError("expected 'int' or 'float', got " + OBJ_NAME(_t(obj)).escape());
+    }
 }
 }
 
 
-
 bool VM::py_bool(PyObject* obj){
 bool VM::py_bool(PyObject* obj){
     if(is_non_tagged_type(obj, tp_bool)) return obj == True;
     if(is_non_tagged_type(obj, tp_bool)) return obj == True;
     if(obj == None) return false;
     if(obj == None) return false;
@@ -416,7 +411,7 @@ PyObject* VM::format(Str spec, PyObject* obj){
     if(type != 'f' && dot >= 0) ValueError("precision not allowed in the format specifier");
     if(type != 'f' && dot >= 0) ValueError("precision not allowed in the format specifier");
     Str ret;
     Str ret;
     if(type == 'f'){
     if(type == 'f'){
-        f64 val = num_to_float(obj);
+        f64 val = CAST(f64, obj);
         if(precision < 0) precision = 6;
         if(precision < 0) precision = 6;
         std::stringstream ss;
         std::stringstream ss;
         ss << std::fixed << std::setprecision(precision) << val;
         ss << std::fixed << std::setprecision(precision) << val;