uben
uben

Reputation: 1491

How can a macro match any token tree except comma

macro_rules! foo {
    ( $( $( $tok:tt )* ,)* ) => {
        [ bar!( $( $tok )* ,)* ]
    }
}

Produces error: local ambiguity when calling macro 'foo'. Because the comma ',' is of type :tt. I would need a way to match all token trees excluding the coma token.

Usage example

foo!(
    add t0 zero zero,
    add t1 t0 a0,
    lb t1 0(t1),
)

Should produce:

[
    bar!(add t0 zero zero),
    bar!(add t1 t0 a0),
    bar!(lb t1 0(t1)),
]

Upvotes: 4

Views: 677

Answers (2)

Sammy
Sammy

Reputation: 211

Just to add to Chayim Friedman's answer, should you wish to accommodate for non-trailing colons, one more rule is necessary:

macro_rules! foo {
    (@accumulate [ $($accumulated:tt)* ] [ ]) => { [ $($accumulated)* ] };
    (@accumulate [ $($accumulated:tt)* ] [ $($final_line:tt)* ]) => {
        [ $($accumulated)* bar!( $($final_line)+ ) ]
    };
    (@accumulate [ $($accumulated:tt)* ] [ $($this_line:tt)* ] , $($rest:tt)* ) => {
        foo! {
            @accumulate [ $($accumulated)* bar!( $($this_line)* ), ]
                        [ ] $($rest)*
        }
    };
    (@accumulate [ $($accumulated:tt)* ] [ $($this_line:tt)* ] $current:tt $($rest:tt)* ) => {
        foo! { @accumulate [ $($accumulated)* ] [ $($this_line)* $current ] $($rest)* }
    };
    ( $($t:tt)* ) => { foo! { @accumulate [ ] [ ] $($t)* } }
}

Upvotes: 0

Chayim Friedman
Chayim Friedman

Reputation: 71380

TT munching to the rescue!

macro_rules! foo {
    (@accumulate [ $($accumulated:tt)* ] [ ]) => { [ $($accumulated)* ] };
    (@accumulate [ $($accumulated:tt)* ] [ $($this_line:tt)* ] , $($rest:tt)* ) => {
        foo! { @accumulate [
            $($accumulated)*
            bar!( $($this_line)* ),
        ] [] $($rest)* }
    };
    (@accumulate [ $($accumulated:tt)* ] [ $($this_line:tt)* ] $current:tt $($rest:tt)* ) => {
        foo! { @accumulate [ $($accumulated)* ] [ $($this_line)* $current ] $($rest)* }
    };
    ( $($t:tt)* ) => { foo! { @accumulate [] [] $($t)* } }
}

Upvotes: 5

Related Questions