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

Method add_vals

compiler/src/modules/vm/ops.rs:436–477  ·  view source on GitHub ↗
(&mut self, a: Val, b: Val)

Source from the content-addressed store, hash-verified

434 Err(VmErr::TypeMsg(s!("argument of type '", str self.type_name(container), "' is not iterable")))
435 }
436 pub fn add_vals(&mut self, a: Val, b: Val) -> Result<Val, VmErr> {
437 // Inline-int fast path; overflow falls through to the i128 slow path.
438 if a.is_int() && b.is_int()
439 && let Some(r) = a.as_int().checked_add(b.as_int())
440 && (Val::INT_MIN..=Val::INT_MAX).contains(&r) {
441 return Ok(Val::int(r));
442 }
443 if let Some((af, bf)) = coerce_floats(a, b, &self.heap) { return Ok(Val::float(af + bf)); }
444 // Wide-int slow path; int_to_val picks the narrowest storage class.
445 if let (Some(ai), Some(bi)) = (as_i128(a, &self.heap), as_i128(b, &self.heap)) {
446 return self.int_to_val(ai.checked_add(bi));
447 }
448 if a.is_heap() && b.is_heap() {
449 // Charge the copy cost so growing concatenation in a loop stays bounded (avoids O(n^2)).
450 let copy_cost = match (self.heap.get(a), self.heap.get(b)) {
451 (HeapObj::Str(sa), HeapObj::Str(sb)) => Some(sa.len() + sb.len()),
452 (HeapObj::List(va), HeapObj::List(vb)) => Some(va.borrow().len() + vb.borrow().len()),
453 (HeapObj::Tuple(va), HeapObj::Tuple(vb)) => Some(va.len() + vb.len()),
454 _ => None,
455 };
456 if let Some(n) = copy_cost { self.charge_steps(n)?; }
457 match (self.heap.get(a), self.heap.get(b)) {
458 (HeapObj::Str(sa), HeapObj::Str(sb)) => {
459 let sa = sa.clone();
460 let sb = sb.clone();
461 let mut r = String::with_capacity(sa.len() + sb.len());
462 r.push_str(&sa); r.push_str(&sb);
463 return self.heap.alloc(HeapObj::Str(r));
464 }
465 (HeapObj::List(va), HeapObj::List(vb)) => {
466 let mut lst = va.borrow().clone(); lst.extend_from_slice(&vb.borrow());
467 return self.heap.alloc(HeapObj::List(Rc::new(RefCell::new(lst))));
468 }
469 (HeapObj::Tuple(va), HeapObj::Tuple(vb)) => {
470 let mut tup = va.clone(); tup.extend_from_slice(vb);
471 return self.heap.alloc(HeapObj::Tuple(tup));
472 }
473 _ => {}
474 }
475 }
476 Err(VmErr::TypeMsg(s!("unsupported operand type(s) for +: '", str self.type_name(a), "' and '", str self.type_name(b), "'")))
477 }
478
479 pub fn sub_vals(&mut self, a: Val, b: Val) -> Result<Val, VmErr> {
480 if a.is_int() && b.is_int()

Callers 2

handle_arithMethod · 0.80
call_sumMethod · 0.80

Calls 12

coerce_floatsFunction · 0.85
as_i128Function · 0.85
is_intMethod · 0.80
as_intMethod · 0.80
int_to_valMethod · 0.80
is_heapMethod · 0.80
borrowMethod · 0.80
charge_stepsMethod · 0.80
containsMethod · 0.45
getMethod · 0.45
lenMethod · 0.45
allocMethod · 0.45

Tested by

no test coverage detected