commit 4598ab90452f96d726662f11dcadab4fdac6f979
parent ce596b979f1dc4b8a446c9e5449aa22fae3d6f89
Author: robert <robertrussell.72001@gmail.com>
Date: Mon, 18 Apr 2022 12:45:17 -0700
Merge branch 'queue'
Diffstat:
| A | control.tex | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | loop.tex | | | 93 | ------------------------------------------------------------------------------- |
| M | queue.tex | | | 86 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
3 files changed, 142 insertions(+), 129 deletions(-)
diff --git a/control.tex b/control.tex
@@ -0,0 +1,92 @@
+% TODO: make loops expandable with immediateassign{ment,ed}?
+
+% The classical Plain TeX \loop macro (approximately).
+% Needs grouping to be nested.
+\def\loop#1\repeat{\def\@body{#1}\@iterate}
+\let\repeat=\fi
+\def\@iterate{\@body\ea\@iterate\fi}
+
+% Loops that can be nested use this stack.
+\newq\@loopstack
+
+\newcount\@forcnt
+\newcount\@forlim
+\newcount\@forstep
+\def\fornum#1=#2..#3\do{\fornumstep#1=#2..#3:1\do}
+\def\fornumstep#1=#2..#3:#4\do#5{% XXX require open brace like \foreach
+ \@forsave
+ \def\@body{\edef#1{\the\@forcnt}#5}%
+ \@forcnt=\numexpr#2\relax
+ \@forlim=\numexpr#3\relax
+ \@forstep=\numexpr#4\relax
+ \@forloop
+ \@forrestore
+}
+\def\@forloop{%
+ \ifnum\@forcnt \ifnum\@forstep<0>\else<\fi \@forlim
+ \@body \advance\@forcnt\@forstep \ea\@forloop
+ \fi
+}
+\def\@forsave{%
+ \let\qtok=\@body \pushtok\@loopstack
+ \qnum=\@forcnt \pushnum\@loopstack
+ \qnum=\@forlim \pushnum\@loopstack
+ \qnum=\@forstep \pushnum\@loopstack
+}
+\def\@forrestore{%
+ \popnum\@loopstack \@forstep=\qnum
+ \popnum\@loopstack \@forlim=\qnum
+ \popnum\@loopstack \@forcnt=\qnum
+ \poptok\@loopstack \let\@body=\qtok
+}
+
+\def\foreach#1\do#2#{\@foreachA{#1}{#2}}
+\def\@foreachA#1#2#3{%
+ \let\qtok=\@body \pushtok\@loopstack
+ \gdef\@body#2{#3\futurelet\@next\@foreachB}%
+ \@body#1\@foreachend
+ \poptok\@loopstack \let\@body=\qtok
+}
+\def\@foreachB{\ifx\@next\@foreachend \ea\selectx \else \ea\@body \fi}
+\def\@foreachend{\errmessage{this can not happen}}
+
+\newcount\swnum
+\def\switchnum#1#{%
+ \qnum=\sqnum \pushnum\@loopstack \swnum=\numexpr#1\relax
+ \let\qtok=\case \pushtok\@loopstack \let\case=\@casenum
+ \@fallthroughfalse \@switchnum
+}
+\def\@switchnum#1{#1\@endswitch \popnum\@loopstack \swnum=\qnum}
+\def\@casenum#1#{%
+ \if@fallthrough
+ \ea\@case
+ \else\ifnum\swnum=\numexpr#1\relax
+ \ea\ea\ea\@case
+ \else
+ \ea\ea\ea\selectx
+ \fi\fi
+}
+
+\newdimen\swdim
+\def\switchdim#1#{%
+ \qdim=\swdim \pushdim\@loopstack \swdim=\dimexpr#1\relax
+ \let\qtok=\case \pushtok\@loopstack \let\case=\@casedim
+ \@fallthroughfalse \@switchdim
+}
+\def\@switchdim#1{#1\@endswitch \popdim\@loopstack \swdim=\qdim}
+\def\@casedim#1#{%
+ \if@fallthrough
+ \ea\@case
+ \else\ifdim\swdim=\dimexpr#1\relax
+ \ea\ea\ea\@case
+ \else
+ \ea\ea\ea\selectx
+ \fi\fi
+}
+
+\newif\if@fallthrough
+\def\@endswitch{\poptok\@loopstack \let\case=\qtok}
+\def\fallthrough{\@fallthroughtrue}
+\def\@case#1#2\@endswitch{\@fallthroughfalse#1\if@fallthrough#2\fi\@endswitch}
+
+\endinput
diff --git a/loop.tex b/loop.tex
@@ -1,93 +0,0 @@
-% TODO: rename loop.tex -> control.tex and add defer macros
-% TODO: make loops expandable with immediateassign{ment,ed}?
-
-% The classical Plain TeX \loop macro (approximately).
-% Needs grouping to be nested.
-\def\loop#1\repeat{\def\@body{#1}\@iterate}
-\let\repeat=\fi
-\def\@iterate{\@body\ea\@iterate\fi}
-
-% Loops that can be nested use this stack.
-\newq\@loopstack
-
-\newcount\@forcnt
-\newcount\@forlim
-\newcount\@forstep
-\def\fornum#1=#2..#3\do{\fornumstep#1=#2..#3:1\do}
-\def\fornumstep#1=#2..#3:#4\do#5{%
- \@forsave
- \def\@body{\edef#1{\the\@forcnt}#5}%
- \@forcnt=\numexpr#2\relax
- \@forlim=\numexpr#3\relax
- \@forstep=\numexpr#4\relax
- \@forloop
- \@forrestore
-}
-\def\@forloop{%
- \ifnum\@forcnt \ifnum\@forstep<0>\else<\fi \@forlim
- \@body \advance\@forcnt\@forstep \ea\@forloop
- \fi
-}
-\def\@forsave{%
- \pushtok\@loopstack\@body
- \pushcount\@loopstack\@forcnt
- \pushcount\@loopstack\@forlim
- \pushcount\@loopstack\@forstep
-}
-\def\@forrestore{%
- \popcount\@loopstack \@forstep=\qcount
- \popcount\@loopstack \@forlim=\qcount
- \popcount\@loopstack \@forcnt=\qcount
- \poptok\@loopstack \let\@body=\qtok
-}
-
-\def\foreach#1\do#2#{\@foreachA{#1}{#2}}
-\def\@foreachA#1#2#3{%
- \pushtok\@loopstack\@body
- \gdef\@body#2{#3\futurelet\@next\@foreachB}%
- \@body#1\@foreachend
- \poptok\@loopstack \let\@body=\qtok
-}
-\def\@foreachB{\ifx\@next\@foreachend \ea\selectx \else \ea\@body \fi}
-\def\@foreachend{\errmessage{this can not happen}}
-
-\newcount\swnum
-\def\switchnum#1#{%
- \pushcount\@loopstack\swnum \swnum=\numexpr#1\relax
- \pushtok\@loopstack\case \let\case=\@casenum
- \@fallthroughfalse \@switchnum
-}
-\def\@switchnum#1{#1\@endswitch \popcount\@loopstack \swnum=\qcount}
-\def\@casenum#1#{%
- \if@fallthrough
- \ea\@case
- \else\ifnum\swnum=\numexpr#1\relax
- \ea\ea\ea\@case
- \else
- \ea\ea\ea\selectx
- \fi\fi
-}
-
-\newdimen\swdim
-\def\switchdim#1#{%
- \pushdimen\@loopstack\swdim \swdim=\dimexpr#1\relax
- \pushtok\@loopstack\case \let\case=\@casedim
- \@fallthroughfalse \@switchdim
-}
-\def\@switchdim#1{#1\@endswitch \popdimen\@loopstack \swdim=\qdimen}
-\def\@casedim#1#{%
- \if@fallthrough
- \ea\@case
- \else\ifdim\swdim=\dimexpr#1\relax
- \ea\ea\ea\@case
- \else
- \ea\ea\ea\selectx
- \fi\fi
-}
-
-\newif\if@fallthrough
-\def\@endswitch{\poptok\@loopstack \let\case=\qtok}
-\def\fallthrough{\@fallthroughtrue}
-\def\@case#1#2\@endswitch{\@fallthroughfalse#1\if@fallthrough#2\fi\@endswitch}
-
-\endinput
diff --git a/queue.tex b/queue.tex
@@ -1,32 +1,40 @@
\newcount\@qn
\newcount\@qt
-\newcount\qcount
-\newdimen\qdimen
+\newcount\qnum
+\newdimen\qdim
\newskip\qskip
-\newmuskip\qmuskip
+\newmuskip\qmu
\newbox\qbox
\newtoks\qtoks
+\newif\if@qapp
+\newif\if@qpeek
-\newif\if@qapp \@qappfalse
-\newif\if@qpeek \@qpeekfalse
\protected\def\newq#1{\newbox#1\g\setbox#1=\hbox{\penalty0}}
-\def\@qop#1{%
+\def\@qexec{%
\g\setbox\@qn=\hbox{\unhbox\@qn \g\@qt=\lastpenalty \unpenalty}%
\g\setbox\@qn=\hbox{%
\if@qapp \unhbox\@qn \fi
- #1%
+ \@qop
\unhbox\@qn % no op iff @qapp is true
\penalty\@qt
}%
}
+\def\@qmodify#1{\def\@qop{#1}\afterassignment\@qexec\@qn=}
\def\@qcs{q:\the\@qn:\the\@qt}
-\def\@qq#1{\deferasn{\@qop{#1}\@qappfalse\@qpeekfalse}}
-\protected\def\precount {\deferasn{\@qq{\penalty\qcount}\g\qcount=}\@qn=}
-\protected\def\predimen {\deferasn{\@qq{\kern\qdimen}\g\qdimen=}\@qn=}
-\protected\def\preskip {\deferasn{\@qq{\hskip\qskip}\g\qskip=}\@qn=}
-\protected\def\premuskip{\deferasn{\@qq{\hskip\mutoglue\qmuskip}\g\qmuskip=}\@qn=}
-\protected\def\prebox {\deferasn{\@qq{\box\qbox}\g\setbox\qbox=}\@qn=}
+\def\@qwnum {\@qmodify{\penalty\qnum}}
+\def\@qwdim {\@qmodify{\kern\qdim}}
+\def\@qwskip{\@qmodify{\hskip\qskip}}
+\def\@qwmu {\@qmodify{\hskip\mutoglue\qmu}}
+\def\@qwbox {\@qmodify{\box\qbox}}
+\def\@qwtoks{\@qmodify{\xcsdef\@qcs{\the\qtoks}\gincr\@qt}}
+\def\@qwtok {\@qmodify{\gcslet\@qcs\qtok\gincr\@qt}}
+
+\protected\def\prenum {\@qappfalse \@qwnum}
+\protected\def\predim {\@qappfalse \@qwdim}
+\protected\def\preskip{\@qappfalse \@qwskip}
+\protected\def\premu {\@qappfalse \@qwmu}
+\protected\def\prebox {\@qappfalse \@qwbox}
% TODO: Implement prepending of tok and toks, which have their own stacking
% mechanism using \@qt. My current idea for how to implement this is to track
% two integers, \@qh (head) and \@qt (tail), for the allocation of unique
@@ -41,31 +49,37 @@
% \@qh - \@qt. With this compaction scheme, appends and prepends remain
% constant time operations, whereas popping becomes amortized constant
% (assuming that compaction happens only after pops).
-% \protected\def\pretoks{?}
-% \protected\def\pretok{?}
-\protected\def\pushcount {\@qapptrue \precount}
-\protected\def\pushdimen {\@qapptrue \predimen}
-\protected\def\pushskip {\@qapptrue \preskip}
-\protected\def\pushmuskip{\@qapptrue \premuskip}
-\protected\def\pushbox {\@qapptrue \prebox}
-\protected\def\pushtoks {\@qapptrue \deferasn{\@qq{\xcsdef\@qcs{\the\qtoks}\gincr\@qt}\g\qtoks=}\@qn=}
-\protected\def\pushtok {\@qapptrue \deferasn{\@qq{\gcslet\@qcs\qtok\gincr\@qt}\glet\qtok=}\@qn=}
+\protected\def\pushnum {\@qapptrue \@qwnum}
+\protected\def\pushdim {\@qapptrue \@qwdim}
+\protected\def\pushskip{\@qapptrue \@qwskip}
+\protected\def\pushmu {\@qapptrue \@qwmu}
+\protected\def\pushbox {\@qapptrue \@qwbox}
+\protected\def\pushtoks{\@qapptrue \@qwtoks}
+\protected\def\pushtok {\@qapptrue \@qwtok}
+
+\def\@qrnum {\@qmodify{\g\qnum\lastpenalty \if@qpeek\else\unpenalty\fi}}
+\def\@qrdim {\@qmodify{\g\qdim\lastkern \if@qpeek\else\unkern\fi}}
+\def\@qrskip{\@qmodify{\g\qskip\lastskip \if@qpeek\else\unskip\fi}}
+\def\@qrmu {\@qmodify{\g\qmu\gluetomu\lastskip \if@qpeek\else\unskip\fi}}
+\def\@qrbox {\@qmodify{\g\setbox\qbox\lastbox \if@qpeek\copy\qbox\fi}}
+\def\@qrtoks{\@qmodify{{\if@qpeek\else\g\fi\decr\@qt \gletcs\qtok\@qcs \g\qtoks\ea{\qtok}}}}
+\def\@qrtok {\@qmodify{{\if@qpeek\else\g\fi\decr\@qt \gletcs\qtok\@qcs}}}
-\protected\def\popcount {\@qq{\g\qcount\lastpenalty \if@qpeek\else\unpenalty\fi}\@qn=}
-\protected\def\popdimen {\@qq{\g\qdimen\lastkern \if@qpeek\else\unkern\fi}\@qn=}
-\protected\def\popskip {\@qq{\g\qskip\lastskip \if@qpeek\else\unskip\fi}\@qn=}
-\protected\def\popmuskip{\@qq{\g\qmuskip\gluetomu\lastskip \if@qpeek\else\unskip\fi}\@qn=}
-\protected\def\popbox {\@qq{\g\setbox\qbox\lastbox \if@qpeek\copy\qbox\fi}\@qn=}
-\protected\def\poptoks {\@qq{{\if@qpeek\else\g\fi\decr\@qt \gletcs\qtok\@qcs \g\qtoks\ea{\qtok}}}\@qn=}
-\protected\def\poptok {\@qq{{\if@qpeek\else\g\fi\decr\@qt \gletcs\qtok\@qcs}}\@qn=}
+\protected\def\popnum {\@qpeekfalse \@qrnum}
+\protected\def\popdim {\@qpeekfalse \@qrdim}
+\protected\def\popskip{\@qpeekfalse \@qrskip}
+\protected\def\popmu {\@qpeekfalse \@qrmu}
+\protected\def\popbox {\@qpeekfalse \@qrbox}
+\protected\def\poptoks{\@qpeekfalse \@qrtoks}
+\protected\def\poptok {\@qpeekfalse \@qrtok}
-\protected\def\peekcount {\@qpeektrue \popcount}
-\protected\def\peekdimen {\@qpeektrue \popdimen}
-\protected\def\peekskip {\@qpeektrue \popskip}
-\protected\def\peekmuskip{\@qpeektrue \popmuskip}
-\protected\def\peekbox {\@qpeektrue \popbox}
-\protected\def\peektoks {\@qpeektrue \poptoks}
-\protected\def\peektok {\@qpeektrue \poptok}
+\protected\def\peeknum {\@qpeektrue \@qrnum}
+\protected\def\peekdim {\@qpeektrue \@qrdim}
+\protected\def\peekskip{\@qpeektrue \@qrskip}
+\protected\def\peekmu {\@qpeektrue \@qrmu}
+\protected\def\peekbox {\@qpeektrue \@qrbox}
+\protected\def\peektoks{\@qpeektrue \@qrtoks}
+\protected\def\peektok {\@qpeektrue \@qrtok}
\endinput