Macro_rules! throwing match to 'top level'

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:

  1. for every match, create an unique token

  2. for every match, recurse to self, appending unique token

  3. 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! ?

Try this Incremental TT Munchers - The Little Book of Rust Macros

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:

  1. in traditional languages, we have nested if/match all the time

  2. in macro_rules! we do not appear to have this

  3. 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