iter.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #pragma once
  2. #include "cffi.h"
  3. #include "common.h"
  4. #include "frame.h"
  5. namespace pkpy{
  6. struct RangeIter{
  7. PY_CLASS(RangeIter, builtins, "_range_iterator")
  8. Range r;
  9. i64 current;
  10. RangeIter(Range r) : r(r), current(r.start) {}
  11. static void _register(VM* vm, PyObject* mod, PyObject* type){
  12. vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false;
  13. vm->bind_notimplemented_constructor<RangeIter>(type);
  14. vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; });
  15. vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
  16. RangeIter& self = _CAST(RangeIter&, obj);
  17. bool has_next = self.r.step > 0 ? self.current < self.r.stop : self.current > self.r.stop;
  18. if(!has_next) return vm->StopIteration;
  19. self.current += self.r.step;
  20. return VAR(self.current - self.r.step);
  21. });
  22. }
  23. };
  24. struct ArrayIter{
  25. PY_CLASS(ArrayIter, builtins, "_array_iterator")
  26. PyObject* ref;
  27. PyObject** begin;
  28. PyObject** end;
  29. PyObject** current;
  30. ArrayIter(PyObject* ref, PyObject** begin, PyObject** end)
  31. : ref(ref), begin(begin), end(end), current(begin) {}
  32. void _gc_mark() const{ OBJ_MARK(ref); }
  33. static void _register(VM* vm, PyObject* mod, PyObject* type){
  34. vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false;
  35. vm->bind_notimplemented_constructor<ArrayIter>(type);
  36. vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; });
  37. vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
  38. ArrayIter& self = _CAST(ArrayIter&, obj);
  39. if(self.current == self.end) return vm->StopIteration;
  40. return *self.current++;
  41. });
  42. }
  43. };
  44. struct StringIter{
  45. PY_CLASS(StringIter, builtins, "_string_iterator")
  46. PyObject* ref;
  47. Str* str;
  48. int index;
  49. StringIter(PyObject* ref) : ref(ref), str(&OBJ_GET(Str, ref)), index(0) {}
  50. void _gc_mark() const{ OBJ_MARK(ref); }
  51. static void _register(VM* vm, PyObject* mod, PyObject* type){
  52. vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false;
  53. vm->bind_notimplemented_constructor<StringIter>(type);
  54. vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; });
  55. vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
  56. StringIter& self = _CAST(StringIter&, obj);
  57. // TODO: optimize this... operator[] is of O(n) complexity
  58. if(self.index == self.str->u8_length()) return vm->StopIteration;
  59. return VAR(self.str->u8_getitem(self.index++));
  60. });
  61. }
  62. };
  63. struct Generator{
  64. PY_CLASS(Generator, builtins, "_generator")
  65. Frame frame;
  66. int state; // 0,1,2
  67. List s_backup;
  68. Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) {
  69. for(PyObject* obj: buffer) s_backup.push_back(obj);
  70. }
  71. void _gc_mark() const{
  72. frame._gc_mark();
  73. for(PyObject* obj: s_backup) OBJ_MARK(obj);
  74. }
  75. PyObject* next(VM* vm){
  76. if(state == 2) return vm->StopIteration;
  77. // reset frame._sp_base
  78. frame._sp_base = frame._s->_sp;
  79. frame._locals.a = frame._s->_sp;
  80. // restore the context
  81. for(PyObject* obj: s_backup) frame._s->push(obj);
  82. s_backup.clear();
  83. vm->callstack.push(std::move(frame));
  84. PyObject* ret = vm->_run_top_frame();
  85. if(ret == PY_OP_YIELD){
  86. // backup the context
  87. frame = std::move(vm->callstack.top());
  88. PyObject* ret = frame._s->popx();
  89. for(PyObject* obj: frame.stack_view()) s_backup.push_back(obj);
  90. vm->_pop_frame();
  91. state = 1;
  92. if(ret == vm->StopIteration) state = 2;
  93. return ret;
  94. }else{
  95. state = 2;
  96. return vm->StopIteration;
  97. }
  98. }
  99. static void _register(VM* vm, PyObject* mod, PyObject* type){
  100. vm->_all_types[OBJ_GET(Type, type)].subclass_enabled = false;
  101. vm->bind_notimplemented_constructor<Generator>(type);
  102. vm->bind__iter__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ return obj; });
  103. vm->bind__next__(OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
  104. Generator& self = _CAST(Generator&, obj);
  105. return self.next(vm);
  106. });
  107. }
  108. };
  109. inline PyObject* VM::_py_generator(Frame&& frame, ArgsView buffer){
  110. return VAR_T(Generator, std::move(frame), buffer);
  111. }
  112. } // namespace pkpy