control.tex (2361B)
1 % The classical Plain TeX \loop macro (approximately). 2 % Needs grouping to be nested. 3 \def\loop#1\repeat{\def\@body{#1}\@iterate} 4 \let\repeat=\fi 5 \def\@iterate{\@body\ea\@iterate\fi} 6 7 % Loops that can be nested use this stack. 8 \newqueue\@ctrlstack 9 10 \newcount\@forcnt 11 \newcount\@forlim 12 \newcount\@forstep 13 \def\fornum#1=#2..#3\do{\fornumstep#1=#2..#3:1\do} 14 \def\fornumstep#1=#2..#3:#4\do#{% 15 \@forsave 16 \@forcnt=\numexpr#2\relax 17 \@forlim=\numexpr#3\relax 18 \@forstep=\numexpr#4\relax 19 \@forstart{#1}% 20 } 21 \def\@forstart#1#2{% 22 \def\@body{\edef#1{\the\@forcnt}#2}% 23 \@forloop 24 \@forrestore 25 } 26 \def\@forloop{% 27 \ifnum\@forcnt \ifnum\@forstep<0 >\else <\fi \@forlim 28 \@body 29 \advance\@forcnt\@forstep 30 \ea\@forloop 31 \fi 32 } 33 \def\@forsave{% 34 \let\qtok=\@body \pushtok\@ctrlstack 35 \qnum=\@forcnt \pushnum\@ctrlstack 36 \qnum=\@forlim \pushnum\@ctrlstack 37 \qnum=\@forstep \pushnum\@ctrlstack 38 } 39 \def\@forrestore{% 40 \popnum\@ctrlstack \@forstep=\qnum 41 \popnum\@ctrlstack \@forlim=\qnum 42 \popnum\@ctrlstack \@forcnt=\qnum 43 \poptok\@ctrlstack \let\@body=\qtok 44 } 45 46 \def\foreach#1\do#2#{\@foreachA{#1}{#2}} 47 \def\@foreachA#1#2#3{% 48 \let\qtok=\@body \pushtok\@ctrlstack 49 \gdef\@body#2{#3\futurelet\@next\@foreachB}% 50 \@body#1\@foreachend 51 \poptok\@ctrlstack \let\@body=\qtok 52 } 53 \def\@foreachB{\ifx\@next\@foreachend \ea\selectx \else \ea\@body \fi} 54 \def\@foreachend{\errmessage{this can not happen}} 55 56 \newcount\swnum 57 \def\switchnum#1#{% 58 \qnum=\sqnum \pushnum\@ctrlstack \swnum=\numexpr#1\relax 59 \let\qtok=\case \pushtok\@ctrlstack \let\case=\@casenum 60 \@fallthroughfalse \@switchnum 61 } 62 \def\@switchnum#1{#1\@endswitch \popnum\@ctrlstack \swnum=\qnum} 63 \def\@casenum#1#{% 64 \if@fallthrough 65 \ea\@case 66 \else\ifnum\swnum=\numexpr#1\relax 67 \ea\ea\ea\@case 68 \else 69 \ea\ea\ea\selectx 70 \fi\fi 71 } 72 73 \newdimen\swdim 74 \def\switchdim#1#{% 75 \qdim=\swdim \pushdim\@ctrlstack \swdim=\dimexpr#1\relax 76 \let\qtok=\case \pushtok\@ctrlstack \let\case=\@casedim 77 \@fallthroughfalse \@switchdim 78 } 79 \def\@switchdim#1{#1\@endswitch \popdim\@ctrlstack \swdim=\qdim} 80 \def\@casedim#1#{% 81 \if@fallthrough 82 \ea\@case 83 \else\ifdim\swdim=\dimexpr#1\relax 84 \ea\ea\ea\@case 85 \else 86 \ea\ea\ea\selectx 87 \fi\fi 88 } 89 90 \newif\if@fallthrough 91 \def\@endswitch{\poptok\@ctrlstack \let\case=\qtok} 92 \def\fallthrough{\@fallthroughtrue} 93 \def\@case#1#2\@endswitch{\@fallthroughfalse#1\if@fallthrough#2\fi\@endswitch} 94 95 \endinput