How to distinguish current macro arguments from new macro arguments when creating a macro inside another one?

65 Views Asked by At

I am trying to make this kind of construct:

changequote([,])dnl
define([mult_by], [define(mult_by_$1, [eval([$1] * $1)])])dnl
mult_by(7)dnl
mult_by_7(3) 

But the result is 49 instead of 21.


I was hoping that [$1] * $1 will make the trick.

Is there another approach?

1

There are 1 best solutions below

0
pietrodito On

To achieve the goal of the OP one has to get two concepts:

How to produce $1 as the result of a macro?

There are three quoting techniques to do that:

  • [$]1
  • $[]1
  • $[1]

How to delay eval macro expansion?

This snippet below produces this error m4:fun-gen.m4:6: bad expression in eval: $1 + 5

define([eval_later], eval($1 + 5))
eval_later(3)

There are two quoting techniques to make this work:

  • Quoting all definition like that define([eval_later], [eval($1 + 5)])
  • Quotes eval and arguments like that define([eval_later], [eval]($1 + 5))

Here we have to use the latter technique, because the former one does not work in the OP problem. Indeed, it will quote the second $1 and make the function unable to take argument in the first place.


Eventually here is an answer:

changequote([,])dnl
define([mult_by],[define(mult_by_$1, [eval]([$]1*$1))])dnl
mult_by(7)dnl
mult_by_7(3)

which produces the expected 21!