`macro_rules!` nested output

I would like to write a macro_rules! macro, that accepts a list, and nests each element of the list one level deeper from back to front. For example, an input of a, b, c, d should produce an output of {{{{{ some_other_stuff } a } b } c } d }. Is this possible?

yes. although your example output requires an accumulator capture. in the following example, I'm assuming the input list is a list of balanced tt, you can adapt it for other parsing elements like statements or expressions. also, you can handle trailing comma if you so desire.

// the fold to the left, need an accumulator.
// since the input accept arbitrary tt, the entry point must come last
macro_rules! left {
	// base case, just return the accumulator
	(@fold $acc:tt) => {
		$acc
	};
	// recursion, fold one element a time
	(@fold $acc:tt $head:tt  $($tail:tt)*) => {
		left!(@fold { $acc $head } $($tail)*)
	};
	// entry point, to normalize the syntax of the input list
	// e.g. comma separated, semicolon separated, or white space separated, etc
	($($item:tt),*) => {
		left!(@fold {some_other_stuff} $($item)*)
	};
}

PS: it would be much easier and cleaner if the output is a right fold, (such as a cons list), since you don't need an accumulator.

macro_rules! list {
	// nil
	() => {
		Nil
	};
	// cons
	($car:expr $(, $cdr:expr)* $(,)?) => {
		Cons($car, list!($($cdr),*))
	}
}
3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.