142 lines
4.5 KiB
Rust
142 lines
4.5 KiB
Rust
use proc_macro2::Ident;
|
|
use quote::quote;
|
|
use syn::{Path, Token};
|
|
|
|
pub(crate) struct MatWrapper {
|
|
pub column_type: Ident,
|
|
}
|
|
|
|
impl MatWrapper {
|
|
pub fn to_field_tokens(&self, wrapped_path: &Path, wrapper_ident: &Ident) -> proc_macro2::TokenStream {
|
|
quote! {
|
|
builder.field("ZERO", #wrapper_ident(#wrapped_path::ZERO));
|
|
builder.field("IDENTITY", #wrapper_ident(#wrapped_path::IDENTITY));
|
|
builder.field("NAN", #wrapper_ident(#wrapped_path::NAN));
|
|
}
|
|
}
|
|
|
|
pub fn to_method_tokens(&self, wrapped_path: &Path, wrapper_ident: &Ident) -> proc_macro2::TokenStream {
|
|
let column_type = &self.column_type;
|
|
|
|
let column_size = {
|
|
let ty_str = column_type.to_string();
|
|
ty_str[ty_str.len() - 1..].parse::<usize>()
|
|
.expect("Failure to parse number from token type")
|
|
};
|
|
let column_size_xtwo = column_size * 2;
|
|
|
|
let element_ty = quote!(f32);
|
|
|
|
quote! {
|
|
builder.function("from_cols",
|
|
|_, (x_axis, y_axis): (#column_type, #column_type)| {
|
|
Ok(#wrapper_ident(#wrapped_path::from_cols(x_axis.0, y_axis.0)))
|
|
});
|
|
|
|
builder.function("from_cols_array",
|
|
|_, (arr,): ([#element_ty; #column_size_xtwo],)| {
|
|
Ok(#wrapper_ident(#wrapped_path::from_cols_array(&arr)))
|
|
});
|
|
|
|
builder.function("from_cols_array_2d",
|
|
|_, (arr,): ([[#element_ty; #column_size]; #column_size],)| {
|
|
Ok(#wrapper_ident(#wrapped_path::from_cols_array_2d(&arr)))
|
|
});
|
|
|
|
builder.function("from_diagonal",
|
|
|_, (diag,): (#column_type,)| {
|
|
Ok(#wrapper_ident(#wrapped_path::from_diagonal(diag.0)))
|
|
});
|
|
|
|
builder.method("col",
|
|
|_, this, (idx,): (usize,)| {
|
|
Ok(#column_type(this.col(idx)))
|
|
});
|
|
|
|
builder.method("row",
|
|
|_, this, (idx,): (usize,)| {
|
|
Ok(#column_type(this.row(idx)))
|
|
});
|
|
|
|
builder.method_mut("set_col",
|
|
|_, this, (idx, newc): (usize, #column_type)| {
|
|
let col = this.col_mut(idx);
|
|
*col = newc.0;
|
|
|
|
Ok(())
|
|
});
|
|
|
|
builder.method("is_finite",
|
|
|_, this, (): ()| {
|
|
Ok(this.is_finite())
|
|
});
|
|
|
|
builder.method("is_nan",
|
|
|_, this, (): ()| {
|
|
Ok(this.is_nan())
|
|
});
|
|
|
|
builder.method("transpose",
|
|
|_, this, (): ()| {
|
|
Ok(#wrapper_ident(this.0.transpose()))
|
|
});
|
|
|
|
builder.method("determinant",
|
|
|_, this, (): ()| {
|
|
Ok(this.determinant())
|
|
});
|
|
|
|
builder.method("inverse",
|
|
|_, this, (): ()| {
|
|
Ok(#wrapper_ident(this.inverse()))
|
|
});
|
|
|
|
builder.method("abs_diff_eq",
|
|
|_, this, (rhs, max_abs_diff): (#wrapper_ident, f32)| {
|
|
Ok(this.abs_diff_eq(rhs.0, max_abs_diff))
|
|
});
|
|
|
|
// TODO: After all DMat's are implemented
|
|
/* builder.method("as_dmat",
|
|
|_, this, (rhs, max_abs_diff): (#wrapper_ident, f32)| {
|
|
Ok(D#wrapper_ident(this.as_dmat))
|
|
}); */
|
|
}
|
|
}
|
|
}
|
|
|
|
impl syn::parse::Parse for MatWrapper {
|
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
|
let mut column_type = None;
|
|
|
|
// cba to remove the use of this bool
|
|
let mut first = true;
|
|
|
|
while input.peek(Token![,]) || first {
|
|
if !first {
|
|
let _: Token![,] = input.parse()?;
|
|
}
|
|
|
|
if input.peek(syn::Ident) {
|
|
let ident: Ident = input.parse()?;
|
|
let ident_str = ident.to_string();
|
|
let ident_str = ident_str.as_str();
|
|
|
|
match ident_str {
|
|
"col_type" => {
|
|
let _eq: Token![=] = input.parse()?;
|
|
column_type = Some(input.parse()?);
|
|
},
|
|
_ => return Err(syn::Error::new_spanned(ident, "unknown matrix wrapper command")),
|
|
}
|
|
}
|
|
|
|
first = false;
|
|
}
|
|
|
|
Ok(Self {
|
|
column_type: column_type.ok_or_else(|| syn::Error::new(input.span(),
|
|
"expected `col_type`"))?,
|
|
})
|
|
}
|
|
} |