(&mut self, obj: Val, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val])
| 130 | } |
| 131 | |
| 132 | pub(crate) fn make_iter_frame(&mut self, obj: Val, chunk: &crate::modules::parser::SSAChunk, slots: &mut [Val]) -> Result<IterFrame, VmErr> { |
| 133 | if !obj.is_heap() { |
| 134 | return Err(VmErr::TypeMsg(s!("'", str self.type_name(obj), "' object is not iterable"))); |
| 135 | } |
| 136 | // Instance `__iter__` produces a user-defined iterator that drives `ForIter` via `__next__`. |
| 137 | if matches!(self.heap.get(obj), HeapObj::Instance(..)) |
| 138 | && let Some(iter) = self.try_call_dunder(obj, "__iter__", &[], chunk, slots)? { |
| 139 | return Ok(IterFrame::UserDefined(iter)); |
| 140 | } |
| 141 | Ok(match self.heap.get(obj) { |
| 142 | HeapObj::Range(s, e, st) => IterFrame::Range { cur: *s, end: *e, step: *st }, |
| 143 | HeapObj::List(v) => IterFrame::Seq { items: v.borrow().clone(), idx: 0 }, |
| 144 | HeapObj::Tuple(v) => IterFrame::Seq { items: v.clone(), idx: 0 }, |
| 145 | HeapObj::Dict(p) => IterFrame::Seq { items: p.borrow().keys().collect(), idx: 0 }, |
| 146 | HeapObj::Set(s) => { |
| 147 | let items: Vec<Val> = s.borrow().iter().cloned().collect(); |
| 148 | IterFrame::Seq { items, idx: 0 } |
| 149 | }, |
| 150 | HeapObj::FrozenSet(s) => { |
| 151 | let items: Vec<Val> = s.iter().cloned().collect(); |
| 152 | IterFrame::Seq { items, idx: 0 } |
| 153 | }, |
| 154 | HeapObj::Str(s) => { |
| 155 | let s = s.clone(); |
| 156 | let items = self.str_to_char_vals(&s)?; |
| 157 | IterFrame::Seq { items, idx: 0 } |
| 158 | }, |
| 159 | HeapObj::Bytes(b) => { |
| 160 | // Bytes iteration yields ints, matching `iter()` and indexing. |
| 161 | let items: Vec<Val> = b.iter().map(|&byte| Val::int(byte as i64)).collect(); |
| 162 | IterFrame::Seq { items, idx: 0 } |
| 163 | }, |
| 164 | HeapObj::Coroutine(..) => return Ok(IterFrame::Coroutine(obj)), |
| 165 | _ => return Err(VmErr::TypeMsg(s!("'", str self.type_name(obj), "' object is not iterable"))), |
| 166 | }) |
| 167 | } |
| 168 | |
| 169 | pub(crate) fn exec_unpack_seq(&mut self, expected: usize) -> Result<(), VmErr> { |
| 170 | let obj = self.pop()?; |
no test coverage detected