GNU M4 似乎在 ifelse 中访问了不必要的值

GNU M4 seems to access unnecessary value in ifelse

我正在 linux 上试用 m4 CLI 并尝试创建一个 for(begin, end, step) 宏,它将打印出给定范围内以逗号分隔的数字列表。我还希望它支持默认步骤 1。我尝试了以下

[tom@sp4 ~]$ m4
define(`for',`ifelse($#,2,`for(,,1)',eval(+>),1,,`, for(eval(+),,)')')

for(3,9)
m4:stdin:3: bad expression in eval: 3+>9
3, 4, 5, 6, 7, 8, 9

虽然它工作正常,但我不明白为什么我会收到错误消息,因为 $3 在第一次传递时只是空白。当 $#==2 时,为什么还要费心去读 eval($1+$3>$2)?

编辑:使用威廉在他的回答中给我的信息,我想出了下面的宏。它接受 0 到 3 个参数,并允许倒计时和倒计时。我从弄乱这个例子中学到了很多东西。

[tom@sp4 ~]$ m4
define(`for',
    `ifelse(
        $#,0,``for'',
        eval($#==1 && +0>0),1,`for(1,,1)',
        $#,1,,
        $#,2,`for(,,ifelse(eval(+0>+0),1,-1,1))',
        eval(+0==0 || +0>0 && +0>+0 || +0<0 && +0<+0),1,,
        eval(+0+(+0)ifelse(eval(+0<0),1,<,>)+0),1,,
        `, for(eval(+),,)'dnl
    )'dnl
)


for
for
for(0)

for(5)
1, 2, 3, 4, 5                
for(5,-23,-5)
5, 0, -5, -10, -15, -20                    
for(5,9)
5, 6, 7, 8, 9                
for(6,1)
6, 5, 4, 3, 2, 1                    

m4 遇到 foo(3,9) 时,它会将其扩展为宏中定义的 ifelse 的文本。为了调用 ifelse,它必须向它传递参数。要确定这些参数,它必须扩展 eval。因此出现错误消息。

您可以通过以下方式避免错误消息:

define(`for',
`ifelse(
        `$#', `2', `for(`', `', `1')',
        eval(`' + ifelse(`', `', `0', `1') > `'), `1', `',
        `, for(eval(`' + `'), `', `')'dnl
)')dnl