Skip to content

Instantly share code, notes, and snippets.

@durka
Forked from anonymous/playground.rs
Last active April 13, 2016 23:50
Show Gist options
  • Save durka/1178ce4e8dbea3d71b49 to your computer and use it in GitHub Desktop.
Save durka/1178ce4e8dbea3d71b49 to your computer and use it in GitHub Desktop.
Rust macros: counting with an accumulator
// cargo-deps: lazy_static
#[macro_use] extern crate lazy_static;
macro_rules! declare_array {
// INTERNAL
// last element (proceed to output)
(@parse $size:expr, ($val:expr) -> [$($accs:expr),*] $thru:tt) => {
declare_array!(@output $size + 1usize, [$($accs,)* $val] $thru);
};
// more elements (keep parsing)
(@parse $size:expr, ($val:expr, $($vals:expr),*) -> [$($accs:expr),*] $thru:tt) => {
declare_array!(@parse $size + 1usize, ($($vals),*) -> [$($accs,)* $val] $thru);
};
// output a local variable
(@output $size:expr, $acc:tt (() let $n:ident $t:ty)) => {
declare_array!(@as_stmt let $n: [$t; $size] = $acc)
};
// output a lazy static
(@output $size:expr, $acc:tt (($($p:tt)*) lazy_static $n:ident $t:ty)) => {
lazy_static!{ $($p)* static ref $n: [$t; $size] = $acc; }
};
// output a static or const item
(@output $size:expr, $acc:tt (($($p:tt)*) $s:ident $n:ident $t:ty)) => {
declare_array!(@as_item $($p)* $s $n: [$t; $size] = $acc;);
};
// screw you, lexer
(@as_stmt $s:stmt) => ($s);
(@as_item $i:item) => ($i);
// EXTERNAL
// entry point
(pub $restr:tt $storage:ident $n:ident: [$t:ty; _] = [$($vals:expr),* $(,)*]) => {
declare_array!(@parse 0usize, ($($vals),*) -> [] ((pub $restr) $storage $n $t));
};
(pub $storage:ident $n:ident: [$t:ty; _] = [$($vals:expr),* $(,)*]) => {
declare_array!(@parse 0usize, ($($vals),*) -> [] ((pub) $storage $n $t));
};
($storage:ident $n:ident: [$t:ty; _] = [$($vals:expr),* $(,)*]) => {
declare_array!(@parse 0usize, ($($vals),*) -> [] (() $storage $n $t));
};
}
use std::time::{SystemTime, UNIX_EPOCH};
declare_array!(const ARR: [i32; _] = [1, 2, 3]);
declare_array!(lazy_static LAZY: [u64; _] = [3, 2, SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()]);
fn main() {
declare_array!(let arr: [i32; _] = [4, 5, 6]);
declare_array!(static LOCAL_ARR: [i32; _] = [7, 8, 9, 10]);
println!("{:?}", ARR);
println!("{:?}", arr);
println!("{:?}", LOCAL_ARR);
println!("{:?}", *LAZY);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment