synthphonia/expr/ops/
float.rs

1use std::cmp::min;
2use std::ops::Not;
3
4use derive_more::DebugCustom;
5use crate::galloc::{AllocForStr, AllocForExactSizeIter, TryAllocForExactSizeIter, AllocForIter};
6use crate::utils::F64;
7use crate::{new_op1, new_op1_opt, new_op2, new_op2_opt, new_op3};
8use itertools::izip;
9
10
11use super::list::to_index;
12use super::{ Op1, Op2, Op3};
13
14
15new_op2!(FAdd, "float.+",
16    (Float, Float) -> Float { |(&s1, &s2)| {
17        F64::new(*s1 + *s2)
18    }}
19);
20new_op2!(FSub, "float.-",
21    (Float, Float) -> Float { |(&s1, &s2)| {
22        F64::new(*s1 - *s2)
23    }}
24);
25
26
27new_op1!(FNeg, "float.neg",
28    Float -> Float { |&s1| {
29        F64::new(-*s1)
30    }}
31);
32
33new_op1!(FAbs, "float.abs",
34    Float -> Float { |&s1| {
35        F64::new(s1.abs())
36    }}
37);
38
39new_op1!(FIsPos, "float.is+",
40    Float -> Bool { |s1| {
41        **s1 > 0.0
42    }}
43);
44new_op1!(FNotNeg, "float.not-",
45    Float -> Bool { |s1| {
46        **s1 >= 0.0
47    }}
48);
49new_op1!(FIsZero, "float.is0",
50    Float -> Bool { |s1| {
51        **s1 == 0.0
52    }}
53);
54
55new_op1!(FExp10, "float.exp10",
56    Int -> Float { |s1| {
57        F64::new(10.0f64.powi(*s1 as i32))
58    }}
59);
60
61new_op2!(FShl10, "float.shl10",
62    (Float, Int) -> Float { |(s1, s2)| {
63        F64::new(**s1 * 10.0f64.powi(*s2 as i32))
64    }}
65);
66
67new_op2_opt!(FFloor, "float.floor",
68    (Float, Float) -> Float { |(&s1, &s2)| {
69        if *s2 == 0.0 { return None }
70        Some(F64::new((*s1 / *s2).floor() * *s2))
71    }}
72);
73new_op2_opt!(FRound, "float.round",
74    (Float, Float) -> Float { |(&s1, &s2)| {
75        if *s2 == 0.0 { return None }
76        Some(F64::new((*s1 / *s2).round() * *s2))
77    }}
78);
79new_op2_opt!(FCeil, "float.ceil",
80    (Float, Float) -> Float { |(&s1, &s2)| {
81        if *s2 == 0.0 { return None }
82        Some(F64::new((*s1 / *s2).ceil() * *s2))
83    }}
84);
85
86new_op1!(IntToFloat, "int.to.float",
87    Int -> Float { |&s1| {
88        F64::new(s1 as f64)
89    }}
90);
91
92new_op1!(FloatToInt, "float.to.int",
93    Float -> Int { |&s1| {
94        *s1 as i64
95    }}
96);
97
98new_op1_opt!(StrToFloat, "str.to.float",
99    Str -> Float { |&s1| {
100        s1.parse::<f64>().ok().map(F64::new)
101    }}
102);
103
104
105#[cfg(test)]
106mod tests {
107    use crate::{expr::{ context::Context}, value::ConstValue};
108    use crate::expr;
109
110    #[test]
111    fn test1() {
112        let ctx = &Context::new(1, Vec::new(), Vec::new(), ConstValue::Int(0).value(1));
113        let result = expr!(FFloor (FNeg (FExp10 1)) (FNeg (IntToFloat 0))).eval(ctx);
114        println!("{result:?}");
115    }
116}