feat: multiple lessons
This commit is contained in:
103
src/macros.rs
Normal file
103
src/macros.rs
Normal file
@@ -0,0 +1,103 @@
|
||||
// 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user