synthphonia/expr/ops/
int.rs

1
2use std::cmp::min;
3use std::ops::Not;
4
5use derive_more::DebugCustom;
6use crate::galloc::{AllocForStr, AllocForExactSizeIter, TryAllocForExactSizeIter, AllocForIter};
7use crate::{new_op1, new_op2, new_op2_opt, new_op3};
8use itertools::izip;
9
10
11
12use super::list::to_index;
13use super::{Op1, Op3, Op2};
14
15
16new_op1!(ToStr, "int.to.str",
17    Int -> Str { |s1| {
18        s1.to_string().galloc_str()
19    }}
20);
21
22new_op2!(Add, "int.+",
23    (Int, Int) -> Int { |(s1, s2)|
24        unsafe { s1.unchecked_add(*s2) }
25    }
26);
27new_op2!(Sub, "int.-",
28    (Int, Int) -> Int { |(s1, s2)|
29        unsafe { s1.unchecked_sub(*s2) }
30    }
31);
32
33
34new_op1!(Neg, "int.neg",
35    Int -> Int { |s1| {
36        unsafe { 0i64.unchecked_sub(*s1) }
37    }}
38);
39
40new_op1!(IsPos, "int.is+",
41    Int -> Bool { |s1| { s1 > &0 }}
42);
43
44new_op1!(IsZero, "int.is0",
45    Int -> Bool { |s1| { s1 == &0 }}
46);
47
48new_op1!(IsNatural, "int.isN",
49    Int -> Bool { |s1| { s1 >= &0 }}
50);
51
52new_op2_opt!(Floor, "int.floor",
53    (Int, Int) -> Int { |(s1, s2)| {
54        if *s2 == 0 { return None; }
55        Some(s1.div_floor(*s2) * *s2)
56    }}
57);
58new_op2_opt!(Round, "int.round",
59    (Int, Int) -> Int { |(s1, s2)| {
60        if *s2 == 0 { return None; }
61        if (*s1 % *s2) * 2 >= *s2 {
62            Some(s1.div_ceil(*s2) * *s2)
63        } else {
64            Some(s1.div_floor(*s2) * *s2)
65        }
66    }}
67);
68new_op2_opt!(Ceil, "int.ceil",
69    (Int, Int) -> Int { |(s1, s2)| {
70        if *s2 == 0 { return None; }
71        Some(s1.div_ceil(*s2) * *s2)
72    }}
73);
74
75
76#[cfg(test)]
77mod tests {
78    use crate::{expr::{ context::Context}, value::ConstValue};
79    use crate::expr;
80
81    #[test]
82    fn test1() {
83        let ctx = &Context::new(1, Vec::new(), Vec::new(), ConstValue::Int(0).value(1));
84        let result = expr!(Add (Ceil 90 10) (Neg 1)).eval(ctx);
85        println!("{result:?}");
86    }
87}