Sfoglia il codice sorgente

add `ZeroDivisionError`

blueloveTH 2 anni fa
parent
commit
e9b2060276
4 ha cambiato i file con 43 aggiunte e 2 eliminazioni
  1. 0 1
      docs/features/ub.md
  2. 3 0
      src/ceval.cpp
  3. 3 0
      src/pocketpy.cpp
  4. 37 1
      tests/01_int.py

+ 0 - 1
docs/features/ub.md

@@ -11,4 +11,3 @@ These are the undefined behaviours of pkpy. The behaviour of pkpy is undefined i
 4. Type `T`'s `__new__` returns an object that is not an instance of `T`.
 5. Call `__new__` with a type that is not a subclass of `type`.
 6. `__eq__`, `__lt__` or `__contains__`, etc.. returns a value that is not a boolean.
-7. Division by zero.

+ 3 - 0
src/ceval.cpp

@@ -330,6 +330,9 @@ __NEXT_STEP:;
     if(is_small_int(TOP()) && is_small_int(SECOND())){  \
         _1 = POPX();                                    \
         _0 = TOP();                                     \
+        if constexpr(#op[0] == '/' || #op[0] == '%'){   \
+            if(_py_sint(_1) == 0) ZeroDivisionError();  \
+        }                                               \
         TOP() = VAR(_py_sint(_0) op _py_sint(_1));      \
         DISPATCH();                                     \
     }

+ 3 - 0
src/pocketpy.cpp

@@ -225,6 +225,7 @@ void init_builtins(VM* _vm) {
         if(is_int(args[0])){
             i64 lhs = _CAST(i64, args[0]);
             i64 rhs = CAST(i64, args[1]);
+            if(rhs == 0) vm->ZeroDivisionError();
             auto res = std::div(lhs, rhs);
             return VAR(Tuple({VAR(res.quot), VAR(res.rem)}));
         }else{
@@ -442,11 +443,13 @@ void init_builtins(VM* _vm) {
 
     _vm->bind__floordiv__(_vm->tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
         i64 rhs = CAST(i64, rhs_);
+        if(rhs == 0) vm->ZeroDivisionError();
         return VAR(_CAST(i64, lhs_) / rhs);
     });
 
     _vm->bind__mod__(_vm->tp_int, [](VM* vm, PyObject* lhs_, PyObject* rhs_) {
         i64 rhs = CAST(i64, rhs_);
+        if(rhs == 0) vm->ZeroDivisionError();
         return VAR(_CAST(i64, lhs_) % rhs);
     });
 

+ 37 - 1
tests/01_int.py

@@ -62,4 +62,40 @@ assert (-4)**13 == -67108864
 
 assert ~3 == -4
 assert ~-3 == 2
-assert ~0 == -1
+assert ~0 == -1
+
+try:
+    1 // 0
+    exit(1)
+except ZeroDivisionError:
+    pass
+
+try:
+    1 % 0
+    exit(1)
+except ZeroDivisionError:
+    pass
+
+try:
+    2**60 // 0
+    exit(1)
+except ZeroDivisionError:
+    pass
+
+try:
+    2**60 % 0
+    exit(1)
+except ZeroDivisionError:
+    pass
+
+try:
+    divmod(1, 0)
+    exit(1)
+except ZeroDivisionError:
+    pass
+
+try:
+    divmod(2**60, 0)
+    exit(1)
+except ZeroDivisionError:
+    pass