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
我正在 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