On Tue, Feb 19, 2013 at 6:43 PM, Paul Stansifer <[email protected]>wrote:

> Alternation already exists, at least at the outer level:
>
> macro_rules! alt_example(
>     ( cons($e1:expr, $e2:expr) ) => ( ... )
>     ( mt() ) => ( ... )
> )
>
> Of course, making use of it for something other than a whole macro
> invocation requires the use of a helper macro, which can be tricky if the
> helper macro wants to be invoked somewhere that macro invocations can't yet
> go.
>
> There's generally some way around this sort of problem, typically
> involving continuation-passing-style at the macro level. Since you can't
> generate patterns, you'll want to generate a whole match (as you are
> doing), and since you want to process each arm on its own (in order to do
> pattern-matching), you'll want to process one at a time, accumulating your
> work into some sort of accumulator argument.
>

One thing this does is force all the alternatives to follow the same form
so that they can be matched by the same matcher, which isn't always
desirable.

Also, I ran into something I can't explain trying to use this approach.
This works:

macro_rules! make_vec(
($($n:ident),*) => (make_vec_rec!($($n),* :));
)

macro_rules! make_vec_rec(
(a $(,$n1:ident)* : $($n2:expr),*) => (make_vec_rec!($($n1),* : $($n2,)*
1));
(b $(,$n1:ident)* : $($n2:expr),*) => (make_vec_rec!($($n1),* : $($n2,)*
2));
 (: $($n2:expr),*) => ([$($n2),*]);
)

But this is ambiguous:

macro_rules! make_vec(
        ($($n:ident),*) => (make_vec_rec!(($($n),*)()));
)

macro_rules! make_vec_rec(
        ((a $(,$n1:ident)*)($($n2:expr),*)) =>
(make_vec_rec!(($($n1),*)($($n2,)* 1)));
        ((b $(,$n1:ident)*)($($n2:expr),*)) =>
(make_vec_rec!(($($n1),*)($($n2,)* 2)));
        (()($($n2:expr),*)) => ([$($n2),*]);
)

Documents/test.rs:85:45: 85:46 error: Local ambiguity: multiple parsing
options: built-in NTs expr ('
n2') or 1 other options.
Documents/test.rs:85    ($($n:ident),*) => (make_vec_rec!(($($n),*)()));

(`^` pointing at `()`)

Any idea why? () could be considered an expression, but it's not in an
expression position, and a lot of things could be considered expressions
and don't do this.

Abusing repetition to get around this is probably equally legitimate
>

My only concern would be whether there are cases where this abuse causes
unexpected behaviour rather than a syntax error when given incorrect input,
though I can't think of any off the top of my head.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to