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

Function fold_binop

compiler/src/modules/vm/optimizer.rs:264–321  ·  view source on GitHub ↗
(op: OpCode, a: Val, b: Val)

Source from the content-addressed store, hash-verified

262}
263
264fn fold_binop(op: OpCode, a: Val, b: Val) -> Option<Val> {
265 if matches!(op, OpCode::Eq | OpCode::NotEq | OpCode::Lt | OpCode::Gt | OpCode::LtEq | OpCode::GtEq) {
266 let (af, bf) = if a.is_int() && b.is_int() {
267 (a.as_int() as f64, b.as_int() as f64)
268 } else if (a.is_int() || a.is_float()) && (b.is_int() || b.is_float()) {
269 let af = if a.is_int() { a.as_int() as f64 } else { a.as_float() };
270 let bf = if b.is_int() { b.as_int() as f64 } else { b.as_float() };
271 (af, bf)
272 } else {
273 return None;
274 };
275 return Some(Val::bool(match op {
276 OpCode::Eq => af == bf,
277 OpCode::NotEq => af != bf,
278 OpCode::Lt => af < bf,
279 OpCode::Gt => af > bf,
280 OpCode::LtEq => af <= bf,
281 OpCode::GtEq => af >= bf,
282 _ => return None,
283 }));
284 }
285
286 if a.is_int() && b.is_int() {
287 let (ai, bi) = (a.as_int() as i128, b.as_int() as i128);
288 let r = match op {
289 OpCode::Add => ai.checked_add(bi)?,
290 OpCode::Sub => ai.checked_sub(bi)?,
291 OpCode::Mul => ai.checked_mul(bi)?,
292 // floored mod/div (sign follows divisor), not Euclidean; matches the runtime path.
293 OpCode::Mod => if bi == 0 { return None; } else { let r = ai % bi; if r != 0 && (r < 0) != (bi < 0) { r + bi } else { r } },
294 OpCode::FloorDiv => if bi == 0 { return None; } else { let q = ai / bi; let r = ai - q * bi; if r != 0 && (r < 0) != (bi < 0) { q - 1 } else { q } },
295 OpCode::BitAnd => ai & bi,
296 OpCode::BitOr => ai | bi,
297 OpCode::BitXor => ai ^ bi,
298 OpCode::Shl => if !(0..63).contains(&bi) { return None; } else { ai.checked_shl(bi as u32)? },
299 OpCode::Shr => if !(0..63).contains(&bi) { return None; } else { ai >> bi },
300 _ => return None,
301 };
302 if (Val::INT_MIN as i128..=Val::INT_MAX as i128).contains(&r) {
303 return Some(Val::int(r as i64));
304 }
305 return None;
306 }
307
308 if (a.is_int() || a.is_float()) && (b.is_int() || b.is_float()) {
309 let af = if a.is_int() { a.as_int() as f64 } else { a.as_float() };
310 let bf = if b.is_int() { b.as_int() as f64 } else { b.as_float() };
311 return Some(Val::float(match op {
312 OpCode::Add => af + bf,
313 OpCode::Sub => af - bf,
314 OpCode::Mul => af * bf,
315 OpCode::Div => if bf == 0.0 { return None; } else { af / bf },
316 _ => return None,
317 }));
318 }
319
320 None
321}

Callers 1

try_fold_binopFunction · 0.85

Calls 5

is_intMethod · 0.80
as_intMethod · 0.80
is_floatMethod · 0.80
as_floatMethod · 0.80
containsMethod · 0.45

Tested by

no test coverage detected