Last active
March 19, 2024 23:39
-
-
Save thibault-cne/a50078771214ee2282baf3701a454b16 to your computer and use it in GitHub Desktop.
introduction_to_rust_declarative_macros
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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