synthphonia/expr/ops/
int.rs1
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}