iter.h 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #pragma once
  2. #include "ceval.h"
  3. class RangeIter : public BaseIter {
  4. i64 current;
  5. pkpy::Range r;
  6. public:
  7. RangeIter(VM* vm, PyVar _ref) : BaseIter(vm, _ref) {
  8. this->r = OBJ_GET(pkpy::Range, _ref);
  9. this->current = r.start;
  10. }
  11. inline bool _has_next(){
  12. return r.step > 0 ? current < r.stop : current > r.stop;
  13. }
  14. PyVar next(){
  15. if(!_has_next()) return nullptr;
  16. current += r.step;
  17. return vm->PyInt(current-r.step);
  18. }
  19. };
  20. template <typename T>
  21. class ArrayIter : public BaseIter {
  22. size_t index = 0;
  23. const T* p;
  24. public:
  25. ArrayIter(VM* vm, PyVar _ref) : BaseIter(vm, _ref) { p = &OBJ_GET(T, _ref);}
  26. PyVar next(){
  27. if(index == p->size()) return nullptr;
  28. return p->operator[](index++);
  29. }
  30. };
  31. class StringIter : public BaseIter {
  32. int index = 0;
  33. Str* str;
  34. public:
  35. StringIter(VM* vm, PyVar _ref) : BaseIter(vm, _ref) {
  36. str = &OBJ_GET(Str, _ref);
  37. }
  38. PyVar next() {
  39. if(index == str->u8_length()) return nullptr;
  40. return vm->PyStr(str->u8_getitem(index++));
  41. }
  42. };
  43. class Generator: public BaseIter {
  44. std::unique_ptr<Frame> frame;
  45. int state; // 0,1,2
  46. public:
  47. Generator(VM* vm, std::unique_ptr<Frame>&& frame)
  48. : BaseIter(vm, nullptr), frame(std::move(frame)), state(0) {}
  49. PyVar next() {
  50. if(state == 2) return nullptr;
  51. vm->callstack.push(std::move(frame));
  52. PyVar ret = vm->_exec();
  53. if(ret == vm->_py_op_yield){
  54. frame = std::move(vm->callstack.top());
  55. vm->callstack.pop();
  56. state = 1;
  57. return frame->pop_value(vm);
  58. }else{
  59. state = 2;
  60. return nullptr;
  61. }
  62. }
  63. };