diff --git a/Cargo.toml b/Cargo.toml index 03545f28..0e109ea8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mech" -version = "0.2.3" +version = "0.2.4" authors = ["Corey Montella "] description = "Toolchain for the Mech programming language." documentation = "https://mech-lang.org/docs" @@ -18,8 +18,8 @@ gitlab = { repository = "mech-lang/mech", branch = "main" } maintenance = { status = "actively-developed" } [dependencies] -mech-core = "0.2.3" -mech-syntax = "0.2.3" +mech-core = "0.2.4" +mech-syntax = "0.2.4" #mech-program = "0.2.2" #mech-utilities = "0.2.2" diff --git a/src/bin/mech.rs b/src/bin/mech.rs index f49dd671..76f0e6b4 100644 --- a/src/bin/mech.rs +++ b/src/bin/mech.rs @@ -25,7 +25,7 @@ use serde_json; fn main() -> Result<(), MechError> { - let version = "0.2.3"; + let version = "0.2.4"; let text_logo = r#" ┌─────────┐ ┌──────┐ ┌─┐ ┌──┐ ┌─┐ ┌─┐ └───┐ ┌───┘ └──────┘ │ │ └┐ │ │ │ │ │ diff --git a/src/core/Cargo.toml b/src/core/Cargo.toml index 01a2fcbe..2d26a237 100644 --- a/src/core/Cargo.toml +++ b/src/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mech-core" -version = "0.2.3" +version = "0.2.4" authors = ["Corey Montella "] description = "The Mech language runtime." documentation = "http://docs.mech-lang.org" diff --git a/src/syntax/Cargo.toml b/src/syntax/Cargo.toml index e9b4d6e2..e3672667 100644 --- a/src/syntax/Cargo.toml +++ b/src/syntax/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mech-syntax" -version = "0.2.3" +version = "0.2.4" authors = ["Corey Montella "] description = "A toolchain for compiling textual syntax into Mech blocks." documentation = "http://docs.mech-lang.org" @@ -21,7 +21,7 @@ default = [] no-std = ["mech-core/no-std", "rlibc"] [dependencies] -mech-core = "0.2.3" +mech-core = "0.2.4" hashbrown = "0.14.5" lazy_static = "1.4.0" diff --git a/src/syntax/benches/interpreter.rs b/src/syntax/benches/interpreter.rs index bdc348a8..a681ce78 100644 --- a/src/syntax/benches/interpreter.rs +++ b/src/syntax/benches/interpreter.rs @@ -17,15 +17,10 @@ use hashbrown::{HashMap, HashSet}; use std::collections::VecDeque; use std::thread; -use mech_core::*; -use mech_core::function::table; use std::fmt::*; use std::ops::*; -use mech_syntax::parser; -use mech_syntax::ast::Ast; -use mech_syntax::compiler::Compiler; use mech_core::*; use mech_syntax::parser; //use mech_syntax::analyzer::*; diff --git a/src/syntax/src/interpreter.rs b/src/syntax/src/interpreter.rs index 1178c9ef..a72bc724 100644 --- a/src/syntax/src/interpreter.rs +++ b/src/syntax/src/interpreter.rs @@ -346,23 +346,27 @@ fn subscript(sbscrpt: &Subscript, val: &Value, plan: Plan, symbols: SymbolTableR _ => todo!(), } }, - Subscript::Range(x) => todo!(), + Subscript::Range(rng) => { + let result = range(rng,plan.clone(), symbols.clone(), functions.clone())?; + match result.as_vecusize() { + Some(v) => Ok(v.to_value()), + None => Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind}), + } + }, Subscript::Swizzle(x) => todo!(), - Subscript::Formula(fctr) => {return factor(fctr,plan.clone(), symbols.clone(), functions.clone());}, + Subscript::Formula(fctr) => { + let result = factor(fctr,plan.clone(), symbols.clone(), functions.clone())?; + result.as_index() + }, Subscript::Bracket(subs) => { let mut resolved_subs = vec![]; for s in subs { let result = subscript(&s, val, plan.clone(), symbols.clone(), functions.clone())?; - match result.as_index() { - Some(ix) => resolved_subs.push(ix), - None => { return Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledIndexKind});} - } + resolved_subs.push(result); } - let sub_value = match resolved_subs.len() { - 1 => resolved_subs[0].clone(), - x => resolved_subs.iter().map(|s| s.as_usize().unwrap()).collect::>().to_value(), - }; - let new_fxn = MatrixAccess{}.compile(&vec![val.clone(),sub_value])?; + let mut fxn_input = vec![val.clone()]; + fxn_input.append(&mut resolved_subs); + let new_fxn = MatrixAccess{}.compile(&fxn_input)?; new_fxn.solve(); let res = new_fxn.out(); let mut plan_brrw = plan.borrow_mut(); diff --git a/src/syntax/src/matrix.rs b/src/syntax/src/matrix.rs index b5ba1cad..f9dfe818 100644 --- a/src/syntax/src/matrix.rs +++ b/src/syntax/src/matrix.rs @@ -12,196 +12,199 @@ use std::hash::{Hash, Hasher}; // Matrix --------------------------------------------------------------------- pub trait ToMatrix: Clone { - fn to_matrix(elements: Vec, rows: usize, cols: usize) -> Matrix; - } + fn to_matrix(elements: Vec, rows: usize, cols: usize) -> Matrix; +} - macro_rules! impl_to_matrix { - ($t:ty) => { - impl ToMatrix for $t { - fn to_matrix(elements: Vec, rows: usize, cols: usize) -> Matrix { - match (rows,cols) { - (1,1) => Matrix::Matrix1(new_ref(Matrix1::from_element(elements[0].clone()))), - (2,2) => Matrix::Matrix2(new_ref(Matrix2::from_vec(elements))), - (3,4) => Matrix::Matrix3(new_ref(Matrix3::from_vec(elements))), - (4,2) => Matrix::Matrix4(new_ref(Matrix4::from_vec(elements))), - (2,3) => Matrix::Matrix2x3(new_ref(Matrix2x3::from_vec(elements))), - (3,2) => Matrix::Matrix3x2(new_ref(Matrix3x2::from_vec(elements))), - (1,2) => Matrix::RowVector2(new_ref(RowVector2::from_vec(elements))), - (1,3) => Matrix::RowVector3(new_ref(RowVector3::from_vec(elements))), - (1,4) => Matrix::RowVector4(new_ref(RowVector4::from_vec(elements))), - (2,1) => Matrix::Vector2(new_ref(Vector2::from_vec(elements))), - (3,1) => Matrix::Vector3(new_ref(Vector3::from_vec(elements))), - (4,1) => Matrix::Vector4(new_ref(Vector4::from_vec(elements))), - (1,n) => Matrix::RowDVector(new_ref(RowDVector::from_vec(elements))), - (m,1) => Matrix::DVector(new_ref(DVector::from_vec(elements))), - (m,n) => Matrix::DMatrix(new_ref(DMatrix::from_vec(m,n,elements))), - } - }}};} +macro_rules! impl_to_matrix { + ($t:ty) => { + impl ToMatrix for $t { + fn to_matrix(elements: Vec, rows: usize, cols: usize) -> Matrix { + match (rows,cols) { + (1,1) => Matrix::Matrix1(new_ref(Matrix1::from_element(elements[0].clone()))), + (2,2) => Matrix::Matrix2(new_ref(Matrix2::from_vec(elements))), + (3,4) => Matrix::Matrix3(new_ref(Matrix3::from_vec(elements))), + (4,2) => Matrix::Matrix4(new_ref(Matrix4::from_vec(elements))), + (2,3) => Matrix::Matrix2x3(new_ref(Matrix2x3::from_vec(elements))), + (3,2) => Matrix::Matrix3x2(new_ref(Matrix3x2::from_vec(elements))), + (1,2) => Matrix::RowVector2(new_ref(RowVector2::from_vec(elements))), + (1,3) => Matrix::RowVector3(new_ref(RowVector3::from_vec(elements))), + (1,4) => Matrix::RowVector4(new_ref(RowVector4::from_vec(elements))), + (2,1) => Matrix::Vector2(new_ref(Vector2::from_vec(elements))), + (3,1) => Matrix::Vector3(new_ref(Vector3::from_vec(elements))), + (4,1) => Matrix::Vector4(new_ref(Vector4::from_vec(elements))), + (1,n) => Matrix::RowDVector(new_ref(RowDVector::from_vec(elements))), + (m,1) => Matrix::DVector(new_ref(DVector::from_vec(elements))), + (m,n) => Matrix::DMatrix(new_ref(DMatrix::from_vec(m,n,elements))), + }}}};} - impl_to_matrix!(bool); - impl_to_matrix!(u8); - impl_to_matrix!(u16); - impl_to_matrix!(u32); - impl_to_matrix!(u64); - impl_to_matrix!(u128); - impl_to_matrix!(i8); - impl_to_matrix!(i16); - impl_to_matrix!(i32); - impl_to_matrix!(i64); - impl_to_matrix!(i128); - impl_to_matrix!(F32); - impl_to_matrix!(F64); +impl_to_matrix!(bool); +impl_to_matrix!(u8); +impl_to_matrix!(u16); +impl_to_matrix!(u32); +impl_to_matrix!(u64); +impl_to_matrix!(u128); +impl_to_matrix!(i8); +impl_to_matrix!(i16); +impl_to_matrix!(i32); +impl_to_matrix!(i64); +impl_to_matrix!(i128); +impl_to_matrix!(F32); +impl_to_matrix!(F64); - #[derive(Clone, Debug, PartialEq, Eq)] - pub enum Matrix { - RowVector2(Ref>), - RowVector3(Ref>), - RowVector4(Ref>), - Vector2(Ref>), - Vector3(Ref>), - Vector4(Ref>), - Matrix1(Ref>), - Matrix2(Ref>), - Matrix3(Ref>), - Matrix4(Ref>), - Matrix2x3(Ref>), - Matrix3x2(Ref>), - DMatrix(Ref>), - DVector(Ref>), - RowDVector(Ref>), - } +pub trait ToIndex: Clone { + fn to_index(elements: Vec) -> Matrix; +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum Matrix { + RowVector2(Ref>), + RowVector3(Ref>), + RowVector4(Ref>), + Vector2(Ref>), + Vector3(Ref>), + Vector4(Ref>), + Matrix1(Ref>), + Matrix2(Ref>), + Matrix3(Ref>), + Matrix4(Ref>), + Matrix2x3(Ref>), + Matrix3x2(Ref>), + DMatrix(Ref>), + DVector(Ref>), + RowDVector(Ref>), +} - impl Hash for Matrix - where T: Hash + na::Scalar - { - fn hash(&self, state: &mut H) { - match self { - Matrix::RowVector2(x) => x.borrow().hash(state), - Matrix::RowVector3(x) => x.borrow().hash(state), - Matrix::RowVector4(x) => x.borrow().hash(state), - Matrix::Vector2(x) => x.borrow().hash(state), - Matrix::Vector3(x) => x.borrow().hash(state), - Matrix::Vector4(x) => x.borrow().hash(state), - Matrix::Matrix1(x) => x.borrow().hash(state), - Matrix::Matrix2(x) => x.borrow().hash(state), - Matrix::Matrix3(x) => x.borrow().hash(state), - Matrix::Matrix4(x) => x.borrow().hash(state), - Matrix::Matrix2x3(x) => x.borrow().hash(state), - Matrix::Matrix3x2(x) => x.borrow().hash(state), - Matrix::DMatrix(x) => x.borrow().hash(state), - Matrix::RowDVector(x) => x.borrow().hash(state), - Matrix::DVector(x) => x.borrow().hash(state), - } +impl Hash for Matrix +where T: Hash + na::Scalar +{ + fn hash(&self, state: &mut H) { + match self { + Matrix::RowVector2(x) => x.borrow().hash(state), + Matrix::RowVector3(x) => x.borrow().hash(state), + Matrix::RowVector4(x) => x.borrow().hash(state), + Matrix::Vector2(x) => x.borrow().hash(state), + Matrix::Vector3(x) => x.borrow().hash(state), + Matrix::Vector4(x) => x.borrow().hash(state), + Matrix::Matrix1(x) => x.borrow().hash(state), + Matrix::Matrix2(x) => x.borrow().hash(state), + Matrix::Matrix3(x) => x.borrow().hash(state), + Matrix::Matrix4(x) => x.borrow().hash(state), + Matrix::Matrix2x3(x) => x.borrow().hash(state), + Matrix::Matrix3x2(x) => x.borrow().hash(state), + Matrix::DMatrix(x) => x.borrow().hash(state), + Matrix::RowDVector(x) => x.borrow().hash(state), + Matrix::DVector(x) => x.borrow().hash(state), } } - - impl Matrix - where T: Debug + Clone + Copy + PartialEq + 'static - { - - pub fn pretty_print(&self) -> String { - let mut builder = Builder::default(); - match self { - Matrix::RowVector2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::RowVector3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::RowVector4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Vector2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Vector3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Vector4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Matrix1(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Matrix2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Matrix3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Matrix4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Matrix2x3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::Matrix3x2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::DMatrix(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::RowDVector(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - Matrix::DVector(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} - _ => todo!(), - }; - let mut table = builder.build(); - table.with(Style::modern()); - format!("{table}") - } - - pub fn shape(&self) -> Vec { - let shape = match self { - Matrix::RowVector2(x) => x.borrow().shape(), - Matrix::RowVector3(x) => x.borrow().shape(), - Matrix::RowVector4(x) => x.borrow().shape(), - Matrix::Vector2(x) => x.borrow().shape(), - Matrix::Vector3(x) => x.borrow().shape(), - Matrix::Vector4(x) => x.borrow().shape(), - Matrix::Matrix1(x) => x.borrow().shape(), - Matrix::Matrix2(x) => x.borrow().shape(), - Matrix::Matrix3(x) => x.borrow().shape(), - Matrix::Matrix4(x) => x.borrow().shape(), - Matrix::Matrix2x3(x) => x.borrow().shape(), - Matrix::Matrix3x2(x) => x.borrow().shape(), - Matrix::DMatrix(x) => x.borrow().shape(), - Matrix::RowDVector(x) => x.borrow().shape(), - Matrix::DVector(x) => x.borrow().shape(), - }; - vec![shape.0, shape.1] - } - - pub fn index1d(&self, ix: usize) -> T { - match self { - Matrix::RowVector2(x) => *x.borrow().index(ix-1), - Matrix::RowVector3(x) => *x.borrow().index(ix-1), - Matrix::RowVector4(x) => *x.borrow().index(ix-1), - Matrix::Vector2(x) => *x.borrow().index(ix-1), - Matrix::Vector3(x) => *x.borrow().index(ix-1), - Matrix::Vector4(x) => *x.borrow().index(ix-1), - Matrix::Matrix1(x) => *x.borrow().index(ix-1), - Matrix::Matrix2(x) => *x.borrow().index(ix-1), - Matrix::Matrix3(x) => *x.borrow().index(ix-1), - Matrix::Matrix4(x) => *x.borrow().index(ix-1), - Matrix::Matrix2x3(x) => *x.borrow().index(ix-1), - Matrix::Matrix3x2(x) => *x.borrow().index(ix-1), - Matrix::DMatrix(x) => *x.borrow().index(ix-1), - Matrix::RowDVector(x) => *x.borrow().index(ix-1), - Matrix::DVector(x) => *x.borrow().index(ix-1), - } +} + +impl Matrix +where T: Debug + Clone + Copy + PartialEq + 'static +{ + + pub fn pretty_print(&self) -> String { + let mut builder = Builder::default(); + match self { + Matrix::RowVector2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::RowVector3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::RowVector4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Vector2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Vector3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Vector4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Matrix1(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Matrix2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Matrix3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Matrix4(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Matrix2x3(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::Matrix3x2(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::DMatrix(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::RowDVector(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + Matrix::DVector(vec) => {let vec_brrw = vec.borrow();(0..vec_brrw.nrows()).for_each(|i| builder.push_record(vec_brrw.row(i).iter().map(|x| format!("{:?}", x)).collect::>()));} + _ => todo!(), + }; + let mut table = builder.build(); + table.with(Style::modern()); + format!("{table}") + } + + pub fn shape(&self) -> Vec { + let shape = match self { + Matrix::RowVector2(x) => x.borrow().shape(), + Matrix::RowVector3(x) => x.borrow().shape(), + Matrix::RowVector4(x) => x.borrow().shape(), + Matrix::Vector2(x) => x.borrow().shape(), + Matrix::Vector3(x) => x.borrow().shape(), + Matrix::Vector4(x) => x.borrow().shape(), + Matrix::Matrix1(x) => x.borrow().shape(), + Matrix::Matrix2(x) => x.borrow().shape(), + Matrix::Matrix3(x) => x.borrow().shape(), + Matrix::Matrix4(x) => x.borrow().shape(), + Matrix::Matrix2x3(x) => x.borrow().shape(), + Matrix::Matrix3x2(x) => x.borrow().shape(), + Matrix::DMatrix(x) => x.borrow().shape(), + Matrix::RowDVector(x) => x.borrow().shape(), + Matrix::DVector(x) => x.borrow().shape(), + }; + vec![shape.0, shape.1] + } + + pub fn index1d(&self, ix: usize) -> T { + match self { + Matrix::RowVector2(x) => *x.borrow().index(ix-1), + Matrix::RowVector3(x) => *x.borrow().index(ix-1), + Matrix::RowVector4(x) => *x.borrow().index(ix-1), + Matrix::Vector2(x) => *x.borrow().index(ix-1), + Matrix::Vector3(x) => *x.borrow().index(ix-1), + Matrix::Vector4(x) => *x.borrow().index(ix-1), + Matrix::Matrix1(x) => *x.borrow().index(ix-1), + Matrix::Matrix2(x) => *x.borrow().index(ix-1), + Matrix::Matrix3(x) => *x.borrow().index(ix-1), + Matrix::Matrix4(x) => *x.borrow().index(ix-1), + Matrix::Matrix2x3(x) => *x.borrow().index(ix-1), + Matrix::Matrix3x2(x) => *x.borrow().index(ix-1), + Matrix::DMatrix(x) => *x.borrow().index(ix-1), + Matrix::RowDVector(x) => *x.borrow().index(ix-1), + Matrix::DVector(x) => *x.borrow().index(ix-1), } - - pub fn index2d(&self, row: usize, col: usize) -> T { - match self { - Matrix::RowVector2(x) => *x.borrow().index((row-1,col-1)), - Matrix::RowVector3(x) => *x.borrow().index((row-1,col-1)), - Matrix::RowVector4(x) => *x.borrow().index((row-1,col-1)), - Matrix::Vector2(x) => *x.borrow().index((row-1,col-1)), - Matrix::Vector3(x) => *x.borrow().index((row-1,col-1)), - Matrix::Vector4(x) => *x.borrow().index((row-1,col-1)), - Matrix::Matrix1(x) => *x.borrow().index((row-1,col-1)), - Matrix::Matrix2(x) => *x.borrow().index((row-1,col-1)), - Matrix::Matrix3(x) => *x.borrow().index((row-1,col-1)), - Matrix::Matrix4(x) => *x.borrow().index((row-1,col-1)), - Matrix::Matrix2x3(x) => *x.borrow().index((row-1,col-1)), - Matrix::Matrix3x2(x) => *x.borrow().index((row-1,col-1)), - Matrix::DMatrix(x) => *x.borrow().index((row-1,col-1)), - Matrix::RowDVector(x) => *x.borrow().index((row-1,col-1)), - Matrix::DVector(x) => *x.borrow().index((row-1,col-1)), - } + } + + pub fn index2d(&self, row: usize, col: usize) -> T { + match self { + Matrix::RowVector2(x) => *x.borrow().index((row-1,col-1)), + Matrix::RowVector3(x) => *x.borrow().index((row-1,col-1)), + Matrix::RowVector4(x) => *x.borrow().index((row-1,col-1)), + Matrix::Vector2(x) => *x.borrow().index((row-1,col-1)), + Matrix::Vector3(x) => *x.borrow().index((row-1,col-1)), + Matrix::Vector4(x) => *x.borrow().index((row-1,col-1)), + Matrix::Matrix1(x) => *x.borrow().index((row-1,col-1)), + Matrix::Matrix2(x) => *x.borrow().index((row-1,col-1)), + Matrix::Matrix3(x) => *x.borrow().index((row-1,col-1)), + Matrix::Matrix4(x) => *x.borrow().index((row-1,col-1)), + Matrix::Matrix2x3(x) => *x.borrow().index((row-1,col-1)), + Matrix::Matrix3x2(x) => *x.borrow().index((row-1,col-1)), + Matrix::DMatrix(x) => *x.borrow().index((row-1,col-1)), + Matrix::RowDVector(x) => *x.borrow().index((row-1,col-1)), + Matrix::DVector(x) => *x.borrow().index((row-1,col-1)), } - - pub fn as_vec(&self) -> Vec { - match self { - Matrix::RowVector2(x) => x.borrow().as_slice().to_vec(), - Matrix::RowVector3(x) => x.borrow().as_slice().to_vec(), - Matrix::RowVector4(x) => x.borrow().as_slice().to_vec(), - Matrix::Vector2(x) => x.borrow().as_slice().to_vec(), - Matrix::Vector3(x) => x.borrow().as_slice().to_vec(), - Matrix::Vector4(x) => x.borrow().as_slice().to_vec(), - Matrix::Matrix1(x) => x.borrow().as_slice().to_vec(), - Matrix::Matrix2(x) => x.borrow().as_slice().to_vec(), - Matrix::Matrix3(x) => x.borrow().as_slice().to_vec(), - Matrix::Matrix4(x) => x.borrow().as_slice().to_vec(), - Matrix::Matrix2x3(x) => x.borrow().as_slice().to_vec(), - Matrix::Matrix3x2(x) => x.borrow().as_slice().to_vec(), - Matrix::DMatrix(x) => x.borrow().as_slice().to_vec(), - Matrix::RowDVector(x) => x.borrow().as_slice().to_vec(), - Matrix::DVector(x) => x.borrow().as_slice().to_vec(), - } + } + + pub fn as_vec(&self) -> Vec { + match self { + Matrix::RowVector2(x) => x.borrow().as_slice().to_vec(), + Matrix::RowVector3(x) => x.borrow().as_slice().to_vec(), + Matrix::RowVector4(x) => x.borrow().as_slice().to_vec(), + Matrix::Vector2(x) => x.borrow().as_slice().to_vec(), + Matrix::Vector3(x) => x.borrow().as_slice().to_vec(), + Matrix::Vector4(x) => x.borrow().as_slice().to_vec(), + Matrix::Matrix1(x) => x.borrow().as_slice().to_vec(), + Matrix::Matrix2(x) => x.borrow().as_slice().to_vec(), + Matrix::Matrix3(x) => x.borrow().as_slice().to_vec(), + Matrix::Matrix4(x) => x.borrow().as_slice().to_vec(), + Matrix::Matrix2x3(x) => x.borrow().as_slice().to_vec(), + Matrix::Matrix3x2(x) => x.borrow().as_slice().to_vec(), + Matrix::DMatrix(x) => x.borrow().as_slice().to_vec(), + Matrix::RowDVector(x) => x.borrow().as_slice().to_vec(), + Matrix::DVector(x) => x.borrow().as_slice().to_vec(), } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/src/syntax/src/stdlib/compare.rs b/src/syntax/src/stdlib/compare.rs index d72c0fbe..fc6ccdab 100644 --- a/src/syntax/src/stdlib/compare.rs +++ b/src/syntax/src/stdlib/compare.rs @@ -5,610 +5,331 @@ use crate::stdlib::*; // Compare Library // ---------------------------------------------------------------------------- -macro_rules! lt_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] < (*$rhs); - }}};} - - macro_rules! lt_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) < (*$rhs)[i]; - }}};} - - - macro_rules! lt_vec_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] < (*$rhs)[i]; - }}};} - - macro_rules! lt_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - (*$out) = (*$lhs) < (*$rhs); - }};} - - macro_rules! gt_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] > (*$rhs); - }}};} - - macro_rules! gt_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) > (*$rhs)[i]; - }}};} - - macro_rules! gt_vec_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] > (*$rhs)[i]; - }}};} - - macro_rules! gt_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - (*$out) = (*$lhs) > (*$rhs); - }};} - - macro_rules! neq_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] != (*$rhs); - }}};} - - macro_rules! neq_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) != (*$rhs)[i]; - }}};} - - - macro_rules! neq_vec_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] != (*$rhs)[i]; - }}};} - - macro_rules! neq_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - (*$out) = (*$lhs) != (*$rhs); - }};} - - macro_rules! eq_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] == (*$rhs); - }}};} - - macro_rules! eq_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) == (*$rhs)[i]; - }}};} - - - macro_rules! eq_vec_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] == (*$rhs)[i]; - }}};} - - macro_rules! eq_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - (*$out) = (*$lhs) == (*$rhs); - }};} - - - macro_rules! lte_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] <= (*$rhs); - }}};} - - macro_rules! lte_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) <= (*$rhs)[i]; - }}};} - - - macro_rules! lte_vec_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] <= (*$rhs)[i]; - }}};} - - macro_rules! lte_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - (*$out) = (*$lhs) <= (*$rhs); - }};} - - macro_rules! gte_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] >= (*$rhs); - }}};} - - macro_rules! gte_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) >= (*$rhs)[i]; - }}};} - - - macro_rules! gte_vec_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] >= (*$rhs)[i]; - }}};} - - macro_rules! gte_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - (*$out) = (*$lhs) >= (*$rhs); - }};} - - // Greater Than --------------------------------------------------------------- - - impl_binop!(GTScalar, T, T, bool, gt_op); - impl_binop!(GTSM2x3, T, Matrix2x3, Matrix2x3,gt_scalar_rhs_op); - impl_binop!(GTSM2, T, Matrix2, Matrix2,gt_scalar_rhs_op); - impl_binop!(GTSM3, T, Matrix3, Matrix3,gt_scalar_rhs_op); - impl_binop!(GTSR2, T, RowVector2, RowVector2,gt_scalar_rhs_op); - impl_binop!(GTSR3, T, RowVector3, RowVector3,gt_scalar_rhs_op); - impl_binop!(GTSR4, T, RowVector4, RowVector4,gt_scalar_rhs_op); - impl_binop!(GTSRD, T, RowDVector, RowDVector,gt_scalar_rhs_op); - impl_binop!(GTSVD, T, DVector, DVector,gt_scalar_rhs_op); - impl_binop!(GTSMD, T, DMatrix, DMatrix,gt_scalar_rhs_op); - impl_binop!(GTM2x3S, Matrix2x3, T, Matrix2x3,gt_scalar_lhs_op); - impl_binop!(GTM2S, Matrix2, T, Matrix2,gt_scalar_lhs_op); - impl_binop!(GTM3S, Matrix3, T, Matrix3,gt_scalar_lhs_op); - impl_binop!(GTR2S, RowVector2, T, RowVector2,gt_scalar_lhs_op); - impl_binop!(GTR3S, RowVector3, T, RowVector3,gt_scalar_lhs_op); - impl_binop!(GTR4S, RowVector4, T, RowVector4,gt_scalar_lhs_op); - impl_binop!(GTRDS, RowDVector, T, RowDVector,gt_scalar_lhs_op); - impl_binop!(GTVDS, DVector, T, DVector,gt_scalar_lhs_op); - impl_binop!(GTMDS, DMatrix, T, DMatrix,gt_scalar_lhs_op); - impl_binop!(GTM2x3M2x3, Matrix2x3, Matrix2x3, Matrix2x3, gt_vec_op); - impl_binop!(GTM2M2, Matrix2, Matrix2, Matrix2, gt_vec_op); - impl_binop!(GTM3M3, Matrix3,Matrix3, Matrix3, gt_vec_op); - impl_binop!(GTR2R2, RowVector2, RowVector2, RowVector2, gt_vec_op); - impl_binop!(GTR3R3, RowVector3, RowVector3, RowVector3, gt_vec_op); - impl_binop!(GTR4R4, RowVector4, RowVector4, RowVector4, gt_vec_op); - impl_binop!(GTRDRD, RowDVector, RowDVector, RowDVector, gt_vec_op); - impl_binop!(GTVDVD, DVector, DVector, DVector, gt_vec_op); - impl_binop!(GTMDMD, DMatrix, DMatrix, DMatrix, gt_vec_op); - - fn generate_gt_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - GT, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, false; - I16, I16 => MatrixI16, i16, false; - I32, I32 => MatrixI32, i32, false; - I64, I64 => MatrixI64, i64, false; - I128, I128 => MatrixI128, i128, false; - U8, U8 => MatrixU8, u8, false; - U16, U16 => MatrixU16, u16, false; - U32, U32 => MatrixU32, u32, false; - U64, U64 => MatrixU64, u64, false; - U128, U128 => MatrixU128, u128, false; - F32, F32 => MatrixF32, F32, false; - F64, F64 => MatrixF64, F64, false; - ) - } - - pub struct CompareGreaterThan {} - - impl NativeFunctionCompiler for CompareGreaterThan { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_gt_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_gt_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_gt_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_gt_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } - } - - // Greater Than Equal --------------------------------------------------------------- - - impl_binop!(GTEScalar, T, T, bool, gte_op); - impl_binop!(GTESM2x3, T, Matrix2x3, Matrix2x3,gte_scalar_rhs_op); - impl_binop!(GTESM2, T, Matrix2, Matrix2,gte_scalar_rhs_op); - impl_binop!(GTESM3, T, Matrix3, Matrix3,gte_scalar_rhs_op); - impl_binop!(GTESR2, T, RowVector2, RowVector2,gte_scalar_rhs_op); - impl_binop!(GTESR3, T, RowVector3, RowVector3,gte_scalar_rhs_op); - impl_binop!(GTESR4, T, RowVector4, RowVector4,gte_scalar_rhs_op); - impl_binop!(GTESRD, T, RowDVector, RowDVector,gte_scalar_rhs_op); - impl_binop!(GTESVD, T, DVector, DVector,gte_scalar_rhs_op); - impl_binop!(GTESMD, T, DMatrix, DMatrix,gte_scalar_rhs_op); - impl_binop!(GTEM2x3S, Matrix2x3, T, Matrix2x3,gte_scalar_lhs_op); - impl_binop!(GTEM2S, Matrix2, T, Matrix2,gte_scalar_lhs_op); - impl_binop!(GTEM3S, Matrix3, T, Matrix3,gte_scalar_lhs_op); - impl_binop!(GTER2S, RowVector2, T, RowVector2,gte_scalar_lhs_op); - impl_binop!(GTER3S, RowVector3, T, RowVector3,gte_scalar_lhs_op); - impl_binop!(GTER4S, RowVector4, T, RowVector4,gte_scalar_lhs_op); - impl_binop!(GTERDS, RowDVector, T, RowDVector,gte_scalar_lhs_op); - impl_binop!(GTEVDS, DVector, T, DVector,gte_scalar_lhs_op); - impl_binop!(GTEMDS, DMatrix, T, DMatrix,gte_scalar_lhs_op); - impl_binop!(GTEM2x3M2x3, Matrix2x3, Matrix2x3, Matrix2x3, gte_vec_op); - impl_binop!(GTEM2M2, Matrix2, Matrix2, Matrix2, gte_vec_op); - impl_binop!(GTEM3M3, Matrix3,Matrix3, Matrix3, gte_vec_op); - impl_binop!(GTER2R2, RowVector2, RowVector2, RowVector2, gte_vec_op); - impl_binop!(GTER3R3, RowVector3, RowVector3, RowVector3, gte_vec_op); - impl_binop!(GTER4R4, RowVector4, RowVector4, RowVector4, gte_vec_op); - impl_binop!(GTERDRD, RowDVector, RowDVector, RowDVector, gte_vec_op); - impl_binop!(GTEVDVD, DVector, DVector, DVector, gte_vec_op); - impl_binop!(GTEMDMD, DMatrix, DMatrix, DMatrix, gte_vec_op); - - fn generate_gte_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - GTE, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, false; - I16, I16 => MatrixI16, i16, false; - I32, I32 => MatrixI32, i32, false; - I64, I64 => MatrixI64, i64, false; - I128, I128 => MatrixI128, i128, false; - U8, U8 => MatrixU8, u8, false; - U16, U16 => MatrixU16, u16, false; - U32, U32 => MatrixU32, u32, false; - U64, U64 => MatrixU64, u64, false; - U128, U128 => MatrixU128, u128, false; - F32, F32 => MatrixF32, F32, false; - F64, F64 => MatrixF64, F64, false; - ) - } - - pub struct CompareGreaterThanEqual {} - - impl NativeFunctionCompiler for CompareGreaterThanEqual { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_gte_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_gte_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_gte_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_gte_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } - } - - // Less Than Equal --------------------------------------------------------------- - - impl_bool_binop!(LTEScalar, T, T, bool, lte_op); - impl_bool_binop!(LTESM2x3, T, Matrix2x3, Matrix2x3,lte_scalar_rhs_op); - impl_bool_binop!(LTESM2, T, Matrix2, Matrix2,lte_scalar_rhs_op); - impl_bool_binop!(LTESM3, T, Matrix3, Matrix3,lte_scalar_rhs_op); - impl_bool_binop!(LTESR2, T, RowVector2, RowVector2,lte_scalar_rhs_op); - impl_bool_binop!(LTESR3, T, RowVector3, RowVector3,lte_scalar_rhs_op); - impl_bool_binop!(LTESR4, T, RowVector4, RowVector4,lte_scalar_rhs_op); - impl_bool_binop!(LTESRD, T, RowDVector, RowDVector,lte_scalar_rhs_op); - impl_bool_binop!(LTESVD, T, DVector, DVector,lte_scalar_rhs_op); - impl_bool_binop!(LTESMD, T, DMatrix, DMatrix,lte_scalar_rhs_op); - impl_bool_binop!(LTEM2x3S, Matrix2x3, T, Matrix2x3,lte_scalar_lhs_op); - impl_bool_binop!(LTEM2S, Matrix2, T, Matrix2,lte_scalar_lhs_op); - impl_bool_binop!(LTEM3S, Matrix3, T, Matrix3,lte_scalar_lhs_op); - impl_bool_binop!(LTER2S, RowVector2, T, RowVector2,lte_scalar_lhs_op); - impl_bool_binop!(LTER3S, RowVector3, T, RowVector3,lte_scalar_lhs_op); - impl_bool_binop!(LTER4S, RowVector4, T, RowVector4,lte_scalar_lhs_op); - impl_bool_binop!(LTERDS, RowDVector, T, RowDVector,lte_scalar_lhs_op); - impl_bool_binop!(LTEVDS, DVector, T, DVector,lte_scalar_lhs_op); - impl_bool_binop!(LTEMDS, DMatrix, T, DMatrix,lte_scalar_lhs_op); - impl_bool_binop!(LTEM2x3M2x3, Matrix2x3, Matrix2x3, Matrix2x3, lte_vec_op); - impl_bool_binop!(LTEM2M2, Matrix2, Matrix2, Matrix2, lte_vec_op); - impl_bool_binop!(LTEM3M3, Matrix3,Matrix3, Matrix3, lte_vec_op); - impl_bool_binop!(LTER2R2, RowVector2, RowVector2, RowVector2, lte_vec_op); - impl_bool_binop!(LTER3R3, RowVector3, RowVector3, RowVector3, lte_vec_op); - impl_bool_binop!(LTER4R4, RowVector4, RowVector4, RowVector4, lte_vec_op); - impl_bool_binop!(LTERDRD, RowDVector, RowDVector, RowDVector, lte_vec_op); - impl_bool_binop!(LTEVDVD, DVector, DVector, DVector, lte_vec_op); - impl_bool_binop!(LTEMDMD, DMatrix, DMatrix, DMatrix, lte_vec_op); - - fn generate_lte_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - LTE, - (lhs_value, rhs_value), - Bool, Bool => MatrixBool, bool, false; - I8, I8 => MatrixI8, i8, false; - I16, I16 => MatrixI16, i16, false; - I32, I32 => MatrixI32, i32, false; - I64, I64 => MatrixI64, i64, false; - I128, I128 => MatrixI128, i128, false; - U8, U8 => MatrixU8, u8, false; - U16, U16 => MatrixU16, u16, false; - U32, U32 => MatrixU32, u32, false; - U64, U64 => MatrixU64, u64, false; - U128, U128 => MatrixU128, u128, false; - F32, F32 => MatrixF32, F32, false; - F64, F64 => MatrixF64, F64, false; - ) - } - - pub struct CompareLessThanEqual {} - - impl NativeFunctionCompiler for CompareLessThanEqual { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_lte_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_lte_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_lte_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_lte_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } - } - - // Equal --------------------------------------------------------------- - - impl_bool_binop!(EQScalar, T, T, bool, eq_op); - impl_bool_binop!(EQSM2x3, T, Matrix2x3, Matrix2x3,eq_scalar_rhs_op); - impl_bool_binop!(EQSM2, T, Matrix2, Matrix2,eq_scalar_rhs_op); - impl_bool_binop!(EQSM3, T, Matrix3, Matrix3,eq_scalar_rhs_op); - impl_bool_binop!(EQSR2, T, RowVector2, RowVector2,eq_scalar_rhs_op); - impl_bool_binop!(EQSR3, T, RowVector3, RowVector3,eq_scalar_rhs_op); - impl_bool_binop!(EQSR4, T, RowVector4, RowVector4,eq_scalar_rhs_op); - impl_bool_binop!(EQSRD, T, RowDVector, RowDVector,eq_scalar_rhs_op); - impl_bool_binop!(EQSVD, T, DVector, DVector,eq_scalar_rhs_op); - impl_bool_binop!(EQSMD, T, DMatrix, DMatrix,eq_scalar_rhs_op); - impl_bool_binop!(EQM2x3S, Matrix2x3, T, Matrix2x3,eq_scalar_lhs_op); - impl_bool_binop!(EQM2S, Matrix2, T, Matrix2,eq_scalar_lhs_op); - impl_bool_binop!(EQM3S, Matrix3, T, Matrix3,eq_scalar_lhs_op); - impl_bool_binop!(EQR2S, RowVector2, T, RowVector2,eq_scalar_lhs_op); - impl_bool_binop!(EQR3S, RowVector3, T, RowVector3,eq_scalar_lhs_op); - impl_bool_binop!(EQR4S, RowVector4, T, RowVector4,eq_scalar_lhs_op); - impl_bool_binop!(EQRDS, RowDVector, T, RowDVector,eq_scalar_lhs_op); - impl_bool_binop!(EQVDS, DVector, T, DVector,eq_scalar_lhs_op); - impl_bool_binop!(EQMDS, DMatrix, T, DMatrix,eq_scalar_lhs_op); - impl_bool_binop!(EQM2x3M2x3, Matrix2x3, Matrix2x3, Matrix2x3, eq_vec_op); - impl_bool_binop!(EQM2M2, Matrix2, Matrix2, Matrix2, eq_vec_op); - impl_bool_binop!(EQM3M3, Matrix3,Matrix3, Matrix3, eq_vec_op); - impl_bool_binop!(EQR2R2, RowVector2, RowVector2, RowVector2, eq_vec_op); - impl_bool_binop!(EQR3R3, RowVector3, RowVector3, RowVector3, eq_vec_op); - impl_bool_binop!(EQR4R4, RowVector4, RowVector4, RowVector4, eq_vec_op); - impl_bool_binop!(EQRDRD, RowDVector, RowDVector, RowDVector, eq_vec_op); - impl_bool_binop!(EQVDVD, DVector, DVector, DVector, eq_vec_op); - impl_bool_binop!(EQMDMD, DMatrix, DMatrix, DMatrix, eq_vec_op); - - fn generate_eq_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - EQ, - (lhs_value, rhs_value), - Bool, Bool => MatrixBool, bool, false; - I8, I8 => MatrixI8, i8, false; - I16, I16 => MatrixI16, i16, false; - I32, I32 => MatrixI32, i32, false; - I64, I64 => MatrixI64, i64, false; - I128, I128 => MatrixI128, i128, false; - U8, U8 => MatrixU8, u8, false; - U16, U16 => MatrixU16, u16, false; - U32, U32 => MatrixU32, u32, false; - U64, U64 => MatrixU64, u64, false; - U128, U128 => MatrixU128, u128, false; - F32, F32 => MatrixF32, F32, false; - F64, F64 => MatrixF64, F64, false; - ) - } - - pub struct CompareEqual {} - - impl NativeFunctionCompiler for CompareEqual { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_eq_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_eq_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_eq_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_eq_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } +#[macro_export] +macro_rules! generate_compare_fxns { + ($lib:ident) => { + generate_fxns!($lib,T,bool,impl_binop); } - - // Not Equal --------------------------------------------------------------- - - impl_binop!(NEQScalar, T, T, bool, neq_op); - impl_binop!(NEQSM2x3, T, Matrix2x3, Matrix2x3,neq_scalar_rhs_op); - impl_binop!(NEQSM2, T, Matrix2, Matrix2,neq_scalar_rhs_op); - impl_binop!(NEQSM3, T, Matrix3, Matrix3,neq_scalar_rhs_op); - impl_binop!(NEQSR2, T, RowVector2, RowVector2,neq_scalar_rhs_op); - impl_binop!(NEQSR3, T, RowVector3, RowVector3,neq_scalar_rhs_op); - impl_binop!(NEQSR4, T, RowVector4, RowVector4,neq_scalar_rhs_op); - impl_binop!(NEQSRD, T, RowDVector, RowDVector,neq_scalar_rhs_op); - impl_binop!(NEQSVD, T, DVector, DVector,neq_scalar_rhs_op); - impl_binop!(NEQSMD, T, DMatrix, DMatrix,neq_scalar_rhs_op); - impl_binop!(NEQM2x3S, Matrix2x3, T, Matrix2x3,neq_scalar_lhs_op); - impl_binop!(NEQM2S, Matrix2, T, Matrix2,neq_scalar_lhs_op); - impl_binop!(NEQM3S, Matrix3, T, Matrix3,neq_scalar_lhs_op); - impl_binop!(NEQR2S, RowVector2, T, RowVector2,neq_scalar_lhs_op); - impl_binop!(NEQR3S, RowVector3, T, RowVector3,neq_scalar_lhs_op); - impl_binop!(NEQR4S, RowVector4, T, RowVector4,neq_scalar_lhs_op); - impl_binop!(NEQRDS, RowDVector, T, RowDVector,neq_scalar_lhs_op); - impl_binop!(NEQVDS, DVector, T, DVector,neq_scalar_lhs_op); - impl_binop!(NEQMDS, DMatrix, T, DMatrix,neq_scalar_lhs_op); - impl_binop!(NEQM2x3M2x3, Matrix2x3, Matrix2x3, Matrix2x3, neq_vec_op); - impl_binop!(NEQM2M2, Matrix2, Matrix2, Matrix2, neq_vec_op); - impl_binop!(NEQM3M3, Matrix3,Matrix3, Matrix3, neq_vec_op); - impl_binop!(NEQR2R2, RowVector2, RowVector2, RowVector2, neq_vec_op); - impl_binop!(NEQR3R3, RowVector3, RowVector3, RowVector3, neq_vec_op); - impl_binop!(NEQR4R4, RowVector4, RowVector4, RowVector4, neq_vec_op); - impl_binop!(NEQRDRD, RowDVector, RowDVector, RowDVector, neq_vec_op); - impl_binop!(NEQVDVD, DVector, DVector, DVector, neq_vec_op); - impl_binop!(NEQMDMD, DMatrix, DMatrix, DMatrix, neq_vec_op); - - fn generate_neq_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - NEQ, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, false; - I16, I16 => MatrixI16, i16, false; - I32, I32 => MatrixI32, i32, false; - I64, I64 => MatrixI64, i64, false; - I128, I128 => MatrixI128, i128, false; - U8, U8 => MatrixU8, u8, false; - U16, U16 => MatrixU16, u16, false; - U32, U32 => MatrixU32, u32, false; - U64, U64 => MatrixU64, u64, false; - U128, U128 => MatrixU128, u128, false; - F32, F32 => MatrixF32, F32, false; - F64, F64 => MatrixF64, F64, false; - ) - } - - pub struct CompareNotEqual {} - - impl NativeFunctionCompiler for CompareNotEqual { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_neq_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_neq_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_neq_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_neq_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } - } - - // Less Than ------------------------------------------------------------------ - - impl_binop!(LTScalar, T, T, bool, lt_op); - impl_binop!(LTSM2x3, T, Matrix2x3, Matrix2x3,lt_scalar_rhs_op); - impl_binop!(LTSM2, T, Matrix2, Matrix2,lt_scalar_rhs_op); - impl_binop!(LTSM3, T, Matrix3, Matrix3,lt_scalar_rhs_op); - impl_binop!(LTSR2, T, RowVector2, RowVector2,lt_scalar_rhs_op); - impl_binop!(LTSR3, T, RowVector3, RowVector3,lt_scalar_rhs_op); - impl_binop!(LTSR4, T, RowVector4, RowVector4,lt_scalar_rhs_op); - impl_binop!(LTSRD, T, RowDVector, RowDVector,lt_scalar_rhs_op); - impl_binop!(LTSVD, T, DVector, DVector,lt_scalar_rhs_op); - impl_binop!(LTSMD, T, DMatrix, DMatrix,lt_scalar_rhs_op); - impl_binop!(LTM2x3S, Matrix2x3, T, Matrix2x3,lt_scalar_lhs_op); - impl_binop!(LTM2S, Matrix2, T, Matrix2,lt_scalar_lhs_op); - impl_binop!(LTM3S, Matrix3, T, Matrix3,lt_scalar_lhs_op); - impl_binop!(LTR2S, RowVector2, T, RowVector2,lt_scalar_lhs_op); - impl_binop!(LTR3S, RowVector3, T, RowVector3,lt_scalar_lhs_op); - impl_binop!(LTR4S, RowVector4, T, RowVector4,lt_scalar_lhs_op); - impl_binop!(LTRDS, RowDVector, T, RowDVector,lt_scalar_lhs_op); - impl_binop!(LTVDS, DVector, T, DVector,lt_scalar_lhs_op); - impl_binop!(LTMDS, DMatrix, T, DMatrix,lt_scalar_lhs_op); - impl_binop!(LTM2x3M2x3, Matrix2x3, Matrix2x3, Matrix2x3, lt_vec_op); - impl_binop!(LTM2M2, Matrix2, Matrix2, Matrix2, lt_vec_op); - impl_binop!(LTM3M3, Matrix3,Matrix3, Matrix3, lt_vec_op); - impl_binop!(LTR2R2, RowVector2, RowVector2, RowVector2, lt_vec_op); - impl_binop!(LTR3R3, RowVector3, RowVector3, RowVector3, lt_vec_op); - impl_binop!(LTR4R4, RowVector4, RowVector4, RowVector4, lt_vec_op); - impl_binop!(LTRDRD, RowDVector, RowDVector, RowDVector, lt_vec_op); - impl_binop!(LTVDVD, DVector, DVector, DVector, lt_vec_op); - impl_binop!(LTMDMD, DMatrix, DMatrix, DMatrix, lt_vec_op); - - fn generate_lt_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - LT, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, false; - I16, I16 => MatrixI16, i16, false; - I32, I32 => MatrixI32, i32, false; - I64, I64 => MatrixI64, i64, false; - I128, I128 => MatrixI128, i128, false; - U8, U8 => MatrixU8, u8, false; - U16, U16 => MatrixU16, u16, false; - U32, U32 => MatrixU32, u32, false; - U64, U64 => MatrixU64, u64, false; - U128, U128 => MatrixU128, u128, false; - F32, F32 => MatrixF32, F32, false; - F64, F64 => MatrixF64, F64, false; - ) +} + +#[macro_export] +macro_rules! generate_compare_fxns_bool { + ($lib:ident) => { + generate_fxns!($lib,T,bool,impl_bool_binop); } - - pub struct CompareLessThan {} - - impl NativeFunctionCompiler for CompareLessThan { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_lt_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_lt_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_lt_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_lt_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } - } \ No newline at end of file +} + +// Greater Than --------------------------------------------------------------- + +macro_rules! gt_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] > (*$rhs); + }}};} + +macro_rules! gt_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) > (*$rhs)[i]; + }}};} + +macro_rules! gt_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] > (*$rhs)[i]; + }}};} + +macro_rules! gt_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + (*$out) = (*$lhs) > (*$rhs); + }};} + +generate_compare_fxns!(GT); + +fn generate_gt_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + GT, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, false; + I16, I16 => MatrixI16, i16, false; + I32, I32 => MatrixI32, i32, false; + I64, I64 => MatrixI64, i64, false; + I128, I128 => MatrixI128, i128, false; + U8, U8 => MatrixU8, u8, false; + U16, U16 => MatrixU16, u16, false; + U32, U32 => MatrixU32, u32, false; + U64, U64 => MatrixU64, u64, false; + U128, U128 => MatrixU128, u128, false; + F32, F32 => MatrixF32, F32, false; + F64, F64 => MatrixF64, F64, false; + ) +} + +impl_mech_binop_fxn!(CompareGreaterThan,generate_gt_fxn); + +// Greater Than Equal --------------------------------------------------------------- + +macro_rules! gte_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] >= (*$rhs); + }}};} + +macro_rules! gte_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) >= (*$rhs)[i]; + }}};} + +macro_rules! gte_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] >= (*$rhs)[i]; + }}};} + +macro_rules! gte_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + (*$out) = (*$lhs) >= (*$rhs); + }};} + +generate_compare_fxns!(GTE); + +fn generate_gte_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + GTE, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, false; + I16, I16 => MatrixI16, i16, false; + I32, I32 => MatrixI32, i32, false; + I64, I64 => MatrixI64, i64, false; + I128, I128 => MatrixI128, i128, false; + U8, U8 => MatrixU8, u8, false; + U16, U16 => MatrixU16, u16, false; + U32, U32 => MatrixU32, u32, false; + U64, U64 => MatrixU64, u64, false; + U128, U128 => MatrixU128, u128, false; + F32, F32 => MatrixF32, F32, false; + F64, F64 => MatrixF64, F64, false; + ) +} + +impl_mech_binop_fxn!(CompareGreaterThanEqual,generate_gte_fxn); + +// Less Than ------------------------------------------------------------------ + +macro_rules! lt_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] < (*$rhs); + }}};} + +macro_rules! lt_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) < (*$rhs)[i]; + }}};} + +macro_rules! lt_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] < (*$rhs)[i]; + }}};} + +macro_rules! lt_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + (*$out) = (*$lhs) < (*$rhs); + }};} + +generate_compare_fxns!(LT); + +fn generate_lt_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + LT, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, false; + I16, I16 => MatrixI16, i16, false; + I32, I32 => MatrixI32, i32, false; + I64, I64 => MatrixI64, i64, false; + I128, I128 => MatrixI128, i128, false; + U8, U8 => MatrixU8, u8, false; + U16, U16 => MatrixU16, u16, false; + U32, U32 => MatrixU32, u32, false; + U64, U64 => MatrixU64, u64, false; + U128, U128 => MatrixU128, u128, false; + F32, F32 => MatrixF32, F32, false; + F64, F64 => MatrixF64, F64, false; + ) +} + +impl_mech_binop_fxn!(CompareLessThan,generate_lt_fxn); + +// Less Than Equal --------------------------------------------------------------- + +macro_rules! lte_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] <= (*$rhs); + }}};} + +macro_rules! lte_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) <= (*$rhs)[i]; + }}};} + +macro_rules! lte_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] <= (*$rhs)[i]; + }}};} + +macro_rules! lte_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + (*$out) = (*$lhs) <= (*$rhs); + }};} + +generate_compare_fxns!(LTE); + +fn generate_lte_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + LTE, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, false; + I16, I16 => MatrixI16, i16, false; + I32, I32 => MatrixI32, i32, false; + I64, I64 => MatrixI64, i64, false; + I128, I128 => MatrixI128, i128, false; + U8, U8 => MatrixU8, u8, false; + U16, U16 => MatrixU16, u16, false; + U32, U32 => MatrixU32, u32, false; + U64, U64 => MatrixU64, u64, false; + U128, U128 => MatrixU128, u128, false; + F32, F32 => MatrixF32, F32, false; + F64, F64 => MatrixF64, F64, false; + ) +} + +impl_mech_binop_fxn!(CompareLessThanEqual,generate_lte_fxn); + +// Equal --------------------------------------------------------------- + +macro_rules! eq_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] == (*$rhs); + }}};} + +macro_rules! eq_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) == (*$rhs)[i]; + }}};} + + +macro_rules! eq_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] == (*$rhs)[i]; + }}};} + +macro_rules! eq_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + (*$out) = (*$lhs) == (*$rhs); + }};} + +generate_compare_fxns_bool!(EQ); + +fn generate_eq_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + EQ, + (lhs_value, rhs_value), + Bool, Bool => MatrixBool, bool, false; + I8, I8 => MatrixI8, i8, false; + I16, I16 => MatrixI16, i16, false; + I32, I32 => MatrixI32, i32, false; + I64, I64 => MatrixI64, i64, false; + I128, I128 => MatrixI128, i128, false; + U8, U8 => MatrixU8, u8, false; + U16, U16 => MatrixU16, u16, false; + U32, U32 => MatrixU32, u32, false; + U64, U64 => MatrixU64, u64, false; + U128, U128 => MatrixU128, u128, false; + F32, F32 => MatrixF32, F32, false; + F64, F64 => MatrixF64, F64, false; + ) +} + +impl_mech_binop_fxn!(CompareEqual,generate_eq_fxn); + +// Not Equal --------------------------------------------------------------- + +macro_rules! neq_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] != (*$rhs); + }}};} + +macro_rules! neq_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) != (*$rhs)[i]; + }}};} + +macro_rules! neq_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] != (*$rhs)[i]; + }}};} + +macro_rules! neq_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + (*$out) = (*$lhs) != (*$rhs); + }};} + +generate_compare_fxns_bool!(NEQ); + +fn generate_neq_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + NEQ, + (lhs_value, rhs_value), + Bool, Bool => MatrixBool, bool, false; + I8, I8 => MatrixI8, i8, false; + I16, I16 => MatrixI16, i16, false; + I32, I32 => MatrixI32, i32, false; + I64, I64 => MatrixI64, i64, false; + I128, I128 => MatrixI128, i128, false; + U8, U8 => MatrixU8, u8, false; + U16, U16 => MatrixU16, u16, false; + U32, U32 => MatrixU32, u32, false; + U64, U64 => MatrixU64, u64, false; + U128, U128 => MatrixU128, u128, false; + F32, F32 => MatrixF32, F32, false; + F64, F64 => MatrixF64, F64, false; + ) +} + +impl_mech_binop_fxn!(CompareNotEqual,generate_neq_fxn); \ No newline at end of file diff --git a/src/syntax/src/stdlib/logic.rs b/src/syntax/src/stdlib/logic.rs index 6b1ce566..7a43868e 100644 --- a/src/syntax/src/stdlib/logic.rs +++ b/src/syntax/src/stdlib/logic.rs @@ -5,6 +5,55 @@ use crate::stdlib::*; // Logic Library // ---------------------------------------------------------------------------- + + +#[macro_export] +macro_rules! impl_logic_binop { + ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => { + #[derive(Debug)] + struct $struct_name { + lhs: Ref<$arg1_type>, + rhs: Ref<$arg2_type>, + out: Ref<$out_type>, + } + impl MechFunction for $struct_name { + fn solve(&self) { + let lhs_ptr = self.lhs.as_ptr(); + let rhs_ptr = self.rhs.as_ptr(); + let out_ptr = self.out.as_ptr(); + $op!(lhs_ptr,rhs_ptr,out_ptr); + } + fn out(&self) -> Value { self.out.to_value() } + fn to_string(&self) -> String { format!("{:?}", self) } + }};} + +#[macro_export] +macro_rules! impl_logic_urnop { + ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => { + #[derive(Debug)] + struct $struct_name { + arg: Ref<$arg_type>, + out: Ref<$out_type>, + } + impl MechFunction for $struct_name { + fn solve(&self) { + let arg_ptr = self.arg.as_ptr(); + let out_ptr = self.out.as_ptr(); + $op!(arg_ptr,out_ptr); + } + fn out(&self) -> Value { self.out.to_value() } + fn to_string(&self) -> String { format!("{:?}", self) } + }};} + +#[macro_export] +macro_rules! generate_logic_fxns { + ($lib:ident) => { + generate_fxns!($lib,bool,bool,impl_logic_binop); + } +} + +// And ------------------------------------------------------------------------ + macro_rules! and_op { ($lhs:expr, $rhs:expr, $out:expr) => { unsafe {*$out = *$lhs && *$rhs;} @@ -32,6 +81,20 @@ macro_rules! and_scalar_lhs_op { (*$out)[i] = (*$lhs)[i] && (*$rhs); }}};} +generate_logic_fxns!(And); + +fn generate_and_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + And, + (lhs_value, rhs_value), + Bool, Bool => MatrixBool, bool, false; + ) +} + +impl_mech_binop_fxn!(LogicAnd,generate_and_fxn); + +// Or ------------------------------------------------------------------------ + macro_rules! or_op { ($lhs:expr, $rhs:expr, $out:expr) => { unsafe {*$out = *$lhs || *$rhs;} @@ -59,6 +122,19 @@ macro_rules! or_scalar_lhs_op { (*$out)[i] = (*$lhs)[i] || (*$rhs); }}};} +generate_logic_fxns!(Or); + +fn generate_or_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + Or, + (lhs_value, rhs_value), + Bool, Bool => MatrixBool, bool, false; + ) +} + +impl_mech_binop_fxn!(LogicOr,generate_or_fxn); + +// Xor ------------------------------------------------------------------------ macro_rules! xor_op { ($lhs:expr, $rhs:expr, $out:expr) => { unsafe {*$out = *$lhs ^ *$rhs;} @@ -84,212 +160,9 @@ macro_rules! xor_scalar_lhs_op { unsafe { for i in 0..(*$lhs).len() { (*$out)[i] = (*$lhs)[i] ^ (*$rhs); - }}};} - -macro_rules! not_op { - ($arg:expr, $out:expr) => { - unsafe {*$out = !*$arg;} - };} - -macro_rules! not_vec_op { - ($arg:expr, $out:expr) => { - unsafe { - for i in 0..(*$arg).len() { - (*$out)[i] = !(*$arg)[i]; - }}};} - -#[macro_export] -macro_rules! impl_logic_binop { - ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => { - #[derive(Debug)] - struct $struct_name { - lhs: Ref<$arg1_type>, - rhs: Ref<$arg2_type>, - out: Ref<$out_type>, - } - impl MechFunction for $struct_name { - fn solve(&self) { - let lhs_ptr = self.lhs.as_ptr(); - let rhs_ptr = self.rhs.as_ptr(); - let out_ptr = self.out.as_ptr(); - $op!(lhs_ptr,rhs_ptr,out_ptr); - } - fn out(&self) -> Value { self.out.to_value() } - fn to_string(&self) -> String { format!("{:?}", self) } - }};} - -#[macro_export] -macro_rules! impl_logic_urnop { - ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => { - #[derive(Debug)] - struct $struct_name { - arg: Ref<$arg_type>, - out: Ref<$out_type>, - } - impl MechFunction for $struct_name { - fn solve(&self) { - let arg_ptr = self.arg.as_ptr(); - let out_ptr = self.out.as_ptr(); - $op!(arg_ptr,out_ptr); - } - fn out(&self) -> Value { self.out.to_value() } - fn to_string(&self) -> String { format!("{:?}", self) } - }};} - -// And ------------------------------------------------------------------------ - -impl_logic_binop!(AndScalar, bool, bool, bool, and_op); -impl_logic_binop!(AndSM2x3, bool, Matrix2x3, Matrix2x3,and_scalar_rhs_op); -impl_logic_binop!(AndSM2, bool, Matrix2, Matrix2,and_scalar_rhs_op); -impl_logic_binop!(AndSM3, bool, Matrix3, Matrix3,and_scalar_rhs_op); -impl_logic_binop!(AndSR2, bool, RowVector2, RowVector2,and_scalar_rhs_op); -impl_logic_binop!(AndSR3, bool, RowVector3, RowVector3,and_scalar_rhs_op); -impl_logic_binop!(AndSR4, bool, RowVector4, RowVector4,and_scalar_rhs_op); -impl_logic_binop!(AndSRD, bool, RowDVector, RowDVector,and_scalar_rhs_op); -impl_logic_binop!(AndSVD, bool, DVector, DVector,and_scalar_rhs_op); -impl_logic_binop!(AndSMD, bool, DMatrix, DMatrix,and_scalar_rhs_op); -impl_logic_binop!(AndM2x3S, Matrix2x3, bool, Matrix2x3,and_scalar_lhs_op); -impl_logic_binop!(AndM2S, Matrix2, bool, Matrix2,and_scalar_lhs_op); -impl_logic_binop!(AndM3S, Matrix3, bool, Matrix3,and_scalar_lhs_op); -impl_logic_binop!(AndR2S, RowVector2, bool, RowVector2,and_scalar_lhs_op); -impl_logic_binop!(AndR3S, RowVector3, bool, RowVector3,and_scalar_lhs_op); -impl_logic_binop!(AndR4S, RowVector4, bool, RowVector4,and_scalar_lhs_op); -impl_logic_binop!(AndRDS, RowDVector, bool, RowDVector,and_scalar_lhs_op); -impl_logic_binop!(AndVDS, DVector, bool, DVector,and_scalar_lhs_op); -impl_logic_binop!(AndMDS, DMatrix, bool, DMatrix,and_scalar_lhs_op); -impl_logic_binop!(AndM2M2, Matrix2,Matrix2,Matrix2, and_vec_op); -impl_logic_binop!(AndM3M3, Matrix3,Matrix3,Matrix3, and_vec_op); -impl_logic_binop!(AndM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, and_vec_op); -impl_logic_binop!(AndR2R2, RowVector2, RowVector2, RowVector2, and_vec_op); -impl_logic_binop!(AndR3R3, RowVector3, RowVector3, RowVector3, and_vec_op); -impl_logic_binop!(AndR4R4, RowVector4, RowVector4, RowVector4, and_vec_op); -impl_logic_binop!(AndRDRD, RowDVector, RowDVector, RowDVector, and_vec_op); -impl_logic_binop!(AndVDVD, DVector,DVector,DVector, and_vec_op); -impl_logic_binop!(AndMDMD, DMatrix,DMatrix,DMatrix, and_vec_op); - -fn generate_and_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - And, - (lhs_value, rhs_value), - Bool, Bool => MatrixBool, bool, false; - ) -} - -pub struct LogicAnd {} - -impl NativeFunctionCompiler for LogicAnd { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_and_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_and_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_and_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_and_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } -} - -// Or ------------------------------------------------------------------------ - -impl_logic_binop!(OrScalar, bool, bool, bool, or_op); -impl_logic_binop!(OrSM2x3, bool, Matrix2x3, Matrix2x3,or_scalar_rhs_op); -impl_logic_binop!(OrSM2, bool, Matrix2, Matrix2,or_scalar_rhs_op); -impl_logic_binop!(OrSM3, bool, Matrix3, Matrix3,or_scalar_rhs_op); -impl_logic_binop!(OrSR2, bool, RowVector2, RowVector2,or_scalar_rhs_op); -impl_logic_binop!(OrSR3, bool, RowVector3, RowVector3,or_scalar_rhs_op); -impl_logic_binop!(OrSR4, bool, RowVector4, RowVector4,or_scalar_rhs_op); -impl_logic_binop!(OrSRD, bool, RowDVector, RowDVector,or_scalar_rhs_op); -impl_logic_binop!(OrSVD, bool, DVector, DVector,or_scalar_rhs_op); -impl_logic_binop!(OrSMD, bool, DMatrix, DMatrix,or_scalar_rhs_op); -impl_logic_binop!(OrM2x3S, Matrix2x3, bool, Matrix2x3,or_scalar_lhs_op); -impl_logic_binop!(OrM2S, Matrix2, bool, Matrix2,or_scalar_lhs_op); -impl_logic_binop!(OrM3S, Matrix3, bool, Matrix3,or_scalar_lhs_op); -impl_logic_binop!(OrR2S, RowVector2, bool, RowVector2,or_scalar_lhs_op); -impl_logic_binop!(OrR3S, RowVector3, bool, RowVector3,or_scalar_lhs_op); -impl_logic_binop!(OrR4S, RowVector4, bool, RowVector4,or_scalar_lhs_op); -impl_logic_binop!(OrRDS, RowDVector, bool, RowDVector,or_scalar_lhs_op); -impl_logic_binop!(OrVDS, DVector, bool, DVector,or_scalar_lhs_op); -impl_logic_binop!(OrMDS, DMatrix, bool, DMatrix,or_scalar_lhs_op); -impl_logic_binop!(OrM2M2, Matrix2,Matrix2,Matrix2, or_vec_op); -impl_logic_binop!(OrM3M3, Matrix3,Matrix3,Matrix3, or_vec_op); -impl_logic_binop!(OrM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, or_vec_op); -impl_logic_binop!(OrR2R2, RowVector2, RowVector2, RowVector2, or_vec_op); -impl_logic_binop!(OrR3R3, RowVector3, RowVector3, RowVector3, or_vec_op); -impl_logic_binop!(OrR4R4, RowVector4, RowVector4, RowVector4, or_vec_op); -impl_logic_binop!(OrRDRD, RowDVector, RowDVector, RowDVector, or_vec_op); -impl_logic_binop!(OrVDVD, DVector,DVector,DVector, or_vec_op); -impl_logic_binop!(OrMDMD, DMatrix,DMatrix,DMatrix, or_vec_op); + }}};} -fn generate_or_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - Or, - (lhs_value, rhs_value), - Bool, Bool => MatrixBool, bool, false; - ) -} - -pub struct LogicOr {} - -impl NativeFunctionCompiler for LogicOr { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_or_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_or_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_or_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_or_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } -} - -// Xor ------------------------------------------------------------------------ - -impl_logic_binop!(XorScalar, bool, bool, bool, xor_op); -impl_logic_binop!(XorSM2x3, bool, Matrix2x3, Matrix2x3,xor_scalar_rhs_op); -impl_logic_binop!(XorSM2, bool, Matrix2, Matrix2,xor_scalar_rhs_op); -impl_logic_binop!(XorSM3, bool, Matrix3, Matrix3,xor_scalar_rhs_op); -impl_logic_binop!(XorSR2, bool, RowVector2, RowVector2,xor_scalar_rhs_op); -impl_logic_binop!(XorSR3, bool, RowVector3, RowVector3,xor_scalar_rhs_op); -impl_logic_binop!(XorSR4, bool, RowVector4, RowVector4,xor_scalar_rhs_op); -impl_logic_binop!(XorSRD, bool, RowDVector, RowDVector,xor_scalar_rhs_op); -impl_logic_binop!(XorSVD, bool, DVector, DVector,xor_scalar_rhs_op); -impl_logic_binop!(XorSMD, bool, DMatrix, DMatrix,xor_scalar_rhs_op); -impl_logic_binop!(XorM2x3S, Matrix2x3, bool, Matrix2x3,xor_scalar_lhs_op); -impl_logic_binop!(XorM2S, Matrix2, bool, Matrix2,xor_scalar_lhs_op); -impl_logic_binop!(XorM3S, Matrix3, bool, Matrix3,xor_scalar_lhs_op); -impl_logic_binop!(XorR2S, RowVector2, bool, RowVector2,xor_scalar_lhs_op); -impl_logic_binop!(XorR3S, RowVector3, bool, RowVector3,xor_scalar_lhs_op); -impl_logic_binop!(XorR4S, RowVector4, bool, RowVector4,xor_scalar_lhs_op); -impl_logic_binop!(XorRDS, RowDVector, bool, RowDVector,xor_scalar_lhs_op); -impl_logic_binop!(XorVDS, DVector, bool, DVector,xor_scalar_lhs_op); -impl_logic_binop!(XorMDS, DMatrix, bool, DMatrix,xor_scalar_lhs_op); -impl_logic_binop!(XorM2M2, Matrix2,Matrix2,Matrix2, xor_vec_op); -impl_logic_binop!(XorM3M3, Matrix3,Matrix3,Matrix3, xor_vec_op); -impl_logic_binop!(XorM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, xor_vec_op); -impl_logic_binop!(XorR2R2, RowVector2, RowVector2, RowVector2, xor_vec_op); -impl_logic_binop!(XorR3R3, RowVector3, RowVector3, RowVector3, xor_vec_op); -impl_logic_binop!(XorR4R4, RowVector4, RowVector4, RowVector4, xor_vec_op); -impl_logic_binop!(XorRDRD, RowDVector, RowDVector, RowDVector, xor_vec_op); -impl_logic_binop!(XorVDVD, DVector,DVector,DVector, xor_vec_op); -impl_logic_binop!(XorMDMD, DMatrix,DMatrix,DMatrix, xor_vec_op); +generate_logic_fxns!(Xor); fn generate_xor_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { generate_binop_match_arms!( @@ -299,31 +172,22 @@ fn generate_xor_fxn(lhs_value: Value, rhs_value: Value) -> Result) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_xor_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_xor_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_xor_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_xor_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } -} +impl_mech_binop_fxn!(LogicXor,generate_xor_fxn); // Not ------------------------------------------------------------------------ +macro_rules! not_op { + ($arg:expr, $out:expr) => { + unsafe {*$out = !*$arg;} + };} + +macro_rules! not_vec_op { + ($arg:expr, $out:expr) => { + unsafe { + for i in 0..(*$arg).len() { + (*$out)[i] = !(*$arg)[i]; + }}};} + impl_logic_urnop!(NotScalar, bool, bool, not_op); impl_logic_urnop!(NotM2, Matrix2, Matrix2, not_vec_op); impl_logic_urnop!(NotM3, Matrix3, Matrix3, not_vec_op); @@ -343,22 +207,4 @@ fn generate_not_fxn(arg_value: Value) -> Result, MechError ) } -pub struct LogicNot {} - -impl NativeFunctionCompiler for LogicNot { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 1 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let arg_value = arguments[0].clone(); - match generate_not_fxn(arg_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match arg_value { - (Value::MutableReference(arg)) => {generate_not_fxn(arg.borrow().clone())} - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } -} \ No newline at end of file +impl_mech_urnop_fxn!(LogicNot,generate_not_fxn); \ No newline at end of file diff --git a/src/syntax/src/stdlib/math.rs b/src/syntax/src/stdlib/math.rs index 4c2f75c0..b46499a5 100644 --- a/src/syntax/src/stdlib/math.rs +++ b/src/syntax/src/stdlib/math.rs @@ -5,535 +5,541 @@ use crate::stdlib::*; // Math Library // ---------------------------------------------------------------------------- -macro_rules! addto_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { (*$lhs).add_to(&*$rhs,&mut *$out) } - };} - - macro_rules! subto_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { (*$lhs).sub_to(&*$rhs,&mut *$out) } - };} - - macro_rules! component_mul_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = (*$lhs).component_mul(&*$rhs); } - };} - - macro_rules! component_div_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = (*$lhs).component_div(&*$rhs); } - };} - - macro_rules! add_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = *$lhs + *$rhs; } - };} - - macro_rules! sub_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = *$lhs - *$rhs; } - };} - - macro_rules! mul_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = *$lhs * *$rhs; } - };} - - macro_rules! div_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = *$lhs / *$rhs; } - };} - - macro_rules! add_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = (*$lhs).add_scalar(*$rhs); } - };} - - macro_rules! add_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = (*$rhs).add_scalar(*$lhs); } - };} - - macro_rules! sub_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] - (*$rhs); - }}};} - - macro_rules! sub_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) - (*$rhs)[i]; - }}};} - - macro_rules! sub_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] - (*$rhs); - }}};} - - macro_rules! sub_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) - (*$rhs)[i]; - }}};} - - macro_rules! sub_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] - (*$rhs); - }}};} - - macro_rules! mul_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = (*$lhs).clone() * *$rhs; } - };} - - macro_rules! mul_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { *$out = (*$rhs).clone() * *$lhs;}};} - - macro_rules! div_scalar_lhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$lhs).len() { - (*$out)[i] = (*$lhs)[i] / (*$rhs); - }}};} - - macro_rules! div_scalar_rhs_op { - ($lhs:expr, $rhs:expr, $out:expr) => { - unsafe { - for i in 0..(*$rhs).len() { - (*$out)[i] = (*$lhs) / (*$rhs)[i]; - }}};} - - macro_rules! neg_op { - ($arg:expr, $out:expr) => { - unsafe { *$out = -*$arg; } - };} - - macro_rules! neg_vec_op { - ($arg:expr, $out:expr) => { - unsafe { *$out = (*$arg).clone().neg(); } - };} - - - // Cos ------------------------------------------------------------------------ - - use libm::cos; - - #[derive(Debug)] - pub struct MathCosScalar { - val: Ref, - out: Ref, - } - - impl MechFunction for MathCosScalar { - fn solve(&self) { - let val_ptr = self.val.as_ptr(); - let out_ptr = self.out.as_ptr(); - unsafe{(*out_ptr).0 = cos((*val_ptr).0);} - } - fn out(&self) -> Value { Value::F64(self.out.clone()) } - fn to_string(&self) -> String { format!("{:#?}", self)} - } - - pub struct MathCos {} - - impl NativeFunctionCompiler for MathCos { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 1 { - return Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - match &arguments[0] { - Value::F64(val) => - Ok(Box::new(MathCosScalar{val: val.clone(), out: new_ref(F64(0.0))})), - Value::MutableReference(val) => match &*val.borrow() { - Value::F64(val) => Ok(Box::new(MathCosScalar{val: val.clone(), out: new_ref(F64(0.0))})), - x => Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}) - } - x =>Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}) - } - } +#[macro_export] +macro_rules! generate_math_fxns { + ($lib:ident) => { + generate_fxns!($lib,T,T,impl_binop); } - - // Sin ------------------------------------------------------------------------ - - use libm::sin; - - #[derive(Debug)] - pub struct MathSinScalar { - val: Ref, - out: Ref, - } - - impl MechFunction for MathSinScalar { - fn solve(&self) { - let val_ptr = self.val.as_ptr(); - let out_ptr = self.out.as_ptr(); - unsafe{(*out_ptr).0 = sin((*val_ptr).0);} - } - fn out(&self) -> Value { Value::F64(self.out.clone()) } - fn to_string(&self) -> String { format!("{:#?}", self)} - } - - pub struct MathSin {} - - impl NativeFunctionCompiler for MathSin { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 1 { - return Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - match &arguments[0] { - Value::F64(val) => - Ok(Box::new(MathSinScalar{val: val.clone(), out: new_ref(F64(0.0))})), - Value::MutableReference(val) => match &*val.borrow() { - Value::F64(val) => Ok(Box::new(MathSinScalar{val: val.clone(), out: new_ref(F64(0.0))})), - x => Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}) - } - x =>Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}) +} + +#[macro_export] +macro_rules! generate_urnop_match_arms2 { + ($lib:ident, $arg:expr, $($lhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr),+);+ $(;)?) => { + paste!{ + match $arg { + $( + $( + (Value::$lhs_type(arg)) => { + Ok(Box::new([<$lib $lhs_type Scalar>]{arg: arg.clone(), out: new_ref($default) }))}, + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(arg))) => { + Ok(Box::new([<$lib $lhs_type M2>]{arg, out: new_ref(Matrix2::from_element($default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(arg))) => { + Ok(Box::new([<$lib $lhs_type M3>]{arg, out: new_ref(Matrix3::from_element($default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowVector2(arg))) => { + Ok(Box::new([<$lib $lhs_type R2>]{arg: arg.clone(), out: new_ref(RowVector2::from_element($default)) }))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowVector3(arg))) => { + Ok(Box::new([<$lib $lhs_type R3>]{arg: arg.clone(), out: new_ref(RowVector3::from_element($default)) }))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(arg))) => { + Ok(Box::new([<$lib $lhs_type R4>]{arg: arg.clone(), out: new_ref(RowVector4::from_element($default)) }))}, + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(arg))) => { + Ok(Box::new([<$lib $lhs_type M2x3>]{arg, out: new_ref(Matrix2x3::from_element($default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(arg))) => { + let length = {arg.borrow().len()}; + Ok(Box::new([<$lib $lhs_type RD>]{arg, out: new_ref(RowDVector::from_element(length,$default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::DVector(arg))) => { + let length = {arg.borrow().len()}; + Ok(Box::new([<$lib $lhs_type VD>]{arg, out: new_ref(DVector::from_element(length,$default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(arg))) => { + let (rows,cols) = {arg.borrow().shape()}; + Ok(Box::new([<$lib $lhs_type MD>]{arg, out: new_ref(DMatrix::from_element(rows,cols,$default))}))}, + )+ + )+ + x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), } } } - - // Add ------------------------------------------------------------------------ - - impl_binop!(AddScalar, T,T,T, add_op); - impl_binop!(AddSM2x3, T, Matrix2x3, Matrix2x3,add_scalar_rhs_op); - impl_binop!(AddSM2, T, Matrix2, Matrix2,add_scalar_rhs_op); - impl_binop!(AddSM3, T, Matrix3, Matrix3,add_scalar_rhs_op); - impl_binop!(AddSR2, T, RowVector2, RowVector2,add_scalar_rhs_op); - impl_binop!(AddSR3, T, RowVector3, RowVector3,add_scalar_rhs_op); - impl_binop!(AddSR4, T, RowVector4, RowVector4,add_scalar_rhs_op); - impl_binop!(AddSRD, T, RowDVector, RowDVector,add_scalar_rhs_op); - impl_binop!(AddSVD, T, DVector, DVector,add_scalar_rhs_op); - impl_binop!(AddSMD, T, DMatrix, DMatrix,add_scalar_rhs_op); - impl_binop!(AddM2x3S, Matrix2x3, T, Matrix2x3,add_scalar_lhs_op); - impl_binop!(AddM2S, Matrix2, T, Matrix2,add_scalar_lhs_op); - impl_binop!(AddM3S, Matrix3, T, Matrix3,add_scalar_lhs_op); - impl_binop!(AddR2S, RowVector2, T, RowVector2,add_scalar_lhs_op); - impl_binop!(AddR3S, RowVector3, T, RowVector3,add_scalar_lhs_op); - impl_binop!(AddR4S, RowVector4, T, RowVector4,add_scalar_lhs_op); - impl_binop!(AddRDS, RowDVector, T, RowDVector,add_scalar_lhs_op); - impl_binop!(AddVDS, DVector, T, DVector,add_scalar_lhs_op); - impl_binop!(AddMDS, DMatrix, T, DMatrix,add_scalar_lhs_op); - impl_binop!(AddM2M2, Matrix2,Matrix2,Matrix2, add_op); - impl_binop!(AddM3M3, Matrix3,Matrix3,Matrix3, add_op); - impl_binop!(AddM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, add_op); - impl_binop!(AddR2R2, RowVector2, RowVector2, RowVector2, add_op); - impl_binop!(AddR3R3, RowVector3, RowVector3, RowVector3, add_op); - impl_binop!(AddR4R4, RowVector4, RowVector4, RowVector4, add_op); - impl_binop!(AddRDRD, RowDVector, RowDVector, RowDVector, addto_op); - impl_binop!(AddVDVD, DVector,DVector,DVector, addto_op); - impl_binop!(AddMDMD, DMatrix,DMatrix,DMatrix, addto_op); - - fn generate_add_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - Add, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, i8::zero(); - I16, I16 => MatrixI16, i16, i16::zero(); - I32, I32 => MatrixI32, i32, i32::zero(); - I64, I64 => MatrixI64, i64, i64::zero(); - I128, I128 => MatrixI128, i128, i128::zero(); - U8, U8 => MatrixU8, u8, u8::zero(); - U16, U16 => MatrixU16, u16, u16::zero(); - U32, U32 => MatrixU32, u32, u32::zero(); - U64, U64 => MatrixU64, u64, u64::zero(); - U128, U128 => MatrixU128, u128, u128::zero(); - F32, F32 => MatrixF32, F32, F32::zero(); - F64, F64 => MatrixF64, F64, F64::zero(); - ) - } - - pub struct MathAdd {} - - impl NativeFunctionCompiler for MathAdd { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_add_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_add_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_add_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_add_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } +} + +// Cos ------------------------------------------------------------------------ + + +use libm::{cos,cosf}; +macro_rules! cos_op { + ($arg:expr, $out:expr) => { + unsafe{(*$out).0 = cos((*$arg).0);} + };} + +macro_rules! cos_vec_op { + ($arg:expr, $out:expr) => { + unsafe { + for i in 0..(*$arg).len() { + ((*$out)[i]).0 = cos(((*$arg)[i]).0); + }}};} + +macro_rules! cosf_op { + ($arg:expr, $out:expr) => { + unsafe{(*$out).0 = cosf((*$arg).0);} + };} + +macro_rules! cosf_vec_op { + ($arg:expr, $out:expr) => { + unsafe { + for i in 0..(*$arg).len() { + ((*$out)[i]).0 = cosf(((*$arg)[i]).0); + }}};} + +impl_urop!(MathCosF32Scalar, F32, F32, cosf_op); +impl_urop!(MathCosF32M2, Matrix2, Matrix2, cosf_vec_op); +impl_urop!(MathCosF32M3, Matrix3, Matrix3, cosf_vec_op); +impl_urop!(MathCosF32R2, RowVector2, RowVector2, cosf_vec_op); +impl_urop!(MathCosF32R3, RowVector3, RowVector3, cosf_vec_op); +impl_urop!(MathCosF32R4, RowVector4, RowVector4, cosf_vec_op); +impl_urop!(MathCosF32M2x3, Matrix2x3, Matrix2x3, cosf_vec_op); +impl_urop!(MathCosF32VD, DVector, DVector, cosf_vec_op); +impl_urop!(MathCosF32RD, RowDVector, RowDVector, cosf_vec_op); +impl_urop!(MathCosF32MD, DMatrix, DMatrix, cosf_vec_op); + +impl_urop!(MathCosF64Scalar, F64, F64, cos_op); +impl_urop!(MathCosF64M2, Matrix2, Matrix2, cos_vec_op); +impl_urop!(MathCosF64M3, Matrix3, Matrix3, cos_vec_op); +impl_urop!(MathCosF64R2, RowVector2, RowVector2, cos_vec_op); +impl_urop!(MathCosF64R3, RowVector3, RowVector3, cos_vec_op); +impl_urop!(MathCosF64R4, RowVector4, RowVector4, cos_vec_op); +impl_urop!(MathCosF64M2x3, Matrix2x3, Matrix2x3, cos_vec_op); +impl_urop!(MathCosF64VD, DVector, DVector, cos_vec_op); +impl_urop!(MathCosF64RD, RowDVector, RowDVector, cos_vec_op); +impl_urop!(MathCosF64MD, DMatrix, DMatrix, cos_vec_op); + +fn generate_cos_fxn(lhs_value: Value) -> Result, MechError> { + generate_urnop_match_arms2!( + MathCos, + (lhs_value), + F32 => MatrixF32, F32, F32::zero(); + F64 => MatrixF64, F64, F64::zero(); + ) +} + +pub struct MathCos {} + +impl NativeFunctionCompiler for MathCos { + fn compile(&self, arguments: &Vec) -> MResult> { + if arguments.len() != 1 { + return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); } - } - - // Sub ------------------------------------------------------------------------ - - impl_binop!(SubScalar, T,T,T, sub_op); - impl_binop!(SubSM2x3, T, Matrix2x3, Matrix2x3,sub_scalar_rhs_op); - impl_binop!(SubSM2, T, Matrix2, Matrix2,sub_scalar_rhs_op); - impl_binop!(SubSM3, T, Matrix3, Matrix3,sub_scalar_rhs_op); - impl_binop!(SubSR2, T, RowVector2, RowVector2,sub_scalar_rhs_op); - impl_binop!(SubSR3, T, RowVector3, RowVector3,sub_scalar_rhs_op); - impl_binop!(SubSR4, T, RowVector4, RowVector4,sub_scalar_rhs_op); - impl_binop!(SubSRD, T, RowDVector, RowDVector,sub_scalar_rhs_op); - impl_binop!(SubSVD, T, DVector, DVector,sub_scalar_rhs_op); - impl_binop!(SubSMD, T, DMatrix, DMatrix,sub_scalar_rhs_op); - impl_binop!(SubM2x3S, Matrix2x3, T, Matrix2x3,sub_scalar_lhs_op); - impl_binop!(SubM2S, Matrix2, T, Matrix2,sub_scalar_lhs_op); - impl_binop!(SubM3S, Matrix3, T, Matrix3,sub_scalar_lhs_op); - impl_binop!(SubR2S, RowVector2, T, RowVector2,sub_scalar_lhs_op); - impl_binop!(SubR3S, RowVector3, T, RowVector3,sub_scalar_lhs_op); - impl_binop!(SubR4S, RowVector4, T, RowVector4,sub_scalar_lhs_op); - impl_binop!(SubRDS, RowDVector, T, RowDVector,sub_scalar_lhs_op); - impl_binop!(SubVDS, DVector, T, DVector,sub_scalar_lhs_op); - impl_binop!(SubMDS, DMatrix, T, DMatrix,sub_scalar_lhs_op); - impl_binop!(SubM2M2, Matrix2,Matrix2,Matrix2, sub_op); - impl_binop!(SubM3M3, Matrix3,Matrix3,Matrix3, sub_op); - impl_binop!(SubM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, sub_op); - impl_binop!(SubR2R2, RowVector2, RowVector2, RowVector2, sub_op); - impl_binop!(SubR3R3, RowVector3, RowVector3, RowVector3, sub_op); - impl_binop!(SubR4R4, RowVector4, RowVector4, RowVector4, sub_op); - impl_binop!(SubRDRD, RowDVector, RowDVector, RowDVector, subto_op); - impl_binop!(SubVDVD, DVector,DVector,DVector, subto_op); - impl_binop!(SubMDMD, DMatrix,DMatrix,DMatrix, subto_op); - - fn generate_sub_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - Sub, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, i8::zero(); - I16, I16 => MatrixI16, i16, i16::zero(); - I32, I32 => MatrixI32, i32, i32::zero(); - I64, I64 => MatrixI64, i64, i64::zero(); - I128, I128 => MatrixI128, i128, i128::zero(); - U8, U8 => MatrixU8, u8, u8::zero(); - U16, U16 => MatrixU16, u16, u16::zero(); - U32, U32 => MatrixU32, u32, u32::zero(); - U64, U64 => MatrixU64, u64, u64::zero(); - U128, U128 => MatrixU128, u128, u128::zero(); - F32, F32 => MatrixF32, F32, F32::zero(); - F64, F64 => MatrixF64, F64, F64::zero(); - ) - } - - pub struct MathSub {} - - impl NativeFunctionCompiler for MathSub { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_sub_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_sub_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_sub_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_sub_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } + let input = arguments[0].clone(); + match generate_cos_fxn(input.clone()) { + Ok(fxn) => Ok(fxn), + Err(_) => { + match (input) { + (Value::MutableReference(input)) => {generate_cos_fxn(input.borrow().clone())} + x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), } } } } - - // Mul ------------------------------------------------------------------------ - - impl_binop!(MulScalar, T,T,T, mul_op); - impl_binop!(MulSM2x3, T, Matrix2x3, Matrix2x3,mul_scalar_rhs_op); - impl_binop!(MulSM2, T, Matrix2, Matrix2,mul_scalar_rhs_op); - impl_binop!(MulSM3, T, Matrix3, Matrix3,mul_scalar_rhs_op); - impl_binop!(MulSR2, T, RowVector2, RowVector2,mul_scalar_rhs_op); - impl_binop!(MulSR3, T, RowVector3, RowVector3,mul_scalar_rhs_op); - impl_binop!(MulSR4, T, RowVector4, RowVector4,mul_scalar_rhs_op); - impl_binop!(MulSRD, T, RowDVector, RowDVector,mul_scalar_rhs_op); - impl_binop!(MulSVD, T, DVector, DVector,mul_scalar_rhs_op); - impl_binop!(MulSMD, T, DMatrix, DMatrix,mul_scalar_rhs_op); - impl_binop!(MulM2x3S, Matrix2x3, T, Matrix2x3,mul_scalar_lhs_op); - impl_binop!(MulM2S, Matrix2, T, Matrix2,mul_scalar_lhs_op); - impl_binop!(MulM3S, Matrix3, T, Matrix3,mul_scalar_lhs_op); - impl_binop!(MulR2S, RowVector2, T, RowVector2,mul_scalar_lhs_op); - impl_binop!(MulR3S, RowVector3, T, RowVector3,mul_scalar_lhs_op); - impl_binop!(MulR4S, RowVector4, T, RowVector4,mul_scalar_lhs_op); - impl_binop!(MulRDS, RowDVector, T, RowDVector,mul_scalar_lhs_op); - impl_binop!(MulVDS, DVector, T, DVector,mul_scalar_lhs_op); - impl_binop!(MulMDS, DMatrix, T, DMatrix,mul_scalar_lhs_op); - impl_binop!(MulM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, component_mul_op); - impl_binop!(MulM2M2, Matrix2,Matrix2,Matrix2, component_mul_op); - impl_binop!(MulM3M3, Matrix3,Matrix3,Matrix3, component_mul_op); - impl_binop!(MulR2R2, RowVector2,RowVector2,RowVector2, component_mul_op); - impl_binop!(MulR3R3, RowVector3,RowVector3,RowVector3, component_mul_op); - impl_binop!(MulR4R4, RowVector4,RowVector4,RowVector4, component_mul_op); - impl_binop!(MulRDRD, RowDVector,RowDVector,RowDVector, component_mul_op); - impl_binop!(MulVDVD, DVector,DVector,DVector, component_mul_op); - impl_binop!(MulMDMD, DMatrix,DMatrix,DMatrix, component_mul_op); - - fn generate_mul_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - Mul, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, i8::zero(); - I16, I16 => MatrixI16, i16, i16::zero(); - I32, I32 => MatrixI32, i32, i32::zero(); - I64, I64 => MatrixI64, i64, i64::zero(); - I128, I128 => MatrixI128, i128, i128::zero(); - U8, U8 => MatrixU8, u8, u8::zero(); - U16, U16 => MatrixU16, u16, u16::zero(); - U32, U32 => MatrixU32, u32, u32::zero(); - U64, U64 => MatrixU64, u64, u64::zero(); - U128, U128 => MatrixU128, u128, u128::zero(); - F32, F32 => MatrixF32, F32, F32::zero(); - F64, F64 => MatrixF64, F64, F64::zero(); - ) - } - - pub struct MathMul {} - - impl NativeFunctionCompiler for MathMul { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_mul_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_mul_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_mul_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_mul_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } +} + +// Sin ------------------------------------------------------------------------ + +use libm::{sin,sinf}; +macro_rules! sin_op { + ($arg:expr, $out:expr) => { + unsafe{(*$out).0 = sin((*$arg).0);} + };} + +macro_rules! sin_vec_op { + ($arg:expr, $out:expr) => { + unsafe { + for i in 0..(*$arg).len() { + ((*$out)[i]).0 = sin(((*$arg)[i]).0); + }}};} + +macro_rules! sinf_op { + ($arg:expr, $out:expr) => { + unsafe{(*$out).0 = sinf((*$arg).0);} + };} + +macro_rules! sinf_vec_op { + ($arg:expr, $out:expr) => { + unsafe { + for i in 0..(*$arg).len() { + ((*$out)[i]).0 = sinf(((*$arg)[i]).0); + }}};} + +impl_urop!(MathSinF32Scalar, F32, F32, sinf_op); +impl_urop!(MathSinF32M2, Matrix2, Matrix2, sinf_vec_op); +impl_urop!(MathSinF32M3, Matrix3, Matrix3, sinf_vec_op); +impl_urop!(MathSinF32R2, RowVector2, RowVector2, sinf_vec_op); +impl_urop!(MathSinF32R3, RowVector3, RowVector3, sinf_vec_op); +impl_urop!(MathSinF32R4, RowVector4, RowVector4, sinf_vec_op); +impl_urop!(MathSinF32M2x3, Matrix2x3, Matrix2x3, sinf_vec_op); +impl_urop!(MathSinF32VD, DVector, DVector, sinf_vec_op); +impl_urop!(MathSinF32RD, RowDVector, RowDVector, sinf_vec_op); +impl_urop!(MathSinF32MD, DMatrix, DMatrix, sinf_vec_op); + +impl_urop!(MathSinF64Scalar, F64, F64, sin_op); +impl_urop!(MathSinF64M2, Matrix2, Matrix2, sin_vec_op); +impl_urop!(MathSinF64M3, Matrix3, Matrix3, sin_vec_op); +impl_urop!(MathSinF64R2, RowVector2, RowVector2, sin_vec_op); +impl_urop!(MathSinF64R3, RowVector3, RowVector3, sin_vec_op); +impl_urop!(MathSinF64R4, RowVector4, RowVector4, sin_vec_op); +impl_urop!(MathSinF64M2x3, Matrix2x3, Matrix2x3, sin_vec_op); +impl_urop!(MathSinF64VD, DVector, DVector, sin_vec_op); +impl_urop!(MathSinF64RD, RowDVector, RowDVector, sin_vec_op); +impl_urop!(MathSinF64MD, DMatrix, DMatrix, sin_vec_op); + +fn generate_sin_fxn(lhs_value: Value) -> Result, MechError> { + generate_urnop_match_arms2!( + MathSin, + (lhs_value), + F32 => MatrixF32, F32, F32::zero(); + F64 => MatrixF64, F64, F64::zero(); + ) +} + +pub struct MathSin {} + +impl NativeFunctionCompiler for MathSin { + fn compile(&self, arguments: &Vec) -> MResult> { + if arguments.len() != 1 { + return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); } - } - - // Div ------------------------------------------------------------------------ - - impl_binop!(DivScalar, T, T, T, div_op); - impl_binop!(DivSM2x3, T, Matrix2x3, Matrix2x3,div_scalar_rhs_op); - impl_binop!(DivSM2, T, Matrix2, Matrix2,div_scalar_rhs_op); - impl_binop!(DivSM3, T, Matrix3, Matrix3,div_scalar_rhs_op); - impl_binop!(DivSR2, T, RowVector2, RowVector2,div_scalar_rhs_op); - impl_binop!(DivSR3, T, RowVector3, RowVector3,div_scalar_rhs_op); - impl_binop!(DivSR4, T, RowVector4, RowVector4,div_scalar_rhs_op); - impl_binop!(DivSRD, T, RowDVector, RowDVector,div_scalar_rhs_op); - impl_binop!(DivSVD, T, DVector, DVector,div_scalar_rhs_op); - impl_binop!(DivSMD, T, DMatrix, DMatrix,div_scalar_rhs_op); - impl_binop!(DivM2x3S, Matrix2x3, T, Matrix2x3,div_scalar_lhs_op); - impl_binop!(DivM2S, Matrix2, T, Matrix2,div_scalar_lhs_op); - impl_binop!(DivM3S, Matrix3, T, Matrix3,div_scalar_lhs_op); - impl_binop!(DivR2S, RowVector2, T, RowVector2,div_scalar_lhs_op); - impl_binop!(DivR3S, RowVector3, T, RowVector3,div_scalar_lhs_op); - impl_binop!(DivR4S, RowVector4, T, RowVector4,div_scalar_lhs_op); - impl_binop!(DivRDS, RowDVector, T, RowDVector,div_scalar_lhs_op); - impl_binop!(DivVDS, DVector, T, DVector,add_scalar_lhs_op); - impl_binop!(DivMDS, DMatrix, T, DMatrix,add_scalar_lhs_op); - impl_binop!(DivM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3,component_div_op); - impl_binop!(DivM2M2, Matrix2,Matrix2,Matrix2,component_div_op); - impl_binop!(DivM3M3, Matrix3,Matrix3,Matrix3,component_div_op); - impl_binop!(DivR2R2, RowVector2,RowVector2,RowVector2,component_div_op); - impl_binop!(DivR3R3, RowVector3,RowVector3,RowVector3,component_div_op); - impl_binop!(DivR4R4, RowVector4,RowVector4,RowVector4,component_div_op); - impl_binop!(DivRDRD, RowDVector,RowDVector,RowDVector,component_div_op); - impl_binop!(DivVDVD, DVector,DVector,DVector,component_div_op); - impl_binop!(DivMDMD, DMatrix,DMatrix,DMatrix,component_div_op); - - fn generate_div_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { - generate_binop_match_arms!( - Div, - (lhs_value, rhs_value), - I8, I8 => MatrixI8, i8, i8::zero(); - I16, I16 => MatrixI16, i16, i16::zero(); - I32, I32 => MatrixI32, i32, i32::zero(); - I64, I64 => MatrixI64, i64, i64::zero(); - I128, I128 => MatrixI128, i128, i128::zero(); - U8, U8 => MatrixU8, u8, u8::zero(); - U16, U16 => MatrixU16, u16, u16::zero(); - U32, U32 => MatrixU32, u32, u32::zero(); - U64, U64 => MatrixU64, u64, u64::zero(); - U128, U128 => MatrixU128, u128, u128::zero(); - F32, F32 => MatrixF32, F32, F32::zero(); - F64, F64 => MatrixF64, F64, F64::zero(); - ) - } - - pub struct MathDiv {} - - impl NativeFunctionCompiler for MathDiv { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_div_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_div_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_div_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_div_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } + let input = arguments[0].clone(); + match generate_sin_fxn(input.clone()) { + Ok(fxn) => Ok(fxn), + Err(_) => { + match (input) { + (Value::MutableReference(input)) => {generate_sin_fxn(input.borrow().clone())} + x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), } } } } - - // Exp ------------------------------------------------------------------------ - - #[derive(Debug)] - struct ExpScalar { - lhs: Ref, - rhs: Ref, - out: Ref, - } - - impl MechFunction for ExpScalar { - fn solve(&self) { - let lhs_ptr = self.lhs.as_ptr(); - let rhs_ptr = self.rhs.as_ptr(); - let out_ptr = self.out.as_ptr(); - unsafe {*out_ptr = (*lhs_ptr).pow(*rhs_ptr as u32);} - } - fn out(&self) -> Value { - Value::I64(self.out.clone()) +} + +// Add ------------------------------------------------------------------------ + +macro_rules! add_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = *$lhs + *$rhs; } + };} + +macro_rules! addto_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { (*$lhs).add_to(&*$rhs,&mut *$out) } + };} + +macro_rules! add_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = (*$lhs).add_scalar(*$rhs); } + };} + +macro_rules! add_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = (*$rhs).add_scalar(*$lhs); } + };} + +impl_binop!(AddScalar, T,T,T, add_op); +impl_binop!(AddSM2x3, T, Matrix2x3, Matrix2x3,add_scalar_rhs_op); +impl_binop!(AddSM2, T, Matrix2, Matrix2,add_scalar_rhs_op); +impl_binop!(AddSM3, T, Matrix3, Matrix3,add_scalar_rhs_op); +impl_binop!(AddSR2, T, RowVector2, RowVector2,add_scalar_rhs_op); +impl_binop!(AddSR3, T, RowVector3, RowVector3,add_scalar_rhs_op); +impl_binop!(AddSR4, T, RowVector4, RowVector4,add_scalar_rhs_op); +impl_binop!(AddSRD, T, RowDVector, RowDVector,add_scalar_rhs_op); +impl_binop!(AddSVD, T, DVector, DVector,add_scalar_rhs_op); +impl_binop!(AddSMD, T, DMatrix, DMatrix,add_scalar_rhs_op); +impl_binop!(AddM2x3S, Matrix2x3, T, Matrix2x3,add_scalar_lhs_op); +impl_binop!(AddM2S, Matrix2, T, Matrix2,add_scalar_lhs_op); +impl_binop!(AddM3S, Matrix3, T, Matrix3,add_scalar_lhs_op); +impl_binop!(AddR2S, RowVector2, T, RowVector2,add_scalar_lhs_op); +impl_binop!(AddR3S, RowVector3, T, RowVector3,add_scalar_lhs_op); +impl_binop!(AddR4S, RowVector4, T, RowVector4,add_scalar_lhs_op); +impl_binop!(AddRDS, RowDVector, T, RowDVector,add_scalar_lhs_op); +impl_binop!(AddVDS, DVector, T, DVector,add_scalar_lhs_op); +impl_binop!(AddMDS, DMatrix, T, DMatrix,add_scalar_lhs_op); +impl_binop!(AddM2M2, Matrix2,Matrix2,Matrix2, add_op); +impl_binop!(AddM3M3, Matrix3,Matrix3,Matrix3, add_op); +impl_binop!(AddM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, add_op); +impl_binop!(AddR2R2, RowVector2, RowVector2, RowVector2, add_op); +impl_binop!(AddR3R3, RowVector3, RowVector3, RowVector3, add_op); +impl_binop!(AddR4R4, RowVector4, RowVector4, RowVector4, add_op); +impl_binop!(AddRDRD, RowDVector, RowDVector, RowDVector, addto_op); +impl_binop!(AddVDVD, DVector,DVector,DVector, addto_op); +impl_binop!(AddMDMD, DMatrix,DMatrix,DMatrix, addto_op); + +fn generate_add_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + Add, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, i8::zero(); + I16, I16 => MatrixI16, i16, i16::zero(); + I32, I32 => MatrixI32, i32, i32::zero(); + I64, I64 => MatrixI64, i64, i64::zero(); + I128, I128 => MatrixI128, i128, i128::zero(); + U8, U8 => MatrixU8, u8, u8::zero(); + U16, U16 => MatrixU16, u16, u16::zero(); + U32, U32 => MatrixU32, u32, u32::zero(); + U64, U64 => MatrixU64, u64, u64::zero(); + U128, U128 => MatrixU128, u128, u128::zero(); + F32, F32 => MatrixF32, F32, F32::zero(); + F64, F64 => MatrixF64, F64, F64::zero(); + ) +} + +impl_mech_binop_fxn!(MathAdd,generate_add_fxn); + +// Sub ------------------------------------------------------------------------ + +macro_rules! sub_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = *$lhs - *$rhs; } + };} + +macro_rules! subto_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { (*$lhs).sub_to(&*$rhs,&mut *$out) } + };} + +macro_rules! sub_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] - (*$rhs); + }}};} + +macro_rules! sub_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) - (*$rhs)[i]; + }}};} + +impl_binop!(SubScalar, T,T,T, sub_op); +impl_binop!(SubSM2x3, T, Matrix2x3, Matrix2x3,sub_scalar_rhs_op); +impl_binop!(SubSM2, T, Matrix2, Matrix2,sub_scalar_rhs_op); +impl_binop!(SubSM3, T, Matrix3, Matrix3,sub_scalar_rhs_op); +impl_binop!(SubSR2, T, RowVector2, RowVector2,sub_scalar_rhs_op); +impl_binop!(SubSR3, T, RowVector3, RowVector3,sub_scalar_rhs_op); +impl_binop!(SubSR4, T, RowVector4, RowVector4,sub_scalar_rhs_op); +impl_binop!(SubSRD, T, RowDVector, RowDVector,sub_scalar_rhs_op); +impl_binop!(SubSVD, T, DVector, DVector,sub_scalar_rhs_op); +impl_binop!(SubSMD, T, DMatrix, DMatrix,sub_scalar_rhs_op); +impl_binop!(SubM2x3S, Matrix2x3, T, Matrix2x3,sub_scalar_lhs_op); +impl_binop!(SubM2S, Matrix2, T, Matrix2,sub_scalar_lhs_op); +impl_binop!(SubM3S, Matrix3, T, Matrix3,sub_scalar_lhs_op); +impl_binop!(SubR2S, RowVector2, T, RowVector2,sub_scalar_lhs_op); +impl_binop!(SubR3S, RowVector3, T, RowVector3,sub_scalar_lhs_op); +impl_binop!(SubR4S, RowVector4, T, RowVector4,sub_scalar_lhs_op); +impl_binop!(SubRDS, RowDVector, T, RowDVector,sub_scalar_lhs_op); +impl_binop!(SubVDS, DVector, T, DVector,sub_scalar_lhs_op); +impl_binop!(SubMDS, DMatrix, T, DMatrix,sub_scalar_lhs_op); +impl_binop!(SubM2M2, Matrix2,Matrix2,Matrix2, sub_op); +impl_binop!(SubM3M3, Matrix3,Matrix3,Matrix3, sub_op); +impl_binop!(SubM2x3M2x3, Matrix2x3,Matrix2x3,Matrix2x3, sub_op); +impl_binop!(SubR2R2, RowVector2, RowVector2, RowVector2, sub_op); +impl_binop!(SubR3R3, RowVector3, RowVector3, RowVector3, sub_op); +impl_binop!(SubR4R4, RowVector4, RowVector4, RowVector4, sub_op); +impl_binop!(SubRDRD, RowDVector, RowDVector, RowDVector, subto_op); +impl_binop!(SubVDVD, DVector,DVector,DVector, subto_op); +impl_binop!(SubMDMD, DMatrix,DMatrix,DMatrix, subto_op); + +fn generate_sub_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + Sub, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, i8::zero(); + I16, I16 => MatrixI16, i16, i16::zero(); + I32, I32 => MatrixI32, i32, i32::zero(); + I64, I64 => MatrixI64, i64, i64::zero(); + I128, I128 => MatrixI128, i128, i128::zero(); + U8, U8 => MatrixU8, u8, u8::zero(); + U16, U16 => MatrixU16, u16, u16::zero(); + U32, U32 => MatrixU32, u32, u32::zero(); + U64, U64 => MatrixU64, u64, u64::zero(); + U128, U128 => MatrixU128, u128, u128::zero(); + F32, F32 => MatrixF32, F32, F32::zero(); + F64, F64 => MatrixF64, F64, F64::zero(); + ) +} + +impl_mech_binop_fxn!(MathSub,generate_sub_fxn); + +// Mul ------------------------------------------------------------------------ + +macro_rules! mul_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = *$lhs * *$rhs; }};} + +macro_rules! mul_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = (*$lhs).component_mul(&*$rhs); }};} + +macro_rules! mul_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = (*$lhs).clone() * *$rhs; }};} + +macro_rules! mul_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = (*$rhs).clone() * *$lhs;}};} + +generate_math_fxns!(Mul); + +fn generate_mul_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + Mul, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, i8::zero(); + I16, I16 => MatrixI16, i16, i16::zero(); + I32, I32 => MatrixI32, i32, i32::zero(); + I64, I64 => MatrixI64, i64, i64::zero(); + I128, I128 => MatrixI128, i128, i128::zero(); + U8, U8 => MatrixU8, u8, u8::zero(); + U16, U16 => MatrixU16, u16, u16::zero(); + U32, U32 => MatrixU32, u32, u32::zero(); + U64, U64 => MatrixU64, u64, u64::zero(); + U128, U128 => MatrixU128, u128, u128::zero(); + F32, F32 => MatrixF32, F32, F32::zero(); + F64, F64 => MatrixF64, F64, F64::zero(); + ) +} + +impl_mech_binop_fxn!(MathMul,generate_mul_fxn); + + +// Div ------------------------------------------------------------------------ + +macro_rules! div_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = *$lhs / *$rhs; } + };} + +macro_rules! div_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { *$out = (*$lhs).component_div(&*$rhs); } + };} + +macro_rules! div_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i] / (*$rhs); + }}};} + +macro_rules! div_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs) / (*$rhs)[i]; + }}};} + +generate_math_fxns!(Div); + +fn generate_div_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + Div, + (lhs_value, rhs_value), + I8, I8 => MatrixI8, i8, i8::zero(); + I16, I16 => MatrixI16, i16, i16::zero(); + I32, I32 => MatrixI32, i32, i32::zero(); + I64, I64 => MatrixI64, i64, i64::zero(); + I128, I128 => MatrixI128, i128, i128::zero(); + U8, U8 => MatrixU8, u8, u8::zero(); + U16, U16 => MatrixU16, u16, u16::zero(); + U32, U32 => MatrixU32, u32, u32::zero(); + U64, U64 => MatrixU64, u64, u64::zero(); + U128, U128 => MatrixU128, u128, u128::zero(); + F32, F32 => MatrixF32, F32, F32::zero(); + F64, F64 => MatrixF64, F64, F64::zero(); + ) +} + +impl_mech_binop_fxn!(MathDiv,generate_div_fxn); + +// Exp ------------------------------------------------------------------------ + +macro_rules! exp_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe {*$out = (*$lhs).pow(*$rhs);} + };} + +macro_rules! exp_vec_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i].pow((*$rhs)[i]); + }}};} + +macro_rules! exp_scalar_lhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$lhs).len() { + (*$out)[i] = (*$lhs)[i].pow((*$rhs)); + }}};} + +macro_rules! exp_scalar_rhs_op { + ($lhs:expr, $rhs:expr, $out:expr) => { + unsafe { + for i in 0..(*$rhs).len() { + (*$out)[i] = (*$lhs).pow((*$rhs)[i]); + }}};} + +#[macro_export] +macro_rules! impl_expop { + ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident) => { + #[derive(Debug)] + struct $struct_name { + lhs: Ref<$arg1_type>, + rhs: Ref<$arg2_type>, + out: Ref<$out_type>, } - fn to_string(&self) -> String { format!("{:?}", self) } - } - - pub struct MathExp {} - - impl NativeFunctionCompiler for MathExp { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { - return Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - match (arguments[0].clone(), arguments[1].clone()) { - (Value::I64(lhs), Value::I64(rhs)) => - Ok(Box::new(ExpScalar{lhs, rhs, out: new_ref(0)})), - x => - Err(MechError{tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}) + impl MechFunction for $struct_name + where + T: Copy + Debug + Clone + Sync + Send + 'static + + PartialEq + PartialOrd + + Add + AddAssign + + Sub + SubAssign + + Mul + MulAssign + + Div + DivAssign + + Pow + + Zero + One, + Ref<$out_type>: ToValue + { + fn solve(&self) { + let lhs_ptr = self.lhs.as_ptr(); + let rhs_ptr = self.rhs.as_ptr(); + let out_ptr = self.out.as_ptr(); + $op!(lhs_ptr,rhs_ptr,out_ptr); } - } + fn out(&self) -> Value { self.out.to_value() } + fn to_string(&self) -> String { format!("{:?}", self) } + }};} + +#[macro_export] +macro_rules! generate_math_fxns_exp { + ($lib:ident) => { + generate_fxns!($lib,T,T,impl_expop); } +} + +generate_math_fxns_exp!(Exp); + +fn generate_exp_fxn(lhs_value: Value, rhs_value: Value) -> Result, MechError> { + generate_binop_match_arms!( + Exp, + (lhs_value, rhs_value), + U8, U8 => MatrixU8, u8, u8::zero(); + U16, U16 => MatrixU16, u16, u16::zero(); + U32, U32 => MatrixU32, u32, u32::zero(); + F32, F32 => MatrixF32, F32, F32::zero(); + F64, F64 => MatrixF64, F64, F64::zero(); + ) +} + +impl_mech_binop_fxn!(MathExp,generate_exp_fxn); + +// Negate --------------------------------------------------------------------- - // Negate --------------------------------------------------------------------- - +macro_rules! neg_op { + ($arg:expr, $out:expr) => { + unsafe { *$out = -*$arg; } + };} + +macro_rules! neg_vec_op { + ($arg:expr, $out:expr) => { + unsafe { *$out = (*$arg).clone().neg(); } + };} + macro_rules! impl_neg_op { ($struct_name:ident, $out_type:ty, $op:ident) => { #[derive(Debug)] @@ -554,48 +560,30 @@ macro_rules! impl_neg_op { fn out(&self) -> Value { self.out.to_value() } fn to_string(&self) -> String { format!("{:?}", self) } }};} - - impl_neg_op!(NegateScalar, T, neg_op); - impl_neg_op!(NegateM2, Matrix2,neg_op); - impl_neg_op!(NegateM3, Matrix3,neg_op); - impl_neg_op!(NegateM2x3, Matrix2x3,neg_op); - impl_neg_op!(NegateR2, RowVector2,neg_op); - impl_neg_op!(NegateR3, RowVector3,neg_op); - impl_neg_op!(NegateR4, RowVector4,neg_op); - impl_neg_op!(NegateRD, RowDVector,neg_vec_op); - impl_neg_op!(NegateVD, DVector,neg_vec_op); - impl_neg_op!(NegateMD, DMatrix,neg_vec_op); - - fn generate_neg_fxn(lhs_value: Value) -> Result, MechError> { - generate_urnop_match_arms!( - Negate, - (lhs_value), - I8 => MatrixI8, i8, i8::zero(); - I16 => MatrixI16, i16, i16::zero(); - I32 => MatrixI32, i32, i32::zero(); - I64 => MatrixI64, i64, i64::zero(); - I128 => MatrixI128, i128, i128::zero(); - F32 => MatrixF32, F32, F32::zero(); - F64 => MatrixF64, F64, F64::zero(); - ) - } - - pub struct MathNegate {} - - impl NativeFunctionCompiler for MathNegate { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 1 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let input = arguments[0].clone(); - match generate_neg_fxn(input.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (input) { - (Value::MutableReference(input)) => {generate_neg_fxn(input.borrow().clone())} - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } - } \ No newline at end of file + +impl_neg_op!(NegateScalar, T, neg_op); +impl_neg_op!(NegateM2, Matrix2,neg_op); +impl_neg_op!(NegateM3, Matrix3,neg_op); +impl_neg_op!(NegateM2x3, Matrix2x3,neg_op); +impl_neg_op!(NegateR2, RowVector2,neg_op); +impl_neg_op!(NegateR3, RowVector3,neg_op); +impl_neg_op!(NegateR4, RowVector4,neg_op); +impl_neg_op!(NegateRD, RowDVector,neg_vec_op); +impl_neg_op!(NegateVD, DVector,neg_vec_op); +impl_neg_op!(NegateMD, DMatrix,neg_vec_op); + +fn generate_neg_fxn(lhs_value: Value) -> Result, MechError> { + generate_urnop_match_arms!( + Negate, + (lhs_value), + I8 => MatrixI8, i8, i8::zero(); + I16 => MatrixI16, i16, i16::zero(); + I32 => MatrixI32, i32, i32::zero(); + I64 => MatrixI64, i64, i64::zero(); + I128 => MatrixI128, i128, i128::zero(); + F32 => MatrixF32, F32, F32::zero(); + F64 => MatrixF64, F64, F64::zero(); + ) +} + +impl_mech_urnop_fxn!(MathNegate,generate_neg_fxn); \ No newline at end of file diff --git a/src/syntax/src/stdlib/matrix.rs b/src/syntax/src/stdlib/matrix.rs index 53db7f28..bd05e49d 100644 --- a/src/syntax/src/stdlib/matrix.rs +++ b/src/syntax/src/stdlib/matrix.rs @@ -5,7 +5,6 @@ use crate::stdlib::*; // Matrix Library // ---------------------------------------------------------------------------- - // MatMul --------------------------------------------------------------------- macro_rules! mul_op { @@ -97,28 +96,7 @@ fn generate_matmul_fxn(lhs_value: Value, rhs_value: Value) -> Result) -> MResult> { - if arguments.len() != 2 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let lhs_value = arguments[0].clone(); - let rhs_value = arguments[1].clone(); - match generate_matmul_fxn(lhs_value.clone(), rhs_value.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (lhs_value,rhs_value) { - (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {generate_matmul_fxn(lhs.borrow().clone(), rhs.borrow().clone())} - (lhs_value,Value::MutableReference(rhs)) => { generate_matmul_fxn(lhs_value.clone(), rhs.borrow().clone())} - (Value::MutableReference(lhs),rhs_value) => { generate_matmul_fxn(lhs.borrow().clone(), rhs_value.clone()) } - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } -} +impl_mech_binop_fxn!(MatrixMatMul,generate_matmul_fxn); // Transpose ------------------------------------------------------------------ @@ -202,25 +180,7 @@ fn generate_transpose_fxn(lhs_value: Value) -> Result, Mec ) } -pub struct MatrixTranspose {} - -impl NativeFunctionCompiler for MatrixTranspose { - fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 1 { - return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); - } - let input = arguments[0].clone(); - match generate_transpose_fxn(input.clone()) { - Ok(fxn) => Ok(fxn), - Err(_) => { - match (input) { - (Value::MutableReference(input)) => {generate_transpose_fxn(input.borrow().clone())} - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), - } - } - } - } -} +impl_mech_urnop_fxn!(MatrixTranspose,generate_transpose_fxn); // Access --------------------------------------------------------------------- @@ -231,7 +191,38 @@ macro_rules! access_1d { macro_rules! access_2d { ($source:expr, $ix:expr, $out:expr) => { - unsafe { *$out = (*$source).index(((*$ix)[0]-1,(*$ix)[1]-1)).clone() } + unsafe { + let ix1 = (*$ix).0; + let ix2 = (*$ix).1; + *$out = (*$source).index((ix1-1,ix2-1)).clone() + } + };} + +macro_rules! access_1d_slice2 { + ($source:expr, $ix:expr, $out:expr) => { + unsafe { + (*$out)[0] = (*$source).index((*$ix)[0]-1).clone(); + (*$out)[1] = (*$source).index((*$ix)[1]-1).clone(); + } + };} + +macro_rules! access_1d_slice3 { + ($source:expr, $ix:expr, $out:expr) => { + unsafe { + (*$out)[0] = (*$source).index((*$ix)[0]-1).clone(); + (*$out)[1] = (*$source).index((*$ix)[1]-1).clone(); + (*$out)[2] = (*$source).index((*$ix)[2]-1).clone(); + } + };} + +macro_rules! access_2d_slice2 { + ($source:expr, $ix:expr, $out:expr) => { + unsafe { + (*$out)[0] = (*$source).index(((*$ix).0[0]-1,(*$ix).1[0]-1)).clone(); + (*$out)[1] = (*$source).index(((*$ix).0[1]-1,(*$ix).1[0]-1)).clone(); + (*$out)[2] = (*$source).index(((*$ix).0[0]-1,(*$ix).1[1]-1)).clone(); + (*$out)[3] = (*$source).index(((*$ix).0[1]-1,(*$ix).1[1]-1)).clone(); + } };} macro_rules! impl_access_fxn { @@ -257,135 +248,134 @@ macro_rules! impl_access_fxn { fn to_string(&self) -> String { format!("{:?}", self) } }};} -impl_access_fxn!(Access1DR2, RowVector2, usize, T, access_1d); -impl_access_fxn!(Access1DR3, RowVector3, usize, T, access_1d); -impl_access_fxn!(Access1DR4, RowVector4, usize, T, access_1d); -impl_access_fxn!(Access1DM2, Matrix2, usize, T, access_1d); -impl_access_fxn!(Access1DM3, Matrix3, usize, T, access_1d); -impl_access_fxn!(Access1DM2x3, Matrix2x3, usize, T, access_1d); -impl_access_fxn!(Access1DM3x2, Matrix3x2, usize, T, access_1d); -impl_access_fxn!(Access1DMD, DMatrix, usize, T, access_1d); -impl_access_fxn!(Access1DRD, RowDVector, usize, T, access_1d); -impl_access_fxn!(Access1DVD, DVector, usize, T, access_1d); - +impl_access_fxn!(Access1DSR2, RowVector2, usize, T, access_1d); +impl_access_fxn!(Access1DSR3, RowVector3, usize, T, access_1d); +impl_access_fxn!(Access1DSR4, RowVector4, usize, T, access_1d); +impl_access_fxn!(Access1DSM2, Matrix2, usize, T, access_1d); +impl_access_fxn!(Access1DSM3, Matrix3, usize, T, access_1d); +impl_access_fxn!(Access1DSM2x3, Matrix2x3, usize, T, access_1d); +impl_access_fxn!(Access1DSM3x2, Matrix3x2, usize, T, access_1d); +impl_access_fxn!(Access1DSMD, DMatrix, usize, T, access_1d); +impl_access_fxn!(Access1DSRD, RowDVector, usize, T, access_1d); +impl_access_fxn!(Access1DSVD, DVector, usize, T, access_1d); -impl_access_fxn!(Access2DR2, RowVector2, RowVector2, T, access_2d); -impl_access_fxn!(Access2DR3, RowVector3, RowVector2, T, access_2d); -impl_access_fxn!(Access2DR4, RowVector4, RowVector2, T, access_2d); -impl_access_fxn!(Access2DM2, Matrix2, RowVector2, T, access_2d); -impl_access_fxn!(Access2DM3, Matrix3, RowVector2, T, access_2d); -impl_access_fxn!(Access2DM2x3, Matrix2x3, RowVector2, T, access_2d); -impl_access_fxn!(Access2DM3x2, Matrix3x2, RowVector2, T, access_2d); -impl_access_fxn!(Access2DMD, DMatrix, RowVector2, T, access_2d); -impl_access_fxn!(Access2DRD, RowDVector, RowVector2, T, access_2d); -impl_access_fxn!(Access2DVD, DVector, RowVector2, T, access_2d); +impl_access_fxn!(Access2DSR2, RowVector2, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSR3, RowVector3, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSR4, RowVector4, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSM2, Matrix2, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSM3, Matrix3, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSM2x3, Matrix2x3, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSM3x2, Matrix3x2, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSMD, DMatrix, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSRD, RowDVector, (usize,usize), T, access_2d); +impl_access_fxn!(Access2DSVD, DVector, (usize,usize), T, access_2d); +impl_access_fxn!(Access1DR2RD, RowDVector, RowVector2, RowVector2, access_1d_slice2); +impl_access_fxn!(Access1DR3RD, RowDVector, RowVector3, RowVector3, access_1d_slice3); +impl_access_fxn!(Access2DR2M3, Matrix3, (RowVector2,RowVector2), Matrix2, access_2d_slice2); +impl_access_fxn!(Access2DR2DM, DMatrix, (RowVector2,RowVector2), Matrix2, access_2d_slice2); macro_rules! generate_access_match_arms { ($arg:expr, $($input_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr),+);+ $(;)?) => { match $arg { $( $( - (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DR4{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSR4{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector3(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DR3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::RowVector3(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSR3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector2(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DR2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::RowVector2(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSR2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DM2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSM2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DM3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSM3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DM2x3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSM2x3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix3x2(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DM3x2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3x2(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSM3x2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DMD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSMD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DRD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSRD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::DVector(input)), Value::Index(ix)) => { - Ok(Box::new(Access1DVD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::DVector(input)), [Value::Index(ix)]) => { + Ok(Box::new(Access1DSVD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DR4{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(input)), [Value::MatrixIndex(Matrix::RowVector2(ix))]) => { + Ok(Box::new(Access1DR2RD{source: input.clone(), ixes: ix.clone(), out: new_ref(RowVector2::from_element($default)) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector3(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DR3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(input)), [Value::MatrixIndex(Matrix::RowVector3(ix))]) => { + Ok(Box::new(Access1DR3RD{source: input.clone(), ixes: ix.clone(), out: new_ref(RowVector3::from_element($default)) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector2(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DR2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(input)), [Value::MatrixIndex(Matrix::RowVector2(ix1)), Value::MatrixIndex(Matrix::RowVector2(ix2))]) => { + Ok(Box::new(Access2DR2M3{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref(Matrix2::from_element($default)) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DM2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(input)), [Value::MatrixIndex(Matrix::RowVector2(ix1)), Value::MatrixIndex(Matrix::RowVector2(ix2))]) => { + Ok(Box::new(Access2DR2DM{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref(Matrix2::from_element($default)) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DM3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(input)), [Value::Index(ix1),Value::Index(ix2)]) => { + Ok(Box::new(Access2DSM2{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DM2x3{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(input)), [Value::Index(ix1),Value::Index(ix2)]) => { + Ok(Box::new(Access2DSM3{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix3x2(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DM3x2{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(input)), [Value::Index(ix1),Value::Index(ix2)]) => { + Ok(Box::new(Access2DSM2x3{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DMD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3x2(input)), [Value::Index(ix1),Value::Index(ix2)]) => { + Ok(Box::new(Access2DSM3x2{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref($default) })) }, - (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DRD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) - }, - (Value::$matrix_kind(Matrix::<$target_type>::DVector(input)), Value::MatrixIndex(Matrix::::RowVector2(ix))) => { - Ok(Box::new(Access2DVD{source: input.clone(), ixes: ix.clone(), out: new_ref($default) })) + (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(input)), [Value::Index(ix1),Value::Index(ix2)]) => { + Ok(Box::new(Access2DSMD{source: input.clone(), ixes: new_ref((ix1.borrow().clone(),ix2.borrow().clone())), out: new_ref($default) })) }, )+ )+ - x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), + x => Err(MechError { tokens: vec![], msg: format!("{:?}",x), id: 314, kind: MechErrorKind::UnhandledFunctionArgumentKind }), } } } -fn generate_access_fxn(lhs_value: Value, ixes: Value) -> Result, MechError> { +fn generate_access_fxn(lhs_value: Value, ixes: Vec) -> Result, MechError> { generate_access_match_arms!( - (lhs_value, ixes), + (lhs_value, ixes.as_slice()), Bool => MatrixBool, bool, false; - I8 => MatrixI8, i8, i8::zero(); - I16 => MatrixI16, i16, i16::zero(); - I32 => MatrixI32, i32, i32::zero(); - I64 => MatrixI64, i64, i64::zero(); + I8 => MatrixI8, i8, i8::zero(); + I16 => MatrixI16, i16, i16::zero(); + I32 => MatrixI32, i32, i32::zero(); + I64 => MatrixI64, i64, i64::zero(); I128 => MatrixI128, i128, i128::zero(); - U8 => MatrixU8, u8, u8::zero(); - U16 => MatrixU16, u16, u16::zero(); - U32 => MatrixU32, u32, u32::zero(); - U64 => MatrixU64, u64, u64::zero(); + U8 => MatrixU8, u8, u8::zero(); + U16 => MatrixU16, u16, u16::zero(); + U32 => MatrixU32, u32, u32::zero(); + U64 => MatrixU64, u64, u64::zero(); U128 => MatrixU128, u128, u128::zero(); - F32 => MatrixF32, F32, F32::zero(); - F64 => MatrixF64, F64, F64::zero(); + F32 => MatrixF32, F32, F32::zero(); + F64 => MatrixF64, F64, F64::zero(); ) } pub struct MatrixAccess {} - impl NativeFunctionCompiler for MatrixAccess { fn compile(&self, arguments: &Vec) -> MResult> { - if arguments.len() != 2 { + if arguments.len() <= 1 { return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); } - let source = arguments[0].clone(); - let ixes = arguments[1].clone(); - match generate_access_fxn(source.clone(), ixes.clone()) { + let ixes = arguments.clone().split_off(1); + let mat = arguments[0].clone(); + match generate_access_fxn(mat.clone(), ixes.clone()) { Ok(fxn) => Ok(fxn), Err(_) => { - match (source) { - (Value::MutableReference(source)) => {generate_access_fxn(source.borrow().clone(), ixes.clone())} + match (mat,ixes) { + (Value::MutableReference(lhs),rhs_value) => { generate_access_fxn(lhs.borrow().clone(), rhs_value.clone()) } x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), } } diff --git a/src/syntax/src/stdlib/mod.rs b/src/syntax/src/stdlib/mod.rs index 4a5e788d..a3fcdea6 100644 --- a/src/syntax/src/stdlib/mod.rs +++ b/src/syntax/src/stdlib/mod.rs @@ -7,7 +7,7 @@ use std::ops::*; use num_traits::*; use std::fmt::Debug; use simba::scalar::ClosedNeg; - +use num_traits::Pow; pub mod math; pub mod logic; @@ -96,7 +96,60 @@ macro_rules! impl_bool_urop { fn out(&self) -> Value { self.out.to_value() } fn to_string(&self) -> String { format!("{:?}", self) } }};} - + +#[macro_export] +macro_rules! impl_urop { + ($struct_name:ident, $arg_type:ty, $out_type:ty, $op:ident) => { + #[derive(Debug)] + struct $struct_name { + arg: Ref<$arg_type>, + out: Ref<$out_type>, + } + impl MechFunction for $struct_name { + fn solve(&self) { + let arg_ptr = self.arg.as_ptr(); + let out_ptr = self.out.as_ptr(); + $op!(arg_ptr,out_ptr); + } + fn out(&self) -> Value { self.out.to_value() } + fn to_string(&self) -> String { format!("{:?}", self) } + }};} + +#[macro_export] +macro_rules! generate_fxns { + ($lib:ident, $in:ident, $out:ident, $op:ident) => { + paste!{ + $op!([<$lib Scalar>], $in, $in, $out, [<$lib:lower _op>]); + $op!([<$lib SM2x3>], $in, Matrix2x3<$in>, Matrix2x3<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SM2>], $in, Matrix2<$in>, Matrix2<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SM3>], $in, Matrix3<$in>, Matrix3<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SR2>], $in, RowVector2<$in>, RowVector2<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SR3>], $in, RowVector3<$in>, RowVector3<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SR4>], $in, RowVector4<$in>, RowVector4<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SRD>], $in, RowDVector<$in>, RowDVector<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SVD>], $in, DVector<$in>, DVector<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib SMD>], $in, DMatrix<$in>, DMatrix<$out>,[<$lib:lower _scalar_rhs_op>]); + $op!([<$lib M2x3S>], Matrix2x3<$in>, $in, Matrix2x3<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib M2S>], Matrix2<$in>, $in, Matrix2<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib M3S>], Matrix3<$in>, $in, Matrix3<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib R2S>], RowVector2<$in>, $in, RowVector2<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib R3S>], RowVector3<$in>, $in, RowVector3<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib R4S>], RowVector4<$in>, $in, RowVector4<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib RDS>], RowDVector<$in>, $in, RowDVector<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib VDS>], DVector<$in>, $in, DVector<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib MDS>], DMatrix<$in>, $in, DMatrix<$out>,[<$lib:lower _scalar_lhs_op>]); + $op!([<$lib M2x3M2x3>], Matrix2x3<$in>, Matrix2x3<$in>, Matrix2x3<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib M2M2>], Matrix2<$in>, Matrix2<$in>, Matrix2<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib M3M3>], Matrix3<$in>,Matrix3<$in>, Matrix3<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib R2R2>], RowVector2<$in>, RowVector2<$in>, RowVector2<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib R3R3>], RowVector3<$in>, RowVector3<$in>, RowVector3<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib R4R4>], RowVector4<$in>, RowVector4<$in>, RowVector4<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib RDRD>], RowDVector<$in>, RowDVector<$in>, RowDVector<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib VDVD>], DVector<$in>, DVector<$in>, DVector<$out>, [<$lib:lower _vec_op>]); + $op!([<$lib MDMD>], DMatrix<$in>, DMatrix<$in>, DMatrix<$out>, [<$lib:lower _vec_op>]); + } + }} + #[macro_export] macro_rules! generate_binop_match_arms { ($lib:ident, $arg:expr, $($lhs_type:ident, $rhs_type:ident => $($matrix_kind:ident, $target_type:ident, $default:expr),+);+ $(;)?) => { @@ -108,6 +161,9 @@ macro_rules! generate_binop_match_arms { Ok(Box::new([<$lib Scalar>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref($default) }))}, (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(lhs)), Value::$matrix_kind(Matrix::<$target_type>::Matrix2(rhs))) => { Ok(Box::new([<$lib M2M2>]{lhs, rhs, out: new_ref(Matrix2::from_element($default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(lhs)), Value::$matrix_kind(Matrix::<$target_type>::Matrix3(rhs))) => { + Ok(Box::new([<$lib M3M3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))}))}, + (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(rhs))) => { Ok(Box::new([<$lib SM2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))}))}, (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::Matrix2(rhs))) => { @@ -118,15 +174,7 @@ macro_rules! generate_binop_match_arms { Ok(Box::new([<$lib SR3>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))}))}, (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::RowVector4(rhs))) => { Ok(Box::new([<$lib SR4>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))}))}, - (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::RowDVector(rhs))) => { - let length = {rhs.borrow().len()}; - Ok(Box::new([<$lib SRD>]{lhs, rhs, out: new_ref(RowDVector::from_element(length,$default))}))}, - (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::DVector(rhs))) => { - let length = {rhs.borrow().len()}; - Ok(Box::new([<$lib SVD>]{lhs, rhs, out: new_ref(DVector::from_element(length,$default))}))}, - (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::DMatrix(rhs))) => { - let (rows,cols) = {rhs.borrow().shape()}; - Ok(Box::new([<$lib SMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(lhs)),Value::$lhs_type(rhs)) => { Ok(Box::new([<$lib M2x3S>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))}))}, (Value::$matrix_kind(Matrix::<$target_type>::Matrix2(lhs)),Value::$lhs_type(rhs)) => { @@ -137,6 +185,17 @@ macro_rules! generate_binop_match_arms { Ok(Box::new([<$lib R3S>]{lhs, rhs, out: new_ref(RowVector3::from_element($default))}))}, (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(lhs)),Value::$lhs_type(rhs)) => { Ok(Box::new([<$lib R4S>]{lhs, rhs, out: new_ref(RowVector4::from_element($default))}))}, + + (Value::$matrix_kind(Matrix::<$target_type>::RowVector2(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowVector2(rhs))) => { + Ok(Box::new([<$lib R2R2>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector2::from_element($default)) }))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowVector3(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowVector3(rhs))) => { + Ok(Box::new([<$lib R3R3>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector3::from_element($default)) }))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowVector4(rhs))) => { + Ok(Box::new([<$lib R4R4>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector4::from_element($default)) }))}, + + (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(rhs))) => { + Ok(Box::new([<$lib M2x3M2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))}))}, + (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(lhs)),Value::$lhs_type(rhs)) => { let length = {lhs.borrow().len()}; Ok(Box::new([<$lib RDS>]{lhs, rhs, out: new_ref(RowDVector::from_element(length,$default))}))}, @@ -145,17 +204,16 @@ macro_rules! generate_binop_match_arms { Ok(Box::new([<$lib VDS>]{lhs, rhs, out: new_ref(DVector::from_element(length,$default))}))}, (Value::$matrix_kind(Matrix::<$target_type>::DMatrix(lhs)),Value::$lhs_type(rhs)) => { let (rows,cols) = {lhs.borrow().shape()}; - Ok(Box::new([<$lib MDS>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))}, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix3(lhs)), Value::$matrix_kind(Matrix::<$target_type>::Matrix3(rhs))) => { - Ok(Box::new([<$lib M3M3>]{lhs, rhs, out: new_ref(Matrix3::from_element($default))}))}, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector2(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowVector2(rhs))) => { - Ok(Box::new([<$lib R2R2>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector2::from_element($default)) }))}, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector3(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowVector3(rhs))) => { - Ok(Box::new([<$lib R3R3>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector3::from_element($default)) }))}, - (Value::$matrix_kind(Matrix::<$target_type>::RowVector4(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowVector4(rhs))) => { - Ok(Box::new([<$lib R4R4>]{lhs: lhs.clone(), rhs: rhs.clone(), out: new_ref(RowVector4::from_element($default)) }))}, - (Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(lhs)), Value::$matrix_kind(Matrix::<$target_type>::Matrix2x3(rhs))) => { - Ok(Box::new([<$lib M2x3M2x3>]{lhs, rhs, out: new_ref(Matrix2x3::from_element($default))}))}, + Ok(Box::new([<$lib MDS>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))}, + (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::RowDVector(rhs))) => { + let length = {rhs.borrow().len()}; + Ok(Box::new([<$lib SRD>]{lhs, rhs, out: new_ref(RowDVector::from_element(length,$default))}))}, + (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::DVector(rhs))) => { + let length = {rhs.borrow().len()}; + Ok(Box::new([<$lib SVD>]{lhs, rhs, out: new_ref(DVector::from_element(length,$default))}))}, + (Value::$lhs_type(lhs), Value::$matrix_kind(Matrix::<$target_type>::DMatrix(rhs))) => { + let (rows,cols) = {rhs.borrow().shape()}; + Ok(Box::new([<$lib SMD>]{lhs, rhs, out: new_ref(DMatrix::from_element(rows,cols,$default))}))}, (Value::$matrix_kind(Matrix::<$target_type>::RowDVector(lhs)), Value::$matrix_kind(Matrix::<$target_type>::RowDVector(rhs))) => { let length = {lhs.borrow().len()}; Ok(Box::new([<$lib RDRD>]{lhs, rhs, out: new_ref(RowDVector::from_element(length,$default))}))}, @@ -211,44 +269,157 @@ macro_rules! generate_urnop_match_arms { } } +#[macro_export] +macro_rules! impl_mech_binop_fxn { + ($fxn_name:ident, $gen_fxn:ident) => { + pub struct $fxn_name {} + impl NativeFunctionCompiler for $fxn_name { + fn compile(&self, arguments: &Vec) -> MResult> { + if arguments.len() != 2 { + return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); + } + let lhs_value = arguments[0].clone(); + let rhs_value = arguments[1].clone(); + match $gen_fxn(lhs_value.clone(), rhs_value.clone()) { + Ok(fxn) => Ok(fxn), + Err(_) => { + match (lhs_value,rhs_value) { + (Value::MutableReference(lhs),Value::MutableReference(rhs)) => {$gen_fxn(lhs.borrow().clone(), rhs.borrow().clone())} + (lhs_value,Value::MutableReference(rhs)) => { $gen_fxn(lhs_value.clone(), rhs.borrow().clone())} + (Value::MutableReference(lhs),rhs_value) => { $gen_fxn(lhs.borrow().clone(), rhs_value.clone()) } + x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), + } + } + } + } + } + } +} + +#[macro_export] +macro_rules! impl_mech_urnop_fxn { + ($fxn_name:ident, $gen_fxn:ident) => { + pub struct $fxn_name {} + impl NativeFunctionCompiler for $fxn_name { + fn compile(&self, arguments: &Vec) -> MResult> { + if arguments.len() != 1 { + return Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments}); + } + let input = arguments[0].clone(); + match $gen_fxn(input.clone()) { + Ok(fxn) => Ok(fxn), + Err(_) => { + match (input) { + (Value::MutableReference(input)) => {$gen_fxn(input.borrow().clone())} + x => Err(MechError { tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }), + } + } + } + } + } + } +} + // ---------------------------------------------------------------------------- // Type Conversion Library // ---------------------------------------------------------------------------- // Convert -------------------------------------------------------------------- -#[derive(Debug)] -struct ConvertScalar { - input: Ref, - out: Ref, +#[macro_export] +macro_rules! impl_convert_op { + ($struct_name:ident, $arg_type:ty, $out_type:ty, $out_type2:ty, $op:ident) => { + #[derive(Debug)] + + struct $struct_name { + arg: Ref<$arg_type>, + out: Ref<$out_type>, + } + impl MechFunction for $struct_name + where + Ref<$out_type>: ToValue + { + fn solve(&self) { + let arg_ptr = self.arg.as_ptr(); + let out_ptr = self.out.as_ptr(); + $op!(arg_ptr,out_ptr,$out_type2) + } + fn out(&self) -> Value { self.out.to_value() } + fn to_string(&self) -> String { format!("{:?}", self) } + } + } } -impl MechFunction for ConvertScalar -where - T: Copy + std::fmt::Debug, - U: Copy + std::fmt::Debug, - Ref: ToValue -{ - fn solve(&self) { - let in_value = self.input.borrow(); - let mut out_value = self.out.borrow_mut(); - unsafe { - *out_value = *(&*in_value as *const T as *const U); +macro_rules! convert_op1 { + ($arg:expr, $out:expr, $out_type:ty) => { + unsafe{ *$out = *$arg as $out_type } + };} + +macro_rules! convert_op2 { + ($arg:expr, $out:expr, $out_type:ty) => { + unsafe{ *$out = (*$arg).0 as $out_type } + };} + +macro_rules! convert_op3 { + ($arg:expr, $out:expr, $out_type:ty) => { + unsafe{ (*$out).0 = (*$arg) as $out_type } + };} + +macro_rules! convert_op4 { + ($arg:expr, $out:expr, $out_type:ty) => { + unsafe{ (*$out).0 = (*$arg).0 as $out_type } + };} + +macro_rules! impl_convert_op_group { + ($from:ty, [$($to:ty),*], $func:ident) => { + paste!{ + $( + impl_convert_op!([], $from, $to, [<$to:lower>], $func); + )* } - } - fn out(&self) -> Value { self.out.to_value() } - fn to_string(&self) -> String { format!("{:?}", self) } + }; } +impl_convert_op_group!(i8, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(i16, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(i32, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(i64, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(i128, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); + +impl_convert_op_group!(u8, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(u16, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(u32, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(u64, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); +impl_convert_op_group!(u128, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op1); + +impl_convert_op_group!(F32, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op2); +impl_convert_op_group!(F64, [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128], convert_op2); + +impl_convert_op_group!(i8, [F32, F64], convert_op3); +impl_convert_op_group!(i16, [F32, F64], convert_op3); +impl_convert_op_group!(i32, [F32, F64], convert_op3); +impl_convert_op_group!(i64, [F32, F64], convert_op3); +impl_convert_op_group!(i128, [F32, F64], convert_op3); +impl_convert_op_group!(u8, [F32, F64], convert_op3); +impl_convert_op_group!(u16, [F32, F64], convert_op3); +impl_convert_op_group!(u32, [F32, F64], convert_op3); +impl_convert_op_group!(u64, [F32, F64], convert_op3); +impl_convert_op_group!(u128, [F32, F64], convert_op3); + +impl_convert_op_group!(F32, [F32, F64], convert_op4); +impl_convert_op_group!(F64, [F32, F64], convert_op4); + macro_rules! generate_conversion_match_arms { - ($arg:expr, $($input_type:ident => $($value_kind:ident, $target_type:ident),+);+ $(;)?) => { - match $arg { - $( + ($arg:expr, $($input_type:ident => $($target_type:ident),+);+ $(;)?) => { + paste!{ + match $arg { $( - (Value::$input_type(arg), ValueKind::$value_kind) => {Ok(Box::new(ConvertScalar {input: arg.clone(),out: new_ref(0 as $target_type)}))}, + $( + (Value::[<$input_type:upper>](arg), ValueKind::[<$target_type:upper>]) => {Ok(Box::new([]{arg: arg.clone(), out: new_ref($target_type::zero())}))}, + )+ )+ - )+ - x => Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}), + x => Err(MechError {tokens: vec![], msg: file!().to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}), + } } } } @@ -256,16 +427,18 @@ macro_rules! generate_conversion_match_arms { fn generate_conversion_fxn(source_value: Value, target_kind: ValueKind) -> MResult> { generate_conversion_match_arms!( (source_value, target_kind), - I8 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - I16 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - I32 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - I64 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - I128 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - U8 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - U16 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - U32 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - U64 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; - U128 => I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128; + i8 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + i16 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + i32 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + i64 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + i128 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + u8 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + u16 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + u32 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + u64 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + u128 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + F32 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; + F64 => i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, F32, F64; ) } @@ -290,4 +463,4 @@ impl NativeFunctionCompiler for ConvertKind { } } } -} \ No newline at end of file +} diff --git a/src/syntax/src/types.rs b/src/syntax/src/types.rs index 2bb8270e..c11f6ec9 100644 --- a/src/syntax/src/types.rs +++ b/src/syntax/src/types.rs @@ -10,6 +10,7 @@ use std::iter::Step; use num_traits::*; use std::fmt::Debug; use std::hash::{Hash, Hasher}; +use libm::{pow,powf}; pub type FunctionsRef = Ref; pub type Plan = Ref>>; @@ -37,6 +38,14 @@ impl Hash for F64 { self.0.to_bits().hash(state); } } + +impl Pow for F64 { + type Output = F64; + fn pow(self, rhs: F64) -> Self::Output { + F64(self.0.powf(rhs.0)) + } +} + impl Add for F64 { type Output = F64; fn add(self, other: F64) -> F64 { @@ -136,6 +145,14 @@ impl F32 { F32(val) } } + +impl Pow for F32 { + type Output = F32; + fn pow(self, rhs: F32) -> Self::Output { + F32(self.0.pow(rhs.0)) + } +} + impl Eq for F32 {} impl Hash for F32 { fn hash(&self, state: &mut H) { diff --git a/src/syntax/src/value.rs b/src/syntax/src/value.rs index 080fceb3..a6085087 100644 --- a/src/syntax/src/value.rs +++ b/src/syntax/src/value.rs @@ -274,12 +274,21 @@ impl Value { pub fn as_veci32(&self) -> Option> {if let Value::MatrixI32(v) = self { Some(v.as_vec()) } else if let Value::MutableReference(val) = self { val.borrow().as_veci32() } else { None }} pub fn as_veci64(&self) -> Option> {if let Value::MatrixI64(v) = self { Some(v.as_vec()) } else if let Value::MutableReference(val) = self { val.borrow().as_veci64() } else { None }} pub fn as_veci128(&self) -> Option> {if let Value::MatrixI128(v) = self { Some(v.as_vec()) } else if let Value::MutableReference(val) = self { val.borrow().as_veci128() } else { None }} - pub fn as_vecusize(&self) -> Option> {if let Value::MatrixIndex(v) = self { Some(v.as_vec()) } else if let Value::MutableReference(val) = self { val.borrow().as_vecusize() } else { None }} + pub fn as_vecusize(&self) -> Option> { + match self { + Value::MatrixIndex(v) => Some(v.as_vec()), + Value::MatrixI64(v) => Some(v.as_vec().iter().map(|x| *x as usize).collect::>()), + _ => todo!(), + } + } - pub fn as_index(&self) -> Option { + pub fn as_index(&self) -> MResult { match self.as_usize() { - Some(ix) => Some(Value::Index(new_ref(ix))), - None => None, + Some(ix) => Ok(Value::Index(new_ref(ix))), + None => match self { + //Value::MatrixI64(x) => Ok(x.as_index()?), + _ => todo!(), + }, } } @@ -304,6 +313,12 @@ impl Value { } +pub trait ToIndex { + fn to_index(&self) -> Value; +} + +impl ToIndex for Ref> { fn to_index(&self) -> Value { (*self.borrow()).iter().map(|x| *x as usize).collect::>().to_value() } } + pub trait ToValue { fn to_value(&self) -> Value; } @@ -335,7 +350,7 @@ impl ToValue for Ref { fn to_value(&self) -> Value { Value::F32(self.clone( impl ToValue for Ref { fn to_value(&self) -> Value { Value::F64(self.clone()) } } impl ToValue for Ref { fn to_value(&self) -> Value { Value::Bool(self.clone()) } } -macro_rules! impl_to_value_matrix { +macro_rules! to_value_matrix { ($($nd_matrix_kind:ident, $matrix_kind:ident, $base_type:ty),+ $(,)?) => { $( impl ToValue for Ref<$nd_matrix_kind<$base_type>> { @@ -346,233 +361,42 @@ macro_rules! impl_to_value_matrix { )+ };} -impl_to_value_matrix!( - - Matrix2x3, MatrixIndex, usize, - Matrix2x3, MatrixBool, bool, - Matrix2x3, MatrixI8, i8, - Matrix2x3, MatrixI16, i16, - Matrix2x3, MatrixI32, i32, - Matrix2x3, MatrixI64, i64, - Matrix2x3, MatrixI128, i128, - Matrix2x3, MatrixU8, u8, - Matrix2x3, MatrixU16, u16, - Matrix2x3, MatrixU32, u32, - Matrix2x3, MatrixU64, u64, - Matrix2x3, MatrixU128, u128, - Matrix2x3, MatrixF32, F32, - Matrix2x3, MatrixF64, F64, - - Matrix3x2, MatrixIndex, usize, - Matrix3x2, MatrixBool, bool, - Matrix3x2, MatrixI8, i8, - Matrix3x2, MatrixI16, i16, - Matrix3x2, MatrixI32, i32, - Matrix3x2, MatrixI64, i64, - Matrix3x2, MatrixI128, i128, - Matrix3x2, MatrixU8, u8, - Matrix3x2, MatrixU16, u16, - Matrix3x2, MatrixU32, u32, - Matrix3x2, MatrixU64, u64, - Matrix3x2, MatrixU128, u128, - Matrix3x2, MatrixF32, F32, - Matrix3x2, MatrixF64, F64, - - Matrix1, MatrixIndex, usize, - Matrix1, MatrixBool, bool, - Matrix1, MatrixI8, i8, - Matrix1, MatrixI16, i16, - Matrix1, MatrixI32, i32, - Matrix1, MatrixI64, i64, - Matrix1, MatrixI128, i128, - Matrix1, MatrixU8, u8, - Matrix1, MatrixU16, u16, - Matrix1, MatrixU32, u32, - Matrix1, MatrixU64, u64, - Matrix1, MatrixU128, u128, - Matrix1, MatrixF32, F32, - Matrix1, MatrixF64, F64, - - Matrix2, MatrixIndex, usize, - Matrix2, MatrixBool, bool, - Matrix2, MatrixI8, i8, - Matrix2, MatrixI16, i16, - Matrix2, MatrixI32, i32, - Matrix2, MatrixI64, i64, - Matrix2, MatrixI128, i128, - Matrix2, MatrixU8, u8, - Matrix2, MatrixU16, u16, - Matrix2, MatrixU32, u32, - Matrix2, MatrixU64, u64, - Matrix2, MatrixU128, u128, - Matrix2, MatrixF32, F32, - Matrix2, MatrixF64, F64, - - Matrix3, MatrixIndex, usize, - Matrix3, MatrixBool, bool, - Matrix3, MatrixI8, i8, - Matrix3, MatrixI16, i16, - Matrix3, MatrixI32, i32, - Matrix3, MatrixI64, i64, - Matrix3, MatrixI128, i128, - Matrix3, MatrixU8, u8, - Matrix3, MatrixU16, u16, - Matrix3, MatrixU32, u32, - Matrix3, MatrixU64, u64, - Matrix3, MatrixU128, u128, - Matrix3, MatrixF32, F32, - Matrix3, MatrixF64, F64, - - Matrix4, MatrixIndex, usize, - Matrix4, MatrixBool, bool, - Matrix4, MatrixI8, i8, - Matrix4, MatrixI16, i16, - Matrix4, MatrixI32, i32, - Matrix4, MatrixI64, i64, - Matrix4, MatrixI128, i128, - Matrix4, MatrixU8, u8, - Matrix4, MatrixU16, u16, - Matrix4, MatrixU32, u32, - Matrix4, MatrixU64, u64, - Matrix4, MatrixU128, u128, - Matrix4, MatrixF32, F32, - Matrix4, MatrixF64, F64, - - Vector2, MatrixIndex, usize, - Vector2, MatrixBool, bool, - Vector2, MatrixI8, i8, - Vector2, MatrixI16, i16, - Vector2, MatrixI32, i32, - Vector2, MatrixI64, i64, - Vector2, MatrixI128, i128, - Vector2, MatrixU8, u8, - Vector2, MatrixU16, u16, - Vector2, MatrixU32, u32, - Vector2, MatrixU64, u64, - Vector2, MatrixU128, u128, - Vector2, MatrixF32, F32, - Vector2, MatrixF64, F64, - - Vector3, MatrixIndex, usize, - Vector3, MatrixBool, bool, - Vector3, MatrixI8, i8, - Vector3, MatrixI16, i16, - Vector3, MatrixI32, i32, - Vector3, MatrixI64, i64, - Vector3, MatrixI128, i128, - Vector3, MatrixU8, u8, - Vector3, MatrixU16, u16, - Vector3, MatrixU32, u32, - Vector3, MatrixU64, u64, - Vector3, MatrixU128, u128, - Vector3, MatrixF32, F32, - Vector3, MatrixF64, F64, - - Vector4, MatrixIndex, usize, - Vector4, MatrixBool, bool, - Vector4, MatrixI8, i8, - Vector4, MatrixI16, i16, - Vector4, MatrixI32, i32, - Vector4, MatrixI64, i64, - Vector4, MatrixI128, i128, - Vector4, MatrixU8, u8, - Vector4, MatrixU16, u16, - Vector4, MatrixU32, u32, - Vector4, MatrixU64, u64, - Vector4, MatrixU128, u128, - Vector4, MatrixF32, F32, - Vector4, MatrixF64, F64, - - RowVector2, MatrixIndex, usize, - RowVector2, MatrixBool, bool, - RowVector2, MatrixI8, i8, - RowVector2, MatrixI16, i16, - RowVector2, MatrixI32, i32, - RowVector2, MatrixI64, i64, - RowVector2, MatrixI128, i128, - RowVector2, MatrixU8, u8, - RowVector2, MatrixU16, u16, - RowVector2, MatrixU32, u32, - RowVector2, MatrixU64, u64, - RowVector2, MatrixU128, u128, - RowVector2, MatrixF32, F32, - RowVector2, MatrixF64, F64, - - RowVector3, MatrixIndex, usize, - RowVector3, MatrixBool, bool, - RowVector3, MatrixI8, i8, - RowVector3, MatrixI16, i16, - RowVector3, MatrixI32, i32, - RowVector3, MatrixI64, i64, - RowVector3, MatrixI128, i128, - RowVector3, MatrixU8, u8, - RowVector3, MatrixU16, u16, - RowVector3, MatrixU32, u32, - RowVector3, MatrixU64, u64, - RowVector3, MatrixU128, u128, - RowVector3, MatrixF32, F32, - RowVector3, MatrixF64, F64, - - RowVector4, MatrixIndex, usize, - RowVector4, MatrixBool, bool, - RowVector4, MatrixI8, i8, - RowVector4, MatrixI16, i16, - RowVector4, MatrixI32, i32, - RowVector4, MatrixI64, i64, - RowVector4, MatrixI128, i128, - RowVector4, MatrixU8, u8, - RowVector4, MatrixU16, u16, - RowVector4, MatrixU32, u32, - RowVector4, MatrixU64, u64, - RowVector4, MatrixU128, u128, - RowVector4, MatrixF32, F32, - RowVector4, MatrixF64, F64, - - RowDVector, MatrixIndex, usize, - RowDVector, MatrixBool, bool, - RowDVector, MatrixI8, i8, - RowDVector, MatrixI16, i16, - RowDVector, MatrixI32, i32, - RowDVector, MatrixI64, i64, - RowDVector, MatrixI128, i128, - RowDVector, MatrixU8, u8, - RowDVector, MatrixU16, u16, - RowDVector, MatrixU32, u32, - RowDVector, MatrixU64, u64, - RowDVector, MatrixU128, u128, - RowDVector, MatrixF32, F32, - RowDVector, MatrixF64, F64, - - DVector, MatrixIndex, usize, - DVector, MatrixBool, bool, - DVector, MatrixI8, i8, - DVector, MatrixI16, i16, - DVector, MatrixI32, i32, - DVector, MatrixI64, i64, - DVector, MatrixI128, i128, - DVector, MatrixU8, u8, - DVector, MatrixU16, u16, - DVector, MatrixU32, u32, - DVector, MatrixU64, u64, - DVector, MatrixU128, u128, - DVector, MatrixF32, F32, - DVector, MatrixF64, F64, - - DMatrix, MatrixIndex, usize, - DMatrix, MatrixBool, bool, - DMatrix, MatrixI8, i8, - DMatrix, MatrixI16, i16, - DMatrix, MatrixI32, i32, - DMatrix, MatrixI64, i64, - DMatrix, MatrixI128, i128, - DMatrix, MatrixU8, u8, - DMatrix, MatrixU16, u16, - DMatrix, MatrixU32, u32, - DMatrix, MatrixU64, u64, - DMatrix, MatrixU128, u128, - DMatrix, MatrixF32, F32, - DMatrix, MatrixF64, F64, -); +macro_rules! impl_to_value_matrix { + ($matrix_kind:ident) => { + to_value_matrix!( + $matrix_kind, MatrixIndex, usize, + $matrix_kind, MatrixBool, bool, + $matrix_kind, MatrixI8, i8, + $matrix_kind, MatrixI16, i16, + $matrix_kind, MatrixI32, i32, + $matrix_kind, MatrixI64, i64, + $matrix_kind, MatrixI128, i128, + $matrix_kind, MatrixU8, u8, + $matrix_kind, MatrixU16, u16, + $matrix_kind, MatrixU32, u32, + $matrix_kind, MatrixU64, u64, + $matrix_kind, MatrixU128, u128, + $matrix_kind, MatrixF32, F32, + $matrix_kind, MatrixF64, F64, + ); + } +} + +impl_to_value_matrix!(Matrix2x3); +impl_to_value_matrix!(Matrix3x2); +impl_to_value_matrix!(Matrix1); +impl_to_value_matrix!(Matrix2); +impl_to_value_matrix!(Matrix3); +impl_to_value_matrix!(Matrix4); +impl_to_value_matrix!(Vector2); +impl_to_value_matrix!(Vector3); +impl_to_value_matrix!(Vector4); +impl_to_value_matrix!(RowVector2); +impl_to_value_matrix!(RowVector3); +impl_to_value_matrix!(RowVector4); +impl_to_value_matrix!(RowDVector); +impl_to_value_matrix!(DVector); +impl_to_value_matrix!(DMatrix); // Set -------------------------------------------------------------------------- diff --git a/src/syntax/tests/interpreter.rs b/src/syntax/tests/interpreter.rs index 840f00d0..4150132c 100644 --- a/src/syntax/tests/interpreter.rs +++ b/src/syntax/tests/interpreter.rs @@ -43,7 +43,8 @@ test_interpreter!(interpret_formula_math_add, "2 + 2", Value::I64(new_ref(4))); test_interpreter!(interpret_formula_math_sub, "2 - 2", Value::I64(new_ref(0))); test_interpreter!(interpret_formula_math_mul, "2 * 2", Value::I64(new_ref(4))); test_interpreter!(interpret_formula_math_div, "2 / 2", Value::I64(new_ref(1))); -test_interpreter!(interpret_formula_math_exp, "2 ^ 2", Value::I64(new_ref(4))); +test_interpreter!(interpret_formula_math_exp, "2 ^ 2", Value::U8(new_ref(4))); +test_interpreter!(interpret_formula_math_exp_f64, "2.0 ^ 2.0", Value::F64(new_ref(F64::new(4.0)))); test_interpreter!(interpret_kind_annotation, "1", Value::U64(new_ref(1))); test_interpreter!(interpret_kind_annotation_math, "1 + 1", Value::U64(new_ref(2))); @@ -54,6 +55,7 @@ test_interpreter!(interpret_kind_matrix_row3, "[1 2 3]", Value::Matr test_interpreter!(interpret_kind_lhs_define, "x := 1", Value::U64(new_ref(1))); test_interpreter!(interpret_kind_lhs_define_overflow, "x := 256", Value::U8(new_ref(0))); test_interpreter!(interpret_kind_convert_twice, "x := 1; y := x", Value::I8(new_ref(1))); +test_interpreter!(interpret_kind_convert_float, "x := 123;", Value::F32(new_ref(F32::new(123.0)))); test_interpreter!(interpret_formula_math_neg, "-1", Value::I64(new_ref(-1))); test_interpreter!(interpret_formula_math_multiple_terms, "1 + 2 + 3", Value::I64(new_ref(6))); @@ -61,6 +63,7 @@ test_interpreter!(interpret_formula_comparison_bool, "true == false", Value::Boo test_interpreter!(interpret_formula_comparison_bool2, "true == true", Value::Bool(new_ref(true))); test_interpreter!(interpret_formula_comparison_eq, "10 == 11", Value::Bool(new_ref(false))); test_interpreter!(interpret_formula_comparison_neq, "10 != 11", Value::Bool(new_ref(true))); +test_interpreter!(interpret_formula_comparison_neq_bool, "false != true", Value::Bool(new_ref(true))); test_interpreter!(interpret_formula_comparison_gt, "10 > 11", Value::Bool(new_ref(false))); test_interpreter!(interpret_formula_comparison_lt, "10 < 11", Value::Bool(new_ref(true))); test_interpreter!(interpret_formula_comparison_gte, "10 >= 10", Value::Bool(new_ref(true))); @@ -122,9 +125,12 @@ test_interpreter!(interpret_tuple, "(1,true)", Value::Tuple(MechTuple::from_vec( test_interpreter!(interpret_tuple_nested, r#"(1,("Hello",false))"#, Value::Tuple(MechTuple::from_vec(vec![Value::I64(new_ref(1)), Value::Tuple(MechTuple::from_vec(vec![Value::String("Hello".to_string()), Value::Bool(new_ref(false))]))]))); test_interpreter!(interpret_slice, "a := [1,2,3]; a[2]", Value::I64(new_ref(2))); -test_interpreter!(interpret_slice_2d, "a := [1,2,3]; a[1,2]", Value::I64(new_ref(2))); +test_interpreter!(interpret_slice_2d, "a := [1,2;3,4]; a[1,2]", Value::I64(new_ref(2))); test_interpreter!(interpret_slice_f64, "a := [1.0,2.0,3.0]; a[2]", Value::F64(new_ref(F64::new(2.0)))); test_interpreter!(interpret_slice_2d_f64, "a := [1,2;3,4]; a[2,1]", Value::I64(new_ref(3))); +test_interpreter!(interpret_slice_range, "x := 4..10; x[1..=3]", Value::MatrixI64(Matrix::RowVector3(new_ref(RowVector3::from_vec(vec![4,5,6]))))); +test_interpreter!(interpret_slice_range_2d, "x := [1 2 3; 4 5 6; 7 8 9]; x[2..=3, 2..=3]", Value::MatrixI64(Matrix::Matrix2(new_ref(Matrix2::from_vec(vec![5,8,6,9]))))); + test_interpreter!(interpret_set_empty,"{_}", Value::Set(MechSet::from_vec(vec![]))); test_interpreter!(interpret_set,"{1,2,3}", Value::Set(MechSet::from_vec(vec![Value::I64(new_ref(1)),Value::I64(new_ref(2)),Value::I64(new_ref(3))]))); @@ -144,5 +150,7 @@ test_interpreter!(interpret_function_define_statements,r#"foo(x, y) = z := a + b. foo(10,20)"#, Value::I64(new_ref(32))); +test_interpreter!(interpret_function_call_native_vector,"math/sin([1.570796327 1.570796327])", new_ref(RowVector2::from_vec(vec![F64::new(1.0),F64::new(1.0)])).to_value()); test_interpreter!(interpret_function_call_native,r#"math/sin(1.5707963267948966)"#, Value::F64(new_ref(F64::new(1.0)))); -test_interpreter!(interpret_function_call_native_cos,r#"math/cos(0.0)"#, Value::F64(new_ref(F64::new(1.0)))); \ No newline at end of file +test_interpreter!(interpret_function_call_native_cos,r#"math/cos(0.0)"#, Value::F64(new_ref(F64::new(1.0)))); +test_interpreter!(interpret_function_call_native_vector2,"math/cos([0.0 0.0])", new_ref(RowVector2::from_vec(vec![F64::new(1.0),F64::new(1.0)])).to_value()); \ No newline at end of file