104 lines
2.4 KiB
Rust
104 lines
2.4 KiB
Rust
// Group functionality with different types
|
|
// Define special syntac for specific purpose
|
|
// Variable number of arguments
|
|
// Different combination of arguments
|
|
macro_rules! say_hello {
|
|
() => {
|
|
println!("Hello world!");
|
|
};
|
|
}
|
|
|
|
// Types of arguments have designators:
|
|
// block
|
|
// expr is used for expressions
|
|
// ident is used for variable/function names
|
|
// item
|
|
// literal is used for literal constants
|
|
// pat (pattern)
|
|
// path
|
|
// stmt (statement)
|
|
// tt (token tree)
|
|
// ty (type)
|
|
// vis (visibility qualifier)
|
|
macro_rules! generate_function {
|
|
($func_name:ident) => {
|
|
fn $func_name() {
|
|
println!("You called {:?}()", stringify!($func_name));
|
|
}
|
|
};
|
|
}
|
|
|
|
generate_function!(foo);
|
|
|
|
macro_rules! process_expression {
|
|
($expression: expr) => {
|
|
println!("{:?} = {:?}", stringify!($expression), $expression);
|
|
};
|
|
}
|
|
|
|
// Overload
|
|
macro_rules! match_block {
|
|
($left: expr; and $right: expr) => {
|
|
println!("A: {:?} and {:?}", stringify!($left), stringify!($right))
|
|
};
|
|
|
|
($left: expr; or $right:expr) => {
|
|
println!(
|
|
"B: {:?} or {:?} is {:?}",
|
|
stringify!($left),
|
|
stringify!($right),
|
|
$left || $right
|
|
)
|
|
};
|
|
}
|
|
|
|
// Repeat: variable number of args o a type
|
|
macro_rules! find_max {
|
|
($x:expr) => ($x);
|
|
($x:expr, $($y:expr), +) => (std::cmp::max($x, find_max!($($y), +)));
|
|
}
|
|
|
|
// DSLs: Domain Specific Languages
|
|
// macro_rules allows you to create your own syntax
|
|
macro_rules! calc {
|
|
(eval $e:expr) => {
|
|
println!("{} = {}", stringify!($e), $e);
|
|
};
|
|
}
|
|
|
|
macro_rules! calculate {
|
|
(eval $e: expr) => {
|
|
{
|
|
let val: usize = $e; // Force types to be integers
|
|
println!("{} = {}", stringify!{$e}, val);
|
|
}
|
|
};
|
|
(eval $e: expr, $(eval $y: expr), +) => {{
|
|
calculate!{eval $e}
|
|
calculate!{ $(eval $y), + }
|
|
}};
|
|
}
|
|
|
|
pub fn macros_rule() {
|
|
foo();
|
|
say_hello!();
|
|
process_expression!(1 + 5 * 3);
|
|
|
|
match_block!(1i32 + 1 == 2i32; and 2i32 * 2 == 4i32); // Enters first branch
|
|
match_block!(true; or false); // Enter second branch
|
|
match_block!(true; and true); // Enters first branch
|
|
|
|
println!("Max is {}", find_max!(5, 3 * 8, 4, 9 * 5));
|
|
|
|
calc! {
|
|
eval (1 + 2) * 4
|
|
}
|
|
|
|
calculate! {
|
|
eval (1 + 2) * 4,
|
|
eval 1 + 5,
|
|
eval 7 + 4,
|
|
eval 3 + 9
|
|
}
|
|
}
|