Before I labour over another solution (if that remains necessary or interesting), here is David Carlisle's syntactic cake coated with chocolate and dates.
\documentclass{article}
\makeatletter
\def\declarenewloop#1{%
\begingroup
\def\newloopa##1{repeat}%
\def\newloopb##1{iterate@}%
\def\newloopc##1##2##3{\endgroup
\ifx##1\@undefined\else
\edef\reserved@a{\expandafter\@gobble\string##1}%
\@notdefinable
\fi
\let##2\fi
\def##1####1##2{%
\def##3{####1\relax\expandafter##3\fi}%
##3\let##3\relax
}%
}%
\def\x##1##2{\expandafter\noexpand\csname\expandafter##1\string##2\endcsname}%
\edef\x{\noexpand#1\x\newloopa#1\x\newloopb#1}%
\expandafter\newloopc\x
}
% Tests:
\declarenewloop\loopb
\newcount\row\newcount\column
\row0 \column0
\def\stack{}
\loop
\advance\row by1
\ifnum\row<3\relax
\column0
\loopb
\advance\column by1
\ifnum\column<4\relax
\let\rom\romannumeral
\typeout{Including numbers \rom\row, \rom\column}%
\edef\stack{%
\unexpanded\expandafter{\stack}\noexpand\\{\rom\row}{\rom\column}%
}%
\repeatloopb
\repeat
\makeatother
\begin{document}
x
\end{document}
This gives
Including numbers i, i
Including numbers i, ii
Including numbers i, iii
Including numbers ii, i
Including numbers ii, ii
Including numbers ii, iii
EDIT
Here is the solution I thought I could build. Notice, in the example, that both \loop
and \repeat
are nested without any change of their names. We have
\loop
...
\loop
***
\repeat
\repeat
The code follows:
\documentclass{article}
\usepackage{catoptions}
\makeatletter
\newcount\amloop@cnt
\newtoks\amloop@toks
\new@def*\this@ghost{\@gobble\this@ghost}
\new@def\amloop@ifcmdeq#1{\expandafter\ifcseqTF\cpt@car#1\this@ghost\car@nil}
\new@def\amloop@orig#1\repeat{\amloop@origb\@gobble{#1}}
\let\repeat\fi
\new@def\amloop@origb\@gobble#1{%
#1\relax\expandafter\amloop@origb\fi\@gobble{#1}%
}
\amloop@toks{\amloop@orig}
\new@def\amloop@iiofii#1#2{#1#2}
\new@def\amloop@ifflochtype#1{%
\csname @\if0\pdfstrcmp{\cptoxdetok{\amloop@iiofii#1{}{}}}%
{\detokenize{#1{}}}first\else second\fi oftwo\endcsname
}
\robust@def*\am@defnewloop{%
\begingroup
\def\def@loop##1##2##3{\endgroup
\def\name@cmd{##1}\def\repeat@cmd{##2}%
\let##2\fi
\def##1####1##2{%
\def##3{####1\relax\expandafter##3\fi}%
##3\let##3\relax
}%
}%
\def\x##1{\noexpandcsn{##1\romannumeral\amloop@cnt}}%
\edef\x{\x{amloop@}\x{amrepeat@}\x{amiterate@}}%
\expandafter\def@loop\x
}
\robust@def*\amloop{%
\edef\amloop@restoreeof{\everyeof{\the\everyeof}}%
\everyeof{EOF}\amloop@cnt\z@
\amloop@pushloop
}
\robust@def\amloop@pushloop{\futurelet\next\amloop@pushloopb}
\robust@def\amloop@pushloopb#1{%
\amloop@ifflochtype{#1}{%
\amloop@ifcmdeq{#1}\amloop{%
\advance\amloop@cnt\@ne
\am@defnewloop
\amloop@toks\expandafter{\the\expandafter\amloop@toks\name@cmd}%
\amloop@pushloop
}{%
\ifstrcmpTF{#1}\repeat{%
\ifnumcmpTF\amloop@cnt=\z@{%
\amloop@restoreeof
\amloop@toks\expandafter{\expandafter\amloop@orig
\expandafter}\the\amloop@toks\repeat
}{%
\amloop@toks\expandafter{\the\expandafter\amloop@toks\repeat@cmd}%
\advance\amloop@cnt\m@ne
\amloop@pushloop
}%
}{%
\ifcseqTF\next\@sptoken{%
\amloop@toks\expandafter{\the\expandafter\amloop@toks\space#1}%
}{%
\amloop@toks\expandafter{\the\amloop@toks#1}%
}%
\amloop@pushloop
}%
}%
}{%
\ifstrcmpTF{#1}{EOF}{%
\amloop@restoreeof
\cpt@err{'\string\repeat' not found: endless loop}\@ehd
}{%
\ifcseqTF\next\@sptoken{%
\amloop@toks\expandafter{\the\expandafter\amloop@toks\space{#1}}%
}{%
\amloop@toks\expandafter{\the\amloop@toks{#1}}%
}%
\amloop@pushloop
}%
}%
}
% Tests
\newcount\row\newcount\column
\row0 \column0
\def\stack{}
\let\loop\amloop
\loop
\advance\row by1\relax
\ifnum\row<3\relax
\column0\relax
\let\rom\romannumeral
\loop
\advance\column by1\relax
\ifnum\column<4\relax
\typeout{Including numbers \rom\row, \rom\column}%
\edef\stack{\expandcsonce{\stack}\noexpand\\{\rom\row}{\rom\column}}%
\repeat
\typeout{Including row \rom\row}%
\edef\stack{\expandcsonce{\stack}\noexpand\do{\rom\row}}%
\repeat
%\show\stack
\makeatother
\begin{document}
x
\end{document}
This gives
Including numbers i, i
Including numbers i, ii
Including numbers i, iii
Including row i
Including numbers ii, i
Including numbers ii, ii
Including numbers ii, iii
Including row ii
with
\stack=macro:
->\\{i}{i}\\{i}{ii}\\{i}{iii}\do {i}\\{ii}{i}\\{ii}{ii}\\{ii}{iii}\do {ii}
More test:
\cptnewcounts{rowcnt,colcnt,maxrow,maxcol}
\maxrow4 \maxcol3
\def\entries{}
\let\loop\amloop
\def\generateentries{%
\loop
\advance\rowcnt1\relax
\colcnt0\relax
\loop
\advance\colcnt1\relax
\edef\entries{\expandcsonce\entries\the\numexpr\rowcnt*\colcnt\relax}%
\ifnum\colcnt<\numexpr\maxcol+1\relax\relax
\edef\entries{\expandcsonce\entries\noexpand&}%
\repeat
\ifnum\rowcnt<\numexpr\maxrow+1\relax\relax
\edef\entries{\expandcsonce\entries\noexpand\cr}%
\repeat
\edef\entries{\expandcsonce\entries\noexpand\crcr}%
}
\generateentries
\begin{document}
$$\vbox{\halign{&\ \hfil#\hfil\strut\cr\entries}}$$
\end{document}