Browse Source

re-checking (#531)

thermalPasteMilkshake 1 month ago
parent
commit
e144785436

+ 1 - 0
include/pocketpy/interpreter/vm.h

@@ -133,6 +133,7 @@ void pk_number__register();
 py_Type pk_str__register();
 py_Type pk_str_iterator__register();
 py_Type pk_bytes__register();
+py_Type pk_bytes_iterator__register();
 py_Type pk_dict__register();
 py_Type pk_dict_items__register();
 py_Type pk_list__register();

+ 1 - 0
include/pocketpy/pocketpy.h

@@ -843,6 +843,7 @@ enum py_PredefinedType {
     tp_BaseException,
     tp_Exception,
     tp_bytes,
+    tp_bytes_iterator,
     tp_namedict,
     tp_locals,
     tp_code,

+ 40 - 0
src/bindings/py_str.c

@@ -817,6 +817,44 @@ static bool bytes__len__(int argc, py_Ref argv) {
     return true;
 }
 
+
+static bool bytes__iter__(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(1);
+    int* ud = py_newobject(py_retval(), tp_bytes_iterator, 1, sizeof(int));
+    *ud = 0;
+    py_setslot(py_retval(), 0, argv);  
+    return true;
+}
+
+bool bytes_iterator__next__(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(1);
+
+    int* index = py_touserdata(&argv[0]);
+
+    int size;
+    unsigned char* data =
+        py_tobytes(py_getslot(argv,0), &size);
+
+    if(*index == size)
+        return StopIteration();
+
+    py_newint(py_retval(), data[*index]);
+    (*index)++;
+
+    return true;
+}
+
+py_Type pk_bytes_iterator__register() {
+    py_Type type =
+        pk_newtype("bytes_iterator", tp_object, NULL, NULL, false, true);
+
+    py_bindmagic(type, __iter__, pk_wrapper__self);
+    py_bindmagic(type, __next__, bytes_iterator__next__);
+
+    return type;
+}
+
+
 py_Type pk_bytes__register() {
     py_Type type = pk_newtype("bytes", tp_object, NULL, NULL, false, true);
     // no need to dtor because the memory is controlled by the object
@@ -829,6 +867,8 @@ py_Type pk_bytes__register() {
     py_bindmagic(tp_bytes, __add__, bytes__add__);
     py_bindmagic(tp_bytes, __hash__, bytes__hash__);
     py_bindmagic(tp_bytes, __len__, bytes__len__);
+    py_bindmagic(tp_bytes, __iter__, bytes__iter__);
+
 
     py_bindmethod(tp_bytes, "decode", bytes_decode);
     return type;

+ 1 - 0
src/interpreter/vm.c

@@ -156,6 +156,7 @@ void VM__ctor(VM* self) {
     validate(tp_BaseException, pk_BaseException__register());
     validate(tp_Exception, pk_Exception__register());
     validate(tp_bytes, pk_bytes__register());
+    validate(tp_bytes_iterator, pk_bytes_iterator__register());
     validate(tp_namedict, pk_namedict__register());
     validate(tp_locals, pk_newtype("locals", tp_object, NULL, NULL, false, true));
     validate(tp_code, pk_code__register());

+ 29 - 1
tests/460_bytes.py

@@ -40,4 +40,32 @@ assert a[5:2:-2] == b",l"
 
 assert bytes() == b''
 assert bytes((65,)) == b'A'
-assert bytes([0, 1, 2, 3]) == b'\x00\x01\x02\x03'
+assert bytes([0, 1, 2, 3]) == b'\x00\x01\x02\x03'
+
+# bytes iterators testing
+assert list(b"abc") == [97, 98, 99]
+
+text = "\x01\x02\x03"
+byteStr = text.encode()
+assert byteStr == b'\x01\x02\x03'
+assert list(byteStr) == [1, 2, 3]
+
+total = 0
+for x in byteStr:
+    total += x
+
+assert total == sum(byteStr)
+
+a = iter(byteStr)
+
+assert iter(a) is a
+
+assert next(a) == 1
+assert next(a) == 2
+assert next(a) == 3
+
+try:
+    next(a)
+    exit(1)
+except StopIteration:
+    pass