How do we express if / match in macro_rules! ?
step 1: let us rewrite all if
as match
; so our problem is now: how do we express match in macro_rules! ?
Consider
match a {
... => match b { ... }
}
how do we express match b { ... }
?
It seems the way to do this is:
match b { ... } -> self! ( @some_token b )
here self
is the name of the macro and @some_token
is some unique token
then we do the actual match at the top level, by adding arms
(@some_token pat1) => { ... }
(@some_token pat2) => { ... }
===
So basically, the way to write nested match is:
-
for every match, create an unique token
-
for every match, recurse to self, appending unique token
-
for every arm of every match, add a line of the form
@some_token pat_N => { ... }
===
So basically we "flatten" all match to the top level, and make nested match "call top level via calling self! w/ @unique_token"
===
I'm not sure if this makes sense -- does this sound about right or dealing with nested match in macro_rules! ?
your problem description is cryptic, I don't know what you are trying to achieve. it would be helpful if you could provide some examples, like how the macro is supposed to used, and what the expected expansion should look like, stuff like such.
1 Like
Sorry, the question I meant to ask is:
-
in traditional languages, we have nested if/match all the time
-
in macro_rules! we do not appear to have this
-
is the way around this that we (1) define a new @token for every if/match, (2) invoke self! @token
at where if the match would have been (3) add a new top level match rule of @token ...
to the self! macro
===
I.e. if you had logic in the form of nested if/match, and you mechanically wanted to convert it to a macro_rules!, would you go through the above procedure ?
Yeah, pretty much.
Note that you don't actually need to use the @token
trick: you could also write a whole bunch of individual macros. The reason for using @token
is to avoid exposing a large number of internal macros to users, since we can't hide macro implementation details like we can with other code.
(The other, historical reason was that macros previously all lived in a single global namespace, and you wanted to have as few macros as possible exported from any given crate. But that's been fixed for a while.)
2 Likes