#[crate::polydat_node(category = Arithmetic)]
fn u64_add(a: u64, b: u64) -> u64 { a.wrapping_add(b) }
#[crate::polydat_node(category = Arithmetic)]
fn u64_sub(a: u64, b: u64) -> u64 { a.wrapping_sub(b) }
#[crate::polydat_node(category = Arithmetic)]
fn u64_mul(a: u64, b: u64) -> u64 { a.wrapping_mul(b) }
#[crate::polydat_node(category = Arithmetic)]
fn u64_div(a: u64, b: u64) -> u64 { if b != 0 { a / b } else { 0 } }
#[crate::polydat_node(category = Arithmetic)]
fn u64_mod(a: u64, b: u64) -> u64 { if b != 0 { a % b } else { 0 } }
#[crate::polydat_node(category = Arithmetic)]
fn u64_and(a: u64, b: u64) -> u64 { a & b }
#[crate::polydat_node(category = Arithmetic)]
fn u64_or(a: u64, b: u64) -> u64 { a | b }
#[crate::polydat_node(category = Arithmetic)]
fn u64_xor(a: u64, b: u64) -> u64 { a ^ b }
#[crate::polydat_node(category = Arithmetic)]
fn u64_shl(a: u64, b: u64) -> u64 { a.wrapping_shl(b as u32) }
#[crate::polydat_node(category = Arithmetic)]
fn u64_shr(a: u64, b: u64) -> u64 { a.wrapping_shr(b as u32) }
#[crate::polydat_node(category = Arithmetic)]
fn u64_not(input: u64) -> u64 { !input }
#[crate::polydat_node(category = Arithmetic)]
fn checked_add(a: u64, b: u64) -> u64 { a.checked_add(b).unwrap_or(0) }
#[crate::polydat_node(category = Arithmetic)]
fn checked_sub(a: u64, b: u64) -> u64 { a.saturating_sub(b) }
#[crate::polydat_node(category = Arithmetic)]
fn checked_mul(a: u64, b: u64) -> u64 { a.checked_mul(b).unwrap_or(0) }
#[cfg(any())]
#[cfg(test)]
mod tests {
use super::*;
use crate::ast::{PolydatNode, Value};
#[test]
fn checked_add_normal() {
let node = CheckedAdd::new();
let mut out = [Value::None];
node.eval(&[Value::U64(100), Value::U64(42)], &mut out);
assert_eq!(out[0].as_u64(), 142);
}
#[test]
fn checked_add_overflow_returns_zero() {
let node = CheckedAdd::new();
let mut out = [Value::None];
node.eval(&[Value::U64(u64::MAX), Value::U64(1)], &mut out);
assert_eq!(out[0].as_u64(), 0);
}
#[test]
fn checked_sub_normal() {
let node = CheckedSub::new();
let mut out = [Value::None];
node.eval(&[Value::U64(42), Value::U64(10)], &mut out);
assert_eq!(out[0].as_u64(), 32);
}
#[test]
fn checked_sub_underflow_returns_zero() {
let node = CheckedSub::new();
let mut out = [Value::None];
node.eval(&[Value::U64(0), Value::U64(1)], &mut out);
assert_eq!(out[0].as_u64(), 0);
}
#[test]
fn checked_mul_normal() {
let node = CheckedMul::new();
let mut out = [Value::None];
node.eval(&[Value::U64(7), Value::U64(6)], &mut out);
assert_eq!(out[0].as_u64(), 42);
}
#[test]
fn checked_mul_overflow_returns_zero() {
let node = CheckedMul::new();
let mut out = [Value::None];
node.eval(&[Value::U64(u64::MAX), Value::U64(2)], &mut out);
assert_eq!(out[0].as_u64(), 0);
}
#[test]
fn u64_and_basic() {
let node = U64And::new();
let mut out = [Value::None];
node.eval(&[Value::U64(0xFF00), Value::U64(0x0FF0)], &mut out);
assert_eq!(out[0].as_u64(), 0x0F00);
}
#[test]
fn u64_or_basic() {
let node = U64Or::new();
let mut out = [Value::None];
node.eval(&[Value::U64(0xF0), Value::U64(0x0F)], &mut out);
assert_eq!(out[0].as_u64(), 0xFF);
}
#[test]
fn u64_xor_basic() {
let node = U64Xor::new();
let mut out = [Value::None];
node.eval(&[Value::U64(0xFF), Value::U64(0x0F)], &mut out);
assert_eq!(out[0].as_u64(), 0xF0);
}
#[test]
fn u64_shl_basic() {
let node = U64Shl::new();
let mut out = [Value::None];
node.eval(&[Value::U64(1), Value::U64(8)], &mut out);
assert_eq!(out[0].as_u64(), 256);
}
#[test]
fn u64_shr_basic() {
let node = U64Shr::new();
let mut out = [Value::None];
node.eval(&[Value::U64(256), Value::U64(4)], &mut out);
assert_eq!(out[0].as_u64(), 16);
}
#[test]
fn u64_not_basic() {
let node = U64Not::new();
let mut out = [Value::None];
node.eval(&[Value::U64(0)], &mut out);
assert_eq!(out[0].as_u64(), u64::MAX);
}
#[test]
fn u64_add2_wrapping() {
let node = U64Add::default();
let mut out = [Value::None];
node.eval(&[Value::U64(u64::MAX), Value::U64(1)], &mut out);
assert_eq!(out[0].as_u64(), 0);
}
#[test]
fn u64_div2_zero_divisor() {
let node = U64Div::default();
let mut out = [Value::None];
node.eval(&[Value::U64(42), Value::U64(0)], &mut out);
assert_eq!(out[0].as_u64(), 0);
}
#[test]
fn u64_sub2_wrapping() {
let node = U64Sub::default();
let mut out = [Value::None];
node.eval(&[Value::U64(0), Value::U64(1)], &mut out);
assert_eq!(out[0].as_u64(), u64::MAX);
}
#[test]
fn u64_mul2_basic() {
let node = U64Mul::default();
let mut out = [Value::None];
node.eval(&[Value::U64(7), Value::U64(6)], &mut out);
assert_eq!(out[0].as_u64(), 42);
}
#[test]
fn u64_mod2_basic() {
let node = U64Mod::default();
let mut out = [Value::None];
node.eval(&[Value::U64(42), Value::U64(10)], &mut out);
assert_eq!(out[0].as_u64(), 2);
}
#[test]
fn u64_mod2_zero_divisor() {
let node = U64Mod::default();
let mut out = [Value::None];
node.eval(&[Value::U64(42), Value::U64(0)], &mut out);
assert_eq!(out[0].as_u64(), 0);
}
}