iter.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "pocketpy/interpreter/iter.hpp"
  2. namespace pkpy {
  3. void RangeIter::_register(VM* vm, PyObject* mod, PyObject* type) {
  4. vm->bind__iter__(type->as<Type>(), [](VM* vm, PyVar _0) {
  5. return _0;
  6. });
  7. vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
  8. RangeIter& self = PK_OBJ_GET(RangeIter, _0);
  9. if(self.current >= self.r.stop) return 0;
  10. vm->s_data.emplace(VM::tp_int, self.current);
  11. self.current += self.r.step;
  12. return 1;
  13. });
  14. }
  15. void RangeIterR::_register(VM* vm, PyObject* mod, PyObject* type) {
  16. vm->bind__iter__(type->as<Type>(), [](VM* vm, PyVar _0) {
  17. return _0;
  18. });
  19. vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
  20. RangeIterR& self = PK_OBJ_GET(RangeIterR, _0);
  21. if(self.current <= self.r.stop) return 0;
  22. vm->s_data.emplace(VM::tp_int, self.current);
  23. self.current += self.r.step;
  24. return 1;
  25. });
  26. }
  27. void ArrayIter::_register(VM* vm, PyObject* mod, PyObject* type) {
  28. vm->bind__iter__(type->as<Type>(), [](VM* vm, PyVar _0) {
  29. return _0;
  30. });
  31. vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
  32. ArrayIter& self = _CAST(ArrayIter&, _0);
  33. if(self.current == self.end) return 0;
  34. vm->s_data.push(*self.current++);
  35. return 1;
  36. });
  37. }
  38. void StringIter::_register(VM* vm, PyObject* mod, PyObject* type) {
  39. vm->bind__iter__(type->as<Type>(), [](VM* vm, PyVar _0) {
  40. return _0;
  41. });
  42. vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
  43. StringIter& self = _CAST(StringIter&, _0);
  44. Str& s = PK_OBJ_GET(Str, self.ref);
  45. if(self.i == s.size) return 0;
  46. int start = self.i;
  47. int len = c11__u8_header(s[self.i], false);
  48. self.i += len;
  49. vm->s_data.push(VAR(s.slice(start, self.i)));
  50. return 1;
  51. });
  52. }
  53. PyVar Generator::next(VM* vm) {
  54. if(state == 2) return vm->StopIteration;
  55. // reset frame._sp_base
  56. lf->frame._sp_base = vm->s_data._sp;
  57. lf->frame._locals.a = vm->s_data._sp;
  58. // restore the context
  59. for(PyVar obj: s_backup)
  60. vm->s_data.push(obj);
  61. s_backup.clear();
  62. vm->callstack.pushx(lf);
  63. lf = nullptr;
  64. PyVar ret;
  65. try {
  66. ret = vm->__run_top_frame();
  67. } catch(...) {
  68. state = 2; // end this generator immediately when an exception is thrown
  69. throw;
  70. }
  71. if(ret == PY_OP_YIELD) {
  72. // backup the context
  73. lf = vm->callstack.popx();
  74. ret = vm->s_data.popx();
  75. for(PyVar obj: lf->frame.stack_view(&vm->s_data))
  76. s_backup.push_back(obj);
  77. vm->s_data.reset(lf->frame._sp_base);
  78. // TODO: should we add this snippet here?
  79. // #if PK_ENABLE_PROFILER
  80. // if(!_next_breakpoint.empty() && callstack.size()<_next_breakpoint.callstack_size){
  81. // _next_breakpoint = NextBreakpoint();
  82. // }
  83. // #endif
  84. state = 1;
  85. if(ret == vm->StopIteration) state = 2;
  86. return ret;
  87. } else {
  88. state = 2;
  89. return vm->StopIteration;
  90. }
  91. }
  92. void Generator::_register(VM* vm, PyObject* mod, PyObject* type) {
  93. vm->bind__iter__(type->as<Type>(), [](VM* vm, PyVar _0) {
  94. return _0;
  95. });
  96. vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
  97. Generator& self = _CAST(Generator&, _0);
  98. PyVar retval = self.next(vm);
  99. if(retval == vm->StopIteration) return 0;
  100. vm->s_data.push(retval);
  101. return 1;
  102. });
  103. }
  104. void DictItemsIter::_register(VM* vm, PyObject* mod, PyObject* type) {
  105. vm->bind__iter__(type->as<Type>(), [](VM* vm, PyVar _0) {
  106. return _0;
  107. });
  108. vm->bind__next__(type->as<Type>(), [](VM* vm, PyVar _0) -> unsigned {
  109. DictItemsIter& self = _CAST(DictItemsIter&, _0);
  110. PyVar key, val;
  111. if (pkpy_DictIter__next(&self.it, (PyVar*)(&key), (PyVar*)(&val))) {
  112. vm->s_data.push(key);
  113. vm->s_data.push(val);
  114. return 2;
  115. }
  116. return 0;
  117. });
  118. }
  119. PyVar VM::__py_generator(LinkedFrame* frame, ArgsView buffer) {
  120. return vm->new_user_object<Generator>(std::move(frame), buffer);
  121. }
  122. } // namespace pkpy