Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'lemu/src/instructions/mop2.rs')
| -rw-r--r-- | lemu/src/instructions/mop2.rs | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/lemu/src/instructions/mop2.rs b/lemu/src/instructions/mop2.rs new file mode 100644 index 0000000..7751736 --- /dev/null +++ b/lemu/src/instructions/mop2.rs @@ -0,0 +1,140 @@ +use super::get_num; +use crate::{lexer::Token, memory::LVar}; +use std::f64::consts::PI; + +super::op_enum! { pub enum MathOp2 { + Angle, + Add, + Sub, + Mul, + Div, + IDiv, + Mod, + Pow, + Equal, + NotEqual, + And, + LessThan, + LessThanEq, + GreaterThan, + GreaterThanEq, + StrictEqual, + ShiftLeft, + ShiftRight, + BitOr, + BitAnd, + ExclusiveOr, + Max, + Min, + AngleDiff, + Len, + Noise, // unimplemented +} } + +macro_rules! num { + ($fn:ident $closure:expr) => { + fn $fn<'v>(a: &LVar<'v>, b: &LVar<'v>) -> f64 { + f64::from($closure(get_num!(a), get_num!(b))) + } + }; +} +macro_rules! op { + ($fn:ident $op:tt) => { + fn $fn<'v>(a: &LVar<'v>, b: &LVar<'v>) -> f64 { + f64::from(get_num!(a) $op get_num!(b)) + } + } +} +macro_rules! bop { + ($fn: ident $op: tt) => { + fn $fn<'v>(a: &LVar<'v>, b:& LVar<'v>) -> f64 { + f64::from(((get_num!(a) as u64) $op (get_num!(b) as u64)) as f64) + } + }; +} +macro_rules! nofun { + ($fn:ident $closure:expr) => { + fn $fn<'v>(a: &LVar<'v>, b: &LVar<'v>) -> f64 { + f64::from($closure(a, b)) + } + }; +} +nofun!(eq | a, b | a == b); +nofun!(ne | a, b | a != b); +num!(and | a, b | a != 0.0 && b != 0.0); +#[rustfmt::skip] +op!(add +); +op!(sub -); +op!(mul *); +num!(idiv | a: f64 , b: f64 | (a / b).floor()); +op!(lt <); +op!(le <=); +op!(gt >); +op!(ge >=); +op!(div /); +op!(rem %); +num!(pow f64::powf); +bop!(shl <<); +bop!(shr >>); +bop!(or |); +bop!(band &); +bop!(xor ^); +num!(max f64::max); +num!(min f64::min); +#[rustfmt::skip] +num!(angle_diff |a, b| { + let a = a % (360.0 * PI); + let b = b % (360.0 * PI); + f64::min( + if (a - b) < 0.0 { a - b + 360.0 } else { a - b }, + if (b - a) < 0.0 { b - a + 360.0 } else { b - a }, + ) +}); +num!(len f64::hypot); +nofun!(noise | _, _ | 9.0); +num!(angle |a: f64, b: f64| { + let mut x = a.atan2(b) * (180.0 / PI); + if x < 0.0 { + x += 360.0; + } + x +}); + +super::op_impl!(MathOp2, ptr type = for<'f> fn(&LVar<'f>, &LVar<'f>) -> f64 { + Equal => eq, + StrictEqual => eq, + NotEqual => ne, + And => and, + Add => add, + Sub => sub, + Mul => mul, + IDiv => idiv, + LessThan => lt, + LessThanEq => le, + GreaterThan => gt, + GreaterThanEq => ge, + Div => div, + Mod => rem, + Pow => pow, + ShiftLeft => shl, + ShiftRight => shr, + BitOr => or, + BitAnd => band, + ExclusiveOr => xor, + Max => max, + Min => min, + AngleDiff => angle_diff, + Len => len, + Noise => noise, + Angle => angle, +}); + +// // no macro cuz funky rem +// impl MathOp2 { +// pub const fn get_fn(self) -> for<'f> fn(&LVar<'f>, &LVar<'f>) -> f64 { +// match self { +// // we kind of interpret strings as numbers so yeah + +// } +// } +// } |