Next value; allocates only for StrChars. Err on alloc failure, Ok(None) on exhaustion.
(&mut self, heap: &mut HeapPool)
| 23 | impl IterCursor { |
| 24 | // Next value; allocates only for StrChars. Err on alloc failure, Ok(None) on exhaustion. |
| 25 | pub fn next(&mut self, heap: &mut HeapPool) -> Result<Option<Val>, VmErr> { |
| 26 | match self { |
| 27 | Self::Range { cur, end, step } => { |
| 28 | let (c, e, s) = (*cur, *end, *step); |
| 29 | let live = if s > 0 { c < e } else if s < 0 { c > e } else { false }; |
| 30 | if !live { return Ok(None); } |
| 31 | // Clamp past the i64 edge so the next call ends the range, never overflows. |
| 32 | *cur = c.checked_add(s).unwrap_or(if s > 0 { i64::MAX } else { i64::MIN }); |
| 33 | Ok(Some(range_int(heap, c)?)) |
| 34 | } |
| 35 | Self::Vec { items, idx } => { |
| 36 | if *idx >= items.len() { return Ok(None); } |
| 37 | let v = items[*idx]; |
| 38 | *idx += 1; |
| 39 | Ok(Some(v)) |
| 40 | } |
| 41 | Self::Bytes { bytes, idx } => { |
| 42 | if *idx >= bytes.len() { return Ok(None); } |
| 43 | let b = bytes[*idx]; |
| 44 | *idx += 1; |
| 45 | Ok(Some(Val::int(b as i64))) |
| 46 | } |
| 47 | Self::StrChars { chars, idx } => { |
| 48 | if *idx >= chars.len() { return Ok(None); } |
| 49 | let mut s = alloc::string::String::new(); |
| 50 | s.push(chars[*idx]); |
| 51 | *idx += 1; |
| 52 | Ok(Some(heap.alloc(HeapObj::Str(s))?)) |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | impl<'a> VM<'a> { |
no test coverage detected