I'm trying to write an M4 macro to produce dotgraph notation but I'm struggling with the recursion.
I would like to have a macro which takes the first parameter, and adds the dotgraph relation for all the remaining parameters. For example
coachExisting(a, b, c, d)
would produce
a -> b; a -> c; a -> d;
This was my attempt at it:
define(coachExisting, `ifelse(eval($#==2), 1, `ifdef(first, first, $1) -> $2;',
ifelse(eval($#>2), 1,
`ifdef(first, ,define(first, $1)) first -> $2; $0(shift($*))')
)')
However this only seems to work if I use numbers
coachExisting(1, 2, 3, 4)
1 -> 2; 1 -> 3; 1 -> 4;
When I try with letters, it seems to lose the first definition.
coachExisting(a, b, c, d)
b -> b; b -> c; c -> d;
You are playing fast and loose with quoting. Please read the m4 manual carefully for guidance about quoting and recursive macro evaluation. On the first expansion, you get
define(first, $1)=>define(first, a). But on the second execution, it expands asdefine(first, $1)=>define(first, b)=>define(a, b)(because thefirstis expanded as a macro). You need to quote thefirsteverywhere you can, sodefine(`first', `$1')', for starters.A much cleaner way to implement your macro is to avoid a temporary macro to begin with. I'd recommend something like:
(be careful though -- I haven't designed this macro to handle the cases with 0 or 1 argument).