Skip to content

Instantly share code, notes, and snippets.

@thibault-cne
Last active March 19, 2024 23:39
Show Gist options
  • Save thibault-cne/a50078771214ee2282baf3701a454b16 to your computer and use it in GitHub Desktop.
Save thibault-cne/a50078771214ee2282baf3701a454b16 to your computer and use it in GitHub Desktop.
introduction_to_rust_declarative_macros
macro_rules! rpn {
{ @inner_op stack [$r:expr, $l:expr $(, $stack:expr)*]; $op:tt $($tt:tt)* } => {
rpn! { @inner stack [$l $op $r $(, $stack)*]; $($tt)* }
};
{ @inner stack [$res:expr]; } => { $res };
{ @inner stack $stack:tt; + $($tt:tt)* } => {
rpn!{ @inner_op stack $stack; + $($tt)* }
};
{ @inner stack $stack:tt; - $($tt:tt)* } => {
rpn!{ @inner_op stack $stack; - $($tt)* }
};
{ @inner stack $stack:tt; * $($tt:tt)* } => {
rpn!{ @inner_op stack $stack; * $($tt)* }
};
{ @inner stack $stack:tt; / $($tt:tt)* } => {
rpn!{ @inner_op stack $stack; / $($tt)* }
};
{ @inner stack [$($stack:expr),*]; $num:tt $($tt:tt)* } => {
rpn!{ @inner stack [$num $(, $stack)*]; $($tt)* }
};
{ $($tt:tt)* } => {
rpn!{ @inner stack [ ]; $($tt)* }
};
}
fn main() {
assert_eq! { rpn! {3 4 +}, 7};
assert_eq! { rpn! {3 4 + 5 +}, 12};
assert_eq! { rpn! {3 4 5 + *}, 27};
assert_eq! { rpn! {15 7 1 1 + - / 3 * 2 1 1 + + -}, 5};
}
macro_rules! pow {
(squared $n:expr) => {
$n.pow(2)
};
(cubed $n:expr) => {
$n.pow(3)
};
}
macro_rules! adder {
() => { 0 };
($($n:expr),*) => {
{
let mut sum = 0;
$(
sum += $n;
)*
sum
}
};
}
macro_rules! calculator {
{add $($add:expr),*; mul $($mul:expr),*} => {
{
let mut sum = 0;
let mut mul = 1;
$(
sum += $add;
)*
$(
mul *= $mul;
)*
(sum, mul)
}
}
}
fn main() {
assert_eq!(pow!(squared 2_i32), 4);
assert_eq!(pow!(cubed 2_i32), 8);
assert_eq!(adder!(1, 2, 3, 4), 10);
assert_eq!(adder!(1), 1);
assert_eq!(adder!(), 0);
assert_eq!(calculator!(add 1, 2, 3; mul 1, 2, 3), (6, 6));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment