\ifx\LOOP\relax\endinput\else\let\LOOP=\relax\fi % \input only once
%
% loop.tex: A simple looping construct (meta-macros).
% version: 1.0  release: 26 June 1991
%
% copyright (c) 1991 Marcel R. van der Goot
%	You can use these macros to typeset documents. You may
%	distribute this file freely, provided that you also distribute
%	the accompanying documentation.
%	    You may make changes to this file, or extract portions
%	of it for inclusion in other files, provided that
%	    (1) you change the name of the file;
%	    (2) you give proper credit and include copyright
%		information where applicable;
%	    (3) explain how an unchanged version can be obtained; and
%	    (4) document the usage of your macros/changes (if usage
%		of your macros is not worth documenting, they must not
%		be worth using).
%	You are not allowed to use the name ``Midnight Macros'' for
%	any changed files.
%	    The above rules for making changes do not apply where it
%	is explicitly noted in this file that something can be changed
%	to conform to your local installation.
%
% USAGE:
%   See the file loop.doc
%
% original: csvax.cs.caltech.edu [131.215.131.131] in pub/tex
%	    (use anonymous ftp). Also in various archives.
%
% Caltech, Pasadena  ---  Marcel van der Goot
%			  marcel@cs.caltech.edu
%			    Caltech 256--80
%			    Pasadena, CA 91125
%			    USA
%			    (818) 356--4603
%

% update history:
% version 1.0: This one.
%	release 26 April 1991: This one.
%	release 15 April 1991: Did not have \long in \Loop, \_break, and
%		\_continue.
%	release 8 Feb 1991: Used \next instead of \Lp_next.
%	

%%%%%% CODE: (you don't need to read this to use the macros)

{
\catcode`\_=11 % 11 = letter; to make macros private
\globaldefs=1

% Code to supply \fi's:

\def\do_fi{\fi\finish_ifs}

\def\finish_ifs
   {\ifnum\count255>0 %
	 \let\Lp_next=\do_fi
    \else\let\Lp_next=\relax
    \fi
    \advance\count255 by-1 %
    \Lp_next
   }

% The loop (tail-recursion does not clog memory):

\long\def\Loop#1\Pool%
   {\def\Pool{#1\Pool}%
    \Pool
   }

% \Break could have been defined as
%	\def\Break#1#2\Pool{{\count255=#1 \finish_ifs}}
% but this fails if you do
%	\ifnum\count0>5\Break
% without space after the 5: \Break wil be expanded to see if there
% are more digits (and expanding \Break means reading its 2nd argument).
% With the solution below, only \Break is expanded because it starts
% with \relax which is not a number. Using \afterassignment rather
% than passing the number as argument gives better error messages.

\def\Break
   {\relax\afterassignment\_break
    \bgroup\count255=
   }

\long\def\_break#1\Pool%
   {\finish_ifs
    \egroup
   }

\def\Continue
   {\relax\afterassignment\_continue
    \bgroup\count255=
   }

\long\def\_continue#1\Pool%
   {\finish_ifs
    \egroup
    \Pool
   }

} % restore \catcode`\_, \globaldefs

