[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
6.4 Iteration by counting
Here is an example of a loop macro that implements a simple for loop.
- Composite: forloop (iterator, start, end, text)
Takes the name in iterator, which must be a valid macro name, and successively assign it each integer value from start to end, inclusive. For each assignment to iterator, append text to the expansion of the
forloop
. text may refer to iterator. Any definition of iterator prior to this invocation is restored.
It can, for example, be used for simple counting:
$ m4 -I examples include(`forloop.m4') ⇒ forloop(`i', `1', `8', `i ') ⇒1 2 3 4 5 6 7 8
For-loops can be nested, like:
$ m4 -I examples include(`forloop.m4') ⇒ forloop(`i', `1', `4', `forloop(`j', `1', `8', ` (i, j)') ') ⇒ (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8) ⇒ (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) ⇒ (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8) ⇒ (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8) ⇒
The implementation of the forloop
macro is fairly
straightforward. The forloop
macro itself is simply a wrapper,
which saves the previous definition of the first argument, calls the
internal macro _forloop
, and re-establishes the saved
definition of the first argument.
The macro _forloop
expands the fourth argument once, and
tests to see if the iterator has reached the final value. If it has
not finished, it increments the iterator (using the predefined macro
incr
, see section Decrement and increment operators), and recurses.
Here is an actual implementation of forloop
, distributed as
‘m4-1.4.17/examples/forloop.m4’ in this package:
$ m4 -I examples undivert(`forloop.m4')dnl ⇒divert(`-1') ⇒# forloop(var, from, to, stmt) - simple version ⇒define(`forloop', `pushdef(`$1', `$2')_forloop($@)popdef(`$1')') ⇒define(`_forloop', ⇒ `$4`'ifelse($1, `$3', `', `define(`$1', incr($1))$0($@)')') ⇒divert`'dnl
Notice the careful use of quotes. Certain macro arguments are left unquoted, each for its own reason. Try to find out why these arguments are left unquoted, and see what happens if they are quoted. (As presented, these two macros are useful but not very robust for general use. They lack even basic error handling for cases like start less than end, end not numeric, or iterator not being a macro name. See if you can improve these macros; or see section Answers).
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on September 29, 2013 using texi2html 5.0.