diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/eijkhout/repeat.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/eijkhout/repeat.tex | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/eijkhout/repeat.tex b/Master/texmf-dist/tex/generic/eijkhout/repeat.tex new file mode 100644 index 00000000000..6d149e15ee7 --- /dev/null +++ b/Master/texmf-dist/tex/generic/eijkhout/repeat.tex @@ -0,0 +1,206 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Repeat loop macro, version 0.92, December 2000 +% Copyright Victor Eijkhout 2000 +% file name: repeat.tex +% +% Author: +% Victor Eijkhout +% Department of Computer Science +% University of Tennessee, Knoxville TN 37996 +% +% victor@eijkhout.net +% +% This program is free software; you can redistribute it and/or +% modify it under the terms of the GNU General Public License +% as published by the Free Software Foundation; either version 2 +% of the License, or (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% For a copy of the GNU General Public License, write to the +% Free Software Foundation, Inc., +% 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, +% or find it on the net, for instance at +% http://www.gnu.org/copyleft/gpl.html +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% General loop macro: +% \repeat +% \for{<var>} \from{<start>} \by{<step>} \to{<end>} \downto{<end>} +% \until{<cond>} \while{<cond>} +% \do { <loop body> } +% where all control sequences in between \repeat and \do are optional. +% The space after each argument is mandatory! +% (This implies that you will have to write "\from\i" as "\from{\i}".) +% +% var: characters to form a control sequence; +% after \for{index} you can access the loop counter as \index. +% This is a count register; to print it use \number\index. +% start,step,end: integers with obvious relations to the loop counter; +% start and step have a default value of 1 +% cond: (sequence of commands ending in) any TeX \if... test. +% +% Count down instead of up with \downto; the increment given in \by +% is always positive, and is added or subtracted accordingly. +% +% Tests: \until is evaluated at the end of the loop body; \while +% at the beginning of the loop body. +% +% Exit from middle of loop: \breakrepeat +% use this at any place in the loop; in case of a conditional, use +% \ifsomething ... \expandafter \breakrepeat \fi +% +% There are some examples at the end of this file, after the \endinput line. +% +% Technical details: +% The loop body is not executed in a group: the braces are those +% of a token list. +% The `for' variable is \let to a \count register. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% revision history: +% 0.9 first release, January 1999 +% 0.91 documentation update, +% csarg-like control sequences made REP... +% counter update made global in case the body issues grouping, +% copyright notice, February 1999 +% 0.92 installed trace switches, eliminated unwanted space caused by +% "\for{ijk} \do{...}" +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% + +%% +%% Prevent multiple loading of this file +%% +\expandafter\ifx\csname REPdepth\endcsname\relax + \message{Loading loop macro, version 0.92}% +\else \endinput \fi + +%% +%% Auxiliary stuff +%% +\def\REPcsarg#1#2{\expandafter#1\csname#2\endcsname} +\def\REPcsrom#1{\csname #1\romannumeral\REPdepth\endcsname} +\def\REPcsargrom#1#2{\expandafter#1\csname#2\romannumeral\REPdepth\endcsname} +%\def\cscsarg#1#2#3{\expandafter#1\expandafter#2\csname#3\endcsname} +%\def\REPcsREPcsargrom#1#2#3{\expandafter#1\expandafter#2% +% \csname#3\romannumeral\REPdepth\endcsname} + +\newcount\REPdepth +\let\endrepeat\relax \def\csprotect{} +% Trace switches may later be defined by PAC_utils +\let\REPtraceinit\relax \let\REPtraceexit\relax + +%% +%% Main repeat macro +%% - go to next level and allocate unique counter/toks if this is the +%% first time we visit this level +%% - setup: gather bounds and termination conditions +%% - scoop up body in token list; after the assignment define and +%% execute body +%% +\def\repeat#1\do{ + \REPtraceinit % exit in \breakrepeat + \advance\REPdepth by 1\relax + \REPcsargrom\ifx{REPcount}\relax + \REPcsargrom{\csname newcount\expandafter\endcsname}{REPcount}% + \REPcsargrom{\csname newtoks\expandafter\endcsname}{REPtoks}% + \REPcsargrom{\csname newtoks\expandafter\endcsname}{REPwtest}% + \REPcsargrom{\csname newtoks\expandafter\endcsname}{REPutest}% + \fi \REPzero \def\REPsign{}\def\REPcomp{>}\REPsetup{#1}% + \edef\REPtmp + {\def\REPcsargrom\noexpand{REPrepeat}{\REPcsargrom\noexpand{REPbody}}}\REPtmp + \afterassignment\REPdxbody\REPcsrom{REPtoks}} +%% +%% Define and execute loop body +%% This is done with an \edef to construct the actual sequence +%% +\def\REPdxbody{\REPcsargrom\edef{REPbody}{% + \REPcsargrom\the{REPwtest}% + \noexpand\the\REPcsargrom\noexpand{REPtoks}% + \REPcsargrom\the{REPutest}% + \global\REPcsargrom\advance{REPcount} by \REPsign\REPcsrom{REPinc}\relax% + \noexpand\endrepeat + \REPcsargrom\noexpand{REPrepeat}}% + \REPcsrom{REPbody}} +%% +%% Stop test +%% In order to stop, issue a +%% \breakrepeat which scoops up the rest of the body and exits +%% +\def\breakrepeat#1\endrepeat{\REPzero\REPcsargrom\let{REPrepeat}\relax + \advance\REPdepth by -1 \REPtraceexit + } +%% +%% Setup +%% gather bounds and termination conditions +%% +\def\REPsetup#1{% + \begingroup + \def\for##1 {\edef\REPtmp{% + \global\let\REPcsarg\noexpand{##1}\REPcsrom{REPcount}}\REPtmp}% + \def\from##1 {\REPcsargrom\global{REPcount}##1\relax}% + \def\to##1 {\edef\REPtmp{\global\REPcsargrom\noexpand{REPwtest}= + {\REPcsargrom\the{REPwtest}% + \noexpand\ifnum\REPcsargrom\noexpand{REPcount}\REPcomp##1\relax + \noexpand\expandafter \noexpand\breakrepeat \noexpand\fi}}\REPtmp}% + \def\downto##1 {\gdef\REPsign{-}\gdef\REPcomp{<}\to{##1}}% + \def\by##1 {\ifnum##1<0 \message{REPEAT: increment has to be >0}% + \REPcsargrom\gdef{REPinc}{-##1}\else + \REPcsargrom\gdef{REPinc}{##1}\fi} + \def\until##1 {\edef\REPtmp{\global\REPcsargrom\noexpand{REPutest}= + {\noexpand##1\relax + \noexpand\expandafter \noexpand\breakrepeat \noexpand\fi}}\REPtmp}% + \def\while##1 {\edef\REPtmp{\global\REPcsargrom\noexpand{REPwtest}= + {\noexpand##1\relax \noexpand\else + \noexpand\expandafter \noexpand\breakrepeat \noexpand\fi}}\REPtmp}% + \from{1} \by{1} #1% + \endgroup} +\def\REPzero + {\REPcsrom{REPtoks}{}\REPcsrom{REPutest}{}\REPcsrom{REPwtest}{}% + \REPcsargrom\def{REPbody}{}} + +\endinput + +%\tracingmacros2 +\repeat \for{i} \by{2} \do { + \ifnum\i=13 \expandafter\breakrepeat \fi + \message{doing \number\i} +} + +\repeat \for{iii} \to{8} \do {} +\message{After loop: \number\iii} + +\repeat \for{i} \from{10} \by{2} \downto{0} \do { + \message{countdown \number\i} +} + +\repeat \for{x} \while{\ifnum\x<7} \do { + \message{going \number\x} +} + +\repeat \to{3} \do { + \message{hello there!} +} + +\newcount\tmpcount +\repeat \for{j} + \until{\tmpcount\j \divide\tmpcount by 37 \noexpand\ifnum\tmpcount=1} + \do { + \message{testing \number\j} +} + +\repeat \for{i} \by{2} \to{10} \do + {\repeat \for{j} \from{\i} \by{3} \to{18} \do + {\message{(\number\i.\number\j)} + }} + +% infinite loop +%\repeat \do {} + +\bye |