MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / store_slice

Method store_slice

compiler/src/modules/vm/builtins/index.rs:273–318  ·  view source on GitHub ↗

Splice for `xs[a:b] = items` and `del xs[a:b]`. step=1 resizes; step≠1 demands exact-length RHS. Lists only, tuples/strings are immutable. */

(&mut self, cont: Val,start: Val, stop: Val, step: Val, new_items: Vec<Val>)

Source from the content-addressed store, hash-verified

271
272 /* Splice for `xs[a:b] = items` and `del xs[a:b]`. step=1 resizes; step≠1 demands exact-length RHS. Lists only, tuples/strings are immutable. */
273 fn store_slice(&mut self, cont: Val,start: Val, stop: Val, step: Val, new_items: Vec<Val>) -> Result<(), VmErr> {
274 let st = if step.is_none() { 1 }
275 else if step.is_int() { step.as_int() }
276 else { return Err(cold_type("slice step must be an integer")); };
277 if st == 0 { return Err(cold_value("slice step cannot be zero")); }
278
279 let HeapObj::List(rc) = self.heap.get_mut(cont) else {
280 return Err(cold_type("object does not support slice assignment"));
281 };
282 let mut b = rc.borrow_mut();
283 let len = b.len() as i64;
284
285 let clamp = |v: Val, def: i64| -> i64 {
286 if v.is_none() { def }
287 else if v.is_int() { let i = v.as_int(); if i < 0 { (len + i).max(0) } else { i.min(len) } }
288 else { def }
289 };
290
291 if st == 1 {
292 let s = clamp(start, 0).max(0) as usize;
293 let e = clamp(stop, len).max(s as i64) as usize;
294 b.splice(s..e, new_items);
295 return Ok(());
296 }
297
298 // Extended slice (step!=1): collect indices; RHS length must match exactly.
299 // Negative-step start caps at len-1; clamp's min(len) alone would yield an out-of-range len.
300 let (s, e) = if st > 0 { (clamp(start, 0), clamp(stop, len)) } else { (clamp(start, len - 1).min(len - 1), clamp(stop, -1)) };
301 let mut indices: Vec<usize> = Vec::new();
302 let mut cur = s;
303 if st > 0 { while cur < e { indices.push(cur as usize); cur += st; } }
304 else { while cur > e { indices.push(cur as usize); cur += st; } }
305
306 if new_items.is_empty() {
307 // Remove highest-index first so earlier indices stay valid.
308 let mut sorted = indices.clone();
309 sorted.sort_unstable();
310 for &i in sorted.iter().rev() { b.remove(i); }
311 return Ok(());
312 }
313 if new_items.len() != indices.len() {
314 return Err(cold_value("attempt to assign sequence of one size to extended slice of another"));
315 }
316 for (i, v) in indices.into_iter().zip(new_items) { b[i] = v; }
317 Ok(())
318 }
319
320 // `slice(stop)` | `slice(start, stop)` | `slice(start, stop, step)`, builtin; usable as a sequence index.
321 pub fn call_slice(&mut self, argc: u16) -> Result<(), VmErr> {

Callers 2

store_item_builtinMethod · 0.80
del_itemMethod · 0.80

Calls 11

cold_typeFunction · 0.85
cold_valueFunction · 0.85
is_noneMethod · 0.80
is_intMethod · 0.80
as_intMethod · 0.80
get_mutMethod · 0.80
pushMethod · 0.80
removeMethod · 0.80
lenMethod · 0.45
is_emptyMethod · 0.45
iterMethod · 0.45

Tested by

no test coverage detected