forked from M-Labs/nalgebra
Initial hacked together prototype without syn
This commit is contained in:
parent
e8d00887e0
commit
e97692255b
@ -92,7 +92,7 @@ matrixcompare = "0.2.0"
|
|||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse" ]
|
members = [ "nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse", "nalgebra-macros" ]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
|
16
nalgebra-macros/Cargo.toml
Normal file
16
nalgebra-macros/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "nalgebra-macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Andreas Longva <andreas.b.longva@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "1.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
nalgebra = { version = "0.25.4", path = ".." }
|
99
nalgebra-macros/src/lib.rs
Normal file
99
nalgebra-macros/src/lib.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
use proc_macro::{TokenStream, TokenTree, Literal, Ident, Punct, Spacing, Group, Delimiter};
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
struct MatrixEntries {
|
||||||
|
entries: Vec<Vec<TokenTree>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MatrixEntries {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
entries: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn begin_new_row(&mut self) {
|
||||||
|
self.entries.push(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_entry(&mut self, entry: TokenTree) {
|
||||||
|
if self.entries.is_empty() {
|
||||||
|
self.entries.push(Vec::new());
|
||||||
|
}
|
||||||
|
let mut last_row = self.entries.last_mut().unwrap();
|
||||||
|
last_row.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_stream(&self) -> TokenStream {
|
||||||
|
let num_rows = self.entries.len();
|
||||||
|
let num_cols = self.entries.first()
|
||||||
|
.map(|first_row| first_row.len())
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
// First check that dimensions are consistent
|
||||||
|
for (i, row) in self.entries.iter().enumerate() {
|
||||||
|
if row.len() != num_cols {
|
||||||
|
panic!("Unexpected number of columns in row {}: {}. Expected {}", i, row.len(), num_cols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut array_tokens = Vec::new();
|
||||||
|
|
||||||
|
// Collect entries in column major order
|
||||||
|
for i in 0 .. num_rows {
|
||||||
|
for j in 0 .. num_cols {
|
||||||
|
let entry = &self.entries[i][j];
|
||||||
|
array_tokens.push(entry.clone());
|
||||||
|
array_tokens.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let row_dim = format!("U{}", num_rows);
|
||||||
|
let col_dim = format!("U{}", num_cols);
|
||||||
|
// let imports = format!("use nalgebra::\{Matrix, {}, {}\};", row_dim, col_dim);
|
||||||
|
// let constructor = format!("Matrix::<_, {}, {}>::from_slice", row_dim, col_dim);
|
||||||
|
// let array_group = Group::new(Delimiter::Bracket, TokenStream::from_iter(array_tokens.into_iter()));
|
||||||
|
|
||||||
|
let array_stream = TokenStream::from_iter(array_tokens);
|
||||||
|
|
||||||
|
// TODO: Build this up without parsing?
|
||||||
|
format!(r"{{
|
||||||
|
nalgebra::MatrixMN::<_, nalgebra::{row_dim}, nalgebra::{col_dim}>::from_column_slice(&[
|
||||||
|
{array_tokens}
|
||||||
|
])
|
||||||
|
}}", row_dim=row_dim, col_dim=col_dim, array_tokens=array_stream.to_string()).parse().unwrap()
|
||||||
|
|
||||||
|
|
||||||
|
// let mut outer_group = Group::new(Delimiter::Brace,
|
||||||
|
//
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Outer group
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn matrix(stream: TokenStream) -> TokenStream {
|
||||||
|
let mut entries = MatrixEntries::new();
|
||||||
|
for tree in stream {
|
||||||
|
match tree {
|
||||||
|
// TokenTree::Ident(ident) => entries.push_entry(tree),
|
||||||
|
// TokenTree::Literal(literal) => entries.push_entry(tree),
|
||||||
|
TokenTree::Punct(punct) if punct == ';' => entries.begin_new_row(),
|
||||||
|
TokenTree::Punct(punct) if punct == ',' => {},
|
||||||
|
// TokenTree::Punct(punct) => panic!("Unexpected punctuation: '{}'", punct),
|
||||||
|
// TokenTree::Group(_) => panic!("Unexpected token group"),
|
||||||
|
_ => entries.push_entry(tree)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.build_stream()
|
||||||
|
}
|
6
nalgebra-macros/tests/tests.rs
Normal file
6
nalgebra-macros/tests/tests.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use nalgebra_macros::matrix;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_usage() {
|
||||||
|
matrix![ 1, 3; 4, 5*3];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user