I'm starting playing with Rust macros and I came to try this little practice example. I want to define a macro that expands into a variable initialization (name doesn't matter) of type i32
(for example, but not really important) and a series of operations to that variable, in this case a var += 1
or a var -= 1
and finally it will call println!("{}", var)
.
The macro will take a series of tokens based on +
and -
that matches the operations described above.
So for example:
operate_integer![+++---]
would expand to:
let mut var: i32 = 0;
var += 1;
var += 1;
var += 1;
var -= 1;
var -= 1;
var -= 1;
print!("{}", var);
I decided to use 2 macros for this, one for wrapping the initialization and the printing and the other to evaluate the +-
tokens:
The base one would be:
macro_rules! operate_integer {
// $($all_tokens:tt)* should match everything, it will be forward to the helper macro
($($all_tokens:tt)*) => {
let mut var : i32 = 0;
operate_integer_helper![$($all_tokens:tt)*]
print!("{}", var);
}
}
The helper would expand the operations:
macro_rules! operate_integer_helper {
// the idea is that it matches a `+` followed by more tokens
(+$($t:tt)*) => {
val += 1;
operate_integer_helper![$($t:tt)*] // we recursively handle the remaining tokens
}
(-$($t:tt)*) => {
val -= 1;
operate_integer_helper![$($t:tt)*]
}
}
This of course do not work, it fails compilation with the following error (Playground):
error: no rules expected the token `(`
--> src/lib.rs:102:5
|
102 | (+$($t:tt)*) => {
| ^ no rules expected this token in macro call
I'm kind of stuck. I know I may be missing many concepts since I just started and I would really appreciate some help understanding how to work with macros. Thank you in advance!