blueloveTH 1 an în urmă
părinte
comite
bf5fe3d898
3 a modificat fișierele cu 23 adăugiri și 4 ștergeri
  1. 1 0
      include/pocketpy/pocketpy.h
  2. 6 0
      src/public/modules.c
  3. 16 4
      src/public/py_number.c

+ 1 - 0
include/pocketpy/pocketpy.h

@@ -385,6 +385,7 @@ void py_clearexc(py_StackRef p0);
 #define ValueError(...) py_exception(tp_ValueError, __VA_ARGS__)
 #define IndexError(...) py_exception(tp_IndexError, __VA_ARGS__)
 #define ImportError(...) py_exception(tp_ImportError, __VA_ARGS__)
+#define ZeroDivisionError(...) py_exception(tp_ZeroDivisionError, __VA_ARGS__)
 #define NotImplementedError() py_exception(tp_NotImplementedError, "")
 #define AttributeError(self, n)                                                                    \
     py_exception(tp_AttributeError, "'%t' object has no attribute '%n'", (self)->type, (n))

+ 6 - 0
src/public/modules.c

@@ -288,6 +288,11 @@ static bool builtins_sum(int argc, py_Ref argv) {
     return true;
 }
 
+static bool builtins_divmod(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(2);
+    return pk_callmagic(__divmod__, 2, argv);
+}
+
 static bool builtins_print(int argc, py_Ref argv) {
     int length;
     py_TValue* args = pk_arrayview(argv, &length);
@@ -443,6 +448,7 @@ py_TValue pk_builtins__register() {
     py_bindfunc(builtins, "hash", builtins_hash);
     py_bindfunc(builtins, "abs", builtins_abs);
     py_bindfunc(builtins, "sum", builtins_sum);
+    py_bindfunc(builtins, "divmod", builtins_divmod);
 
     py_bindfunc(builtins, "exec", builtins_exec);
     py_bindfunc(builtins, "eval", builtins_eval);

+ 16 - 4
src/public/py_number.c

@@ -83,8 +83,6 @@ static bool float__truediv__(int argc, py_Ref argv) {
     return true;
 }
 
-#define ZeroDivisionError(msg) false
-
 static bool number__pow__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(2);
     if(py_isint(&argv[0]) && py_isint(&argv[1])) {
@@ -124,7 +122,7 @@ static bool int__floordiv__(int argc, py_Ref argv) {
     py_i64 lhs = py_toint(&argv[0]);
     if(py_isint(&argv[1])) {
         py_i64 rhs = py_toint(&argv[1]);
-        if(rhs == 0) return -1;
+        if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero");
         py_newint(py_retval(), lhs / rhs);
     } else {
         py_newnotimplemented(py_retval());
@@ -145,6 +143,19 @@ static bool int__mod__(int argc, py_Ref argv) {
     return true;
 }
 
+static bool int__divmod__(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(2);
+    PY_CHECK_ARG_TYPE(1, tp_int);
+    py_i64 lhs = py_toint(&argv[0]);
+    py_i64 rhs = py_toint(&argv[1]);
+    if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero");
+    py_newtuple(py_retval(), 2);
+    ldiv_t res = ldiv(lhs, rhs);
+    py_newint(py_getslot(py_retval(), 0), res.quot);
+    py_newint(py_getslot(py_retval(), 1), res.rem);
+    return true;
+}
+
 static bool int__invert__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     py_i64 val = py_toint(&argv[0]);
@@ -459,9 +470,10 @@ void pk_number__register() {
     py_bindmagic(tp_int, __pow__, number__pow__);
     py_bindmagic(tp_float, __pow__, number__pow__);
 
-    // __floordiv__ & __mod__
+    // __floordiv__ & __mod__ & __divmod__
     py_bindmagic(tp_int, __floordiv__, int__floordiv__);
     py_bindmagic(tp_int, __mod__, int__mod__);
+    py_bindmagic(tp_int, __divmod__, int__divmod__);
 
     // int.__invert__ & int.<BITWISE OP>
     py_bindmagic(tp_int, __invert__, int__invert__);