mech_string/
lib.rs

1#![no_main]
2#![allow(warnings)]
3#[macro_use]
4extern crate mech_core;
5extern crate paste;
6
7use mech_core::*;
8
9#[cfg(feature = "vector3")]
10use nalgebra::Vector3;
11#[cfg(feature = "vectord")]
12use nalgebra::DVector;
13#[cfg(feature = "vector2")]
14use nalgebra::Vector2;
15#[cfg(feature = "vector4")]
16use nalgebra::Vector4;
17#[cfg(feature = "rowdvector")]
18use nalgebra::RowDVector;
19#[cfg(feature = "row_vectord")]
20use nalgebra::RowDVector;
21#[cfg(feature = "matrix1")]
22use nalgebra::Matrix1;
23#[cfg(feature = "matrix3")]
24use nalgebra::Matrix3;
25#[cfg(feature = "matrix4")]
26use nalgebra::Matrix4;
27#[cfg(feature = "row_vector3")]
28use nalgebra::RowVector3;
29#[cfg(feature = "row_vector4")]
30use nalgebra::RowVector4;
31#[cfg(feature = "row_vector2")]
32use nalgebra::RowVector2;
33#[cfg(feature = "matrixd")]
34use nalgebra::DMatrix;
35#[cfg(feature = "matrix2x3")]
36use nalgebra::Matrix2x3;
37#[cfg(feature = "matrix3x2")]
38use nalgebra::Matrix3x2;
39#[cfg(feature = "matrix2")]
40use nalgebra::Matrix2;
41
42use paste::paste;
43
44#[cfg(feature = "concat")]
45pub mod concat;
46
47#[cfg(feature = "concat")]
48pub use self::concat::*;
49
50// ----------------------------------------------------------------------------
51// String Library
52// ----------------------------------------------------------------------------
53
54pub trait Concat {
55  fn concat(&self, rhs: &Self) -> Self;
56}
57
58impl Concat for String {
59  fn concat(&self, rhs: &Self) -> Self {
60    let mut s = self.clone();
61    s.push_str(rhs);
62    s
63  }
64}
65
66#[macro_export]
67macro_rules! impl_string_binop {
68  ($struct_name:ident, $arg1_type:ty, $arg2_type:ty, $out_type:ty, $op:ident, $feature_flag:expr) => {
69    #[derive(Debug)]
70    struct $struct_name<T> {
71      lhs: Ref<$arg1_type>,
72      rhs: Ref<$arg2_type>,
73      out: Ref<$out_type>,
74    }
75    impl<T> MechFunctionFactory for $struct_name<T>
76    where
77      T: std::fmt::Debug + Clone + Sync + Send + 'static + 
78      ConstElem + CompileConst + AsValueKind + Concat,
79      Ref<$out_type>: ToValue
80    {
81      fn new(args: FunctionArgs) -> MResult<Box<dyn MechFunction>> {
82        match args {
83          FunctionArgs::Binary(out, arg1, arg2) => {
84            let lhs: Ref<$arg1_type> = unsafe { arg1.as_unchecked() }.clone();
85            let rhs: Ref<$arg2_type> = unsafe { arg2.as_unchecked() }.clone();
86            let out: Ref<$out_type> = unsafe { out.as_unchecked() }.clone();
87            Ok(Box::new(Self {lhs, rhs, out }))
88          },
89          _ => Err(MechError2::new(
90              IncorrectNumberOfArguments { expected: 2, found: args.len() }, 
91              None
92            ).with_compiler_loc()
93          ),
94        }
95      }
96    }
97    impl<T> MechFunctionImpl for $struct_name<T>
98    where
99      T: std::fmt::Debug + Clone + Sync + Send + 'static + Concat,
100      Ref<$out_type>: ToValue
101    {
102    fn solve(&self) {
103      let lhs_ptr = self.lhs.as_ptr();
104      let rhs_ptr = self.rhs.as_ptr();
105      let out_ptr = self.out.as_mut_ptr();
106      $op!(lhs_ptr,rhs_ptr,out_ptr);
107    }
108    fn out(&self) -> Value { self.out.to_value() }
109    fn to_string(&self) -> String { format!("{:#?}", self) }
110  }
111  #[cfg(feature = "compiler")]
112  impl<T> MechFunctionCompiler for $struct_name<T> 
113  where
114    T: ConstElem + CompileConst + AsValueKind
115  {
116    fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
117      let name = format!("{}<{}>", stringify!($struct_name), T::as_value_kind());
118      compile_binop!(name, self.out, self.lhs, self.rhs, ctx, $feature_flag);
119    }
120  }
121  register_fxn_descriptor!($struct_name, String, "string");
122};}
123
124#[macro_export]
125macro_rules! impl_string_fxns {
126  ($lib:ident) => {
127    impl_fxns!($lib,T,T,impl_string_binop);
128  }
129}