index c3139842624b3919ce4e251f6c40a8136590bd99..571c0dc783fc27b0bd0ecd42f7140d717b83f107 100644 (file)
@result{}# performs sanity check that FROM is larger than TO
@result{}# allows complex numerical expressions in TO and FROM
@result{}define(`forloop', `ifelse(eval(`(3ドル) >= (2ドル)'), `1',
-@result{} `pushdef(`1ドル', eval(`2ドル'))_forloop(`1ドル',
+@result{} `pushdef(`1ドル', eval(`2ドル'))_0ドル(`1ドル',
@result{} eval(`3ドル'), `4ドル')popdef(`1ドル')')')
@result{}define(`_forloop',
@result{} `3ドル`'ifelse(indir(`1ドル'), `2ドル', `',
@result{}
@end example
+One other change to notice is that the improved version used @samp{_0ドル}
+rather than @samp{_foreach} to invoke the helper routine. In general,
+this is a good practice to follow, because then the set of macros can be
+uniformly transformed. The following example shows a transformation
+that doubles the current quoting and appends a suffix @samp{2} to each
+transformed macro. If @code{foreach} refers to the literal
+@samp{_foreach}, then @code{foreach2} invokes @code{_foreach} instead of
+the intended @code{_foreach2}, and the mixing of quoting paradigms leads
+to an infinite recursion loop in this example.
+
+@comment options: -L9
+@comment status: 1
+@comment examples
+@example
+$ @kbd{m4 -d -L 9 -I examples}
+define(`arg1', `1ドル')include(`forloop2.m4')include(`quote.m4')
+@result{}
+define(`double', `define(`1ドル'`2',
+ arg1(patsubst(dquote(defn(`1ドル')), `[`']', `\&\&')))')
+@result{}
+double(`forloop')double(`_forloop')defn(`forloop2')
+@result{}ifelse(eval(``(3ドル) >= (2ドル)''), ``1'',
+@result{} ``pushdef(``1ドル'', eval(``2ドル''))_0ドル(``1ドル'',
+@result{} eval(``3ドル''), ``4ドル'')popdef(``1ドル'')'')
+forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
+@result{}
+changequote(`[', `]')changequote([``], [''])
+@result{}
+forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
+@result{}
+changequote`'include(`forloop.m4')
+@result{}
+double(`forloop')double(`_forloop')defn(`forloop2')
+@result{}pushdef(``1ドル'', ``2ドル'')_forloop($@@)popdef(``1ドル'')
+forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
+@result{}
+changequote(`[', `]')changequote([``], [''])
+@result{}
+forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
+@error{}m4:stdin:12: recursion limit of 9 exceeded, use -L<N> to change it
+@end example
+
Of course, it is possible to make even more improvements, such as
adding an optional step argument, or allowing iteration through
descending sequences. @acronym{GNU} Autoconf provides some of these
@result{}divert(`-1')
@result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt)
@result{}# quoted list, improved version
-@result{}define(`foreachq', `pushdef(`1ドル')_foreachq($@@)popdef(`1ドル')')
+@result{}define(`foreachq', `pushdef(`1ドル')_0ドル($@@)popdef(`1ドル')')
@result{}define(`_arg1q', ``1ドル'')
@result{}define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@@))')')
@result{}define(`_foreachq', `ifelse(`2ドル', `', `',
@result{}divert(`-1')
@result{}# foreach(x, (item_1, item_2, ..., item_n), stmt)
@result{}# parenthesized list, improved version
-@result{}define(`foreach', `pushdef(`1ドル')_foreach(`1ドル',
+@result{}define(`foreach', `pushdef(`1ドル')_0ドル(`1ドル',
@result{} (dquote(dquote_elt2ドル)), `3ドル')popdef(`1ドル')')
@result{}define(`_arg1', `1ドル')
@result{}define(`_foreach', `ifelse(`2ドル', `(`')', `',
index c4a7c147213814d17b78c43d2bf7cdb9271a56b2..32fd8a414e24b4bc73c4fee526fb98c19215f26f 100644 (file)
@@ -6,10 +6,10 @@ define(`move', `Move one disk from `1ドル' to `2ドル'.
# _hanoi (cnt, from, to, aux)
define(`_hanoi', `ifelse(eval(`1ドル'<=1), 1, `move(2,ドル 3ドル)',
-`_hanoi(decr(1ドル), 2,ドル 4,ドル 3ドル)move(2,ドル 3ドル)_hanoi(decr(1ドル), 4,ドル 3,ドル 2ドル)')')
+`0ドル(decr(1ドル), 2,ドル 4,ドル 3ドル)move(2,ドル 3ドル)0ドル(decr(1ドル), 4,ドル 3,ドル 2ドル)')')
# hanoi (cnt)
-define(`hanoi', `_hanoi(`1ドル', source, destination, auxilliary)')
+define(`hanoi', `_0ドル(`1ドル', source, destination, auxilliary)')
# traceon(`move', `_hanoi', `decr')
divert`'dnl
index a79dbcdd27e5a6d3b82337b780543f8d33864f6d..92ce9816bf86cd448fae552e13d89b53bc4b3a70 100644 (file)
@@ -6,10 +6,10 @@ define(`move', `Move one disk from `1ドル' to `2ドル'.
# _hanoi (cnt, from, to, aux)
define(`_hanoi', `ifelse(eval(`1ドル'<=1), 1, `move(2,ドル 3ドル)',
-`_hanoi(decr(1ドル), 2,ドル 4,ドル 3ドル)move(2,ドル 3ドル)_hanoi(decr(1ドル), 4,ドル 3,ドル 2ドル)')')
+`0ドル(decr(1ドル), 2,ドル 4,ドル 3ドル)move(2,ドル 3ドル)0ドル(decr(1ドル), 4,ドル 3,ドル 2ドル)')')
# hanoi (cnt)
-define(`hanoi', `_hanoi(`1ドル', source, destination, auxilliary)')
+define(`hanoi', `_0ドル(`1ドル', source, destination, auxilliary)')
divert`'dnl
# Debugmode t