diff options
Diffstat (limited to 'support/splint/tex/yymisc.sty')
-rw-r--r-- | support/splint/tex/yymisc.sty | 435 |
1 files changed, 262 insertions, 173 deletions
diff --git a/support/splint/tex/yymisc.sty b/support/splint/tex/yymisc.sty index b961135b02..ad9296292d 100644 --- a/support/splint/tex/yymisc.sty +++ b/support/splint/tex/yymisc.sty @@ -1,4 +1,4 @@ -% Copyright 2012-2020, Alexander Shibakov +% Copyright 2012-2024, Alexander Shibakov % This file is part of SPLinT % % SPLinT is free software: you can redistribute it and/or modify @@ -14,133 +14,6 @@ % You should have received a copy of the GNU General Public License % along with SPLinT. If not, see <http://www.gnu.org/licenses/>. -% `data structure access' macros: picking the n-th undelimited parameter -% in a parameter list inside a token register -% it is assumed that none of the arguments is \end, and that there are enough -% parameters to pick the desired one - -\def\getfirst#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tfirst\the#1\end}% -} - -\def\g@tfirst#1#2\end{#1} - -\def\getsecond#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tsecond\the#1\end}% -} - -\def\g@tsecond#1#2#3\end{#2} - -\def\getthird#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tthird\the#1\end}% -} - -\def\g@tthird#1#2#3#4\end{#3} - -\def\getfourth#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tfourth\the#1\end}% -} - -\def\g@tfourth#1#2#3#4#5\end{#4} - -\def\getfifth#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tfifth\the#1\end}% -} - -\def\g@tfifth#1#2#3#4#5#6\end{#5} - -\def\getsixth#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tsixth\the#1\end}% -} - -\def\g@tsixth#1#2#3#4#5#6#7\end{#6} - -\def\getseventh#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@tseventh\the#1\end}% -} - -\def\g@tseventh#1#2#3#4#5#6#7#8\end{#7} - -\def\geteightth#1\to#2{% - #2\expandafter\expandafter\expandafter{\expandafter\g@teightth\the#1\end}% -} - -\def\g@teightth#1#2#3#4#5#6#7#8#9\end{#8} - -\def\getninth#1\to#2{% the `.' is necessary since \TeX's scanning mechanism will - % strip any potential braces surrounding the last parameter - % (assuming there are exactly nine) twice: - % o first, expanding \g@tninth, - % o second, expanding \g@tfirst - #2\expandafter\expandafter\expandafter{\expandafter\g@tninth\the#1.\end}% - #2\expandafter\expandafter\expandafter{\the#2}% -} - -\def\g@tninth#1#2#3#4#5#6#7#8#9\end{\g@tfirst#9\end} - -\def\gettenth#1\to#2{% no need for `.' (or any other placeholder) here, - % since the #9-th parameter to \g@ttenth is a list of - % at least two parameters itself, thus any existing braces - % have survived intact - #2\expandafter\expandafter\expandafter{\expandafter\g@ttenth\the#1\end}% - #2\expandafter\expandafter\expandafter{\the#2}% -} - -\def\g@ttenth#1#2#3#4#5#6#7#8#9\end{\g@tsecond#9\end} - -% removing the first element of a token register if it has more than one; - -\def\sansfirst#1{% - \expandafter\s@nsfirst\expandafter{\the#1}{#1}% -} - -\def\s@nsfirst#1#2{% - \expandafter\s@nsf@rst\expandafter{\eatone#1}{#2}% -} - -\def\s@nsf@rst#1#2{% - \yystringempty{#1}{}{% - #2{#1}% - }% -} - -% a version of the macro above that expands to the original argument with the first element removed - -\def\sansfirstx#1{% - \expandafter\yystringempty\expandafter{\eatone#1}{#1}{\eatone#1}% -} - -% string replacement: all arguments are registers, nothing is expanded, no \next is defined -% note that this is not a greedy replacement: this could be arranged with a more sophisticated macro -% also note that the string being replaced cannot have any braces in it - -\newif\ifyytracereplacements -\newif\ifyyreplaced - -\yytracereplacementstrue - -\def\yyreplacestring#1\in#2\with#3{% - \expandafter\def\expandafter\r@placestring\expandafter##\expandafter1\the#1##2\end{% - \def\r@placestring{##2}% is this the string at the very end? - \ifx\r@placestring\empty % then it is the one we inserted, - % report - \yyreplacedfalse - \ifyytracereplacements - \errmessage{string <\the#1> not present in \the#2}% do not change the register if the string is not there - \fi - \else % remove the extra copy of #1\end at the end - \yyreplacedtrue - \expandafter#2\expandafter\expandafter\expandafter - {\expandafter\r@plac@string\expandafter{\the#3}{##1}##2\end}% - \fi}% end of \r@placestring definition - \expandafter\def\expandafter\r@plac@string - \expandafter##\expandafter1% - \expandafter##\expandafter2% - \expandafter##\expandafter3% - \the#1\end{##2##1##3}% - \expandafter\expandafter\expandafter\r@placestring\expandafter\the\expandafter#2\the#1\end -} - % creating a sequence containing all pairs from the two given sequences; % the (long) string produced by the \diagprod macro % lists all the elements so that each ordered pair ab where a and b are @@ -287,9 +160,9 @@ } % namespace management for macros -% note that if one of the sequences were made \let\name. the macros would break; +% note that if one of the sequences, say \name, were made \let\name. the macros would break; % this can be fixed by using a more sophisticated comparison but was decided against -% in the interest of efficiency; the old version (that used a control sequence +% in the interests of efficiency; the old version (that used a control sequence % as a `stop marker') was more prone to this bug. % the next sequence is not merely a convenient abbreviation; it is useful if one @@ -480,6 +353,10 @@ } % dynamic typing macros +% +% (1) define a macro prototype, this also defines a few other macros to be used in +% special circumstances, such as for error checking (strict), and to use where +% expansion must be suppressed (such as diagnostic output) \def\defp#1#2#{% flexible dynamic type checking \toksa\expandafter\expandafter\expandafter{\yyuniontag#1}% @@ -494,38 +371,53 @@ \def#1#2% } -% define the macro with checking of the prototype +% (2) define the macro (#1) with an automatic prototype (if the parameter list is empty) or +% with prototype checking; the prototype should have been defined earlier with \.{\\defp} -\def\defu#1#2#{% - \restorecs\parserprototypesnamespace#1% +\def\defc#1#2#{% + \restorecs\parserprototypesnamespace#1% \toksa{#2}% \edef\next{\the\toksa}% - \ifx#1\next - \yybreak{\def#1#2}% + \ifx\next\empty + \yybreak{\expandafter\def\expandafter#1#1}% \else - \toksb\expandafter{#1}% - \yybreak{% - {\newlinechar=`^^J% - \errhelp{the prototype of #1is from <parser-strict:headers>^^J% - you might want to look for a \defp#1line... somewhere}% - \errmessage{macro definition of \noexpand#1 - does not match its prototype:^^J - \the\toksa\space (should be \the\toksb)}% + \ifx\next#1% + \yybreak@{\expandafter\def\expandafter#1#1}% + \else + \yybreak@{% + \toksb\expandafter{#1}% + {% + \newlinechar=`^^J% + \edef\next{% + \errhelp{the prototype of \string#1 is from <\parserprototypesnamespace>^^J% + you might want to look for a \expandafter\string\expandafter\defp\string#1... line somewhere}% + }\next + \errmessage{macro definition of \string#1 does not match its prototype:^^J + \the\toksa\space (should be \the\toksb)}% + }% }% - }% + \fi \yycontinue } -% define the macro with an automatic prototype - -\def\defc#1{% - \restorecs\parserprototypesnamespace#1% - \expandafter\def\expandafter#1#1% -} +% (3) once a set of macros have been defined, all current definitions are added to the +% \.{\\yyunion} list in a namespace of your choosing by the \.{\\toyyunion} command \def\t@yyunion#1#2{\def\currentyyunionnamespace{#2}\savecslist{#2}#1} \def\toyyunion#1{\expandafter\t@yyunion\yyuniontag{#1}} +% this command sequence provides a standard set of parameters for the scheme above +% to work; note that these settings will stay unchanged till the next command + +\def\yyuniondeclare#1#2{% #1 is the command sequence that holds the union + % #2 is the root of the namespace + \def#1{\currentyyunionnamespace}% subset of the global union that deals with footnotes + \def\yyuniontag{#1}% + \def\parserstrictnamespace{#2:strict}% + \def\parserprototypesnamespace{#2:headers}% + \def\parserdebugnamespace{#2:debug}% +} + {\catcode`\ =13 \aftergroup\def\aftergroup\activespace\aftergroup{\aftergroup \aftergroup}}% active space {\catcode`\% =12 \aftergroup\def\aftergroup\harmlesscomment\aftergroup{\aftergroup%\aftergroup}}% not really a comment {\catcode`\{ =12 \catcode`\[=1 \aftergroup\def\aftergroup\lbchar\aftergroup[\aftergroup{\aftergroup}}% not really a brace @@ -662,6 +554,8 @@ \edef\next{\let\the\toksb\the\toksa}\next }% +\def\tokenpp#1{} % ignore \prodstyle{\%prec}-like declarations + \def\numberstochars#1{% \ifx\end#1% \yybreak{}% @@ -690,6 +584,51 @@ \yycontinue } +% packing \write lines to avoid unnecessary expansions; it is \outer +% because it would be pretty useless inside a macro since all the category +% codes have already been set + +\outer\def\packliteral{% + \begingroup + \catcode`\\=\other + \catcode`\{=\other + \catcode`\}=\other + \catcode`\$=\other + \catcode`\&=\other + \catcode`\#=\other + \catcode`\%=\other + \catcode`\~=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\ =\other + \catcode`\^^M=\other + \p@ckliteral +} + +{\catcode`\%=\other\gdef\p@ckliteral#1%{\toksa{#1}\expandafter\endgroup\expandafter\p@ckl@teral\expandafter{\the\toksa}}} + +\def\p@ckl@teral#1#2{#2{#1}} + +% example of use: \packliteral {\crazy\sequence }% \toksa % this will save ` \crazy...' as cat 12 code characters in \toksa + +% a (relatively) safe way to turn a command sequence into its name (sans the escape character) made up of nonletters + +\def\csstring{% + \ifnum\escapechar>-1 + \yybreak{\cs@tring}% + \else + \yybreak{}% + \yycontinue +} + +\def\cs@tring{% + \ifnum\escapechar>255 + \yybreak{}% + \else + \yybreak{\expandafter\eatone\string}% + \yycontinue +} % other parser and lexer variables @@ -778,7 +717,6 @@ % \yyval and \yylval will be token registers \settokreg{yyval}% \settokreg{yylval}% - \setnulstack{astarray}% an array of AST nodes \setnulstack{yyssa}% \setnulstack{yyvsa}% } @@ -796,14 +734,6 @@ \settokreg{yytextseenpure}% % as \yytext et al except they collect characters \settokreg{yybytepure}% % with category code 11 (letter) and the same character code % - \settokreg{yyformat}% % the registers that serve the same role - \settokreg{yyformatseen}% % as \yytext et al except they collect format - \settokreg{yyfbyte}% % commands - % - \settokreg{yystash}% % the registers that serve the same role - \settokreg{yystashseen}% % as \yytext et al except they collect stashed - \settokreg{yysbyte}% % tokens - % \setcntreg{yycurrentstate}% \setcntreg{yycurrentstatelocal}% a state variable used in eob macros \setcntreg{yyc}% @@ -841,6 +771,43 @@ % take advantage of the grouping mechanism provided by \TeX; note that the grouping approach seems % to be the only viable solution if the stack mechanism is `optimized' +% optimization macros: currently, the level of optimization has to be consistent throughout the +% document, i.e. \optimize macros have to be called on the same arrays after loading. +% the reason is the yyfaststack.sty file that modifies the \newtable macro once for all the tables + +\def\optimize#1{% + \setoptopt{#1}% + \tempca\z@ + \bloop + \tempcb=\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\@MM\fi\relax + \ifnum\tempcb<\@MM % + \expandafter\edef\csname #1\parsernamespace\the\tempca\endcsname{\the\tempcb}% + \advance\tempca\@ne + \repeat +} + +\def\optimizetext#1{% optimizing text arrays + \setoptopt{#1}% + \tempca\z@ + \@ptimizetext{#1} +} + +\def\@ptimizetext#1{% + \edef\next{\expandafter\ifcase\expandafter\tempca\the\csname#1\endcsname\else\end\fi}% + \ifx\next\endcontainer + \let\next\eatone + \else + \expandafter\edef\csname #1\parsernamespace\the\tempca\endcsname{\next}% + \advance\tempca\@ne + \let\next\@ptimizetext + \fi + \next{#1}% +} + +\def\setoptopt#1{% + \expandafter\let\csname optopt[#1]\parsernamespace\endcsname\end +} + % optimization options \def\optimizeall{% @@ -869,7 +836,6 @@ \optimize{yycheck}% \optimize{yyprhs}% \optimize{yyrhs}% - \optimize{yytoknum}% \optimize{yystos}% \optimizetext{yytname}% \fi @@ -886,7 +852,7 @@ \pinittoks{}% \input #2 % load main parser table \settokens % set the values of all tokens - \yystringempty{#4}{}{% + \expandafter\yystringempty\expandafter{#4}{}{% \input #4 % use token equivalence table to set the values of non-string tokens }% #5% (a)dditional setups @@ -1097,11 +1063,11 @@ \expandafter\noexpand\csname (#1)\endcsname}}\next\s@tspecialcharsfrom} \def\putother#1\in#2{% - \tempca=\catcode`\^^A\relax - \tempcb=\uccode`\^^A\relax - \uccode`\^^A=#1\relax - \uppercase{\edef\next{#2{^^A}}}\next - \uccode`\^^A=\tempcb + {% + \uccode`\^^A=#1\relax + \uppercase{\edef\next{#2{^^A}}}% + \expandafter + }\next } % listing all the rules in a macro @@ -1299,7 +1265,7 @@ \def\termsymname#1#2{% set the symbolic name, if it is nonempty \def\next{#2}% \ifx\next\empty - \else % there is a symolic name + \else % there is a symbolic name \expandafter\ifx\csname$[#2]\endcsname\relax% i$ this name unassigned? \setnameflag{#2}\end % ... this name has been explicitly set \setuprefs{#2}{\the\tempca}% @@ -1438,6 +1404,110 @@ \catcode`\^^A=\tempca +% the number below (15) is not chosen randomly but is designed to follow the conventions +% outlined in plain.tex: +% +% The following counters are reserved: +% ... +% 10 count allocation +% 11 dimen allocation +% 12 skip allocation +% 13 muskip allocation +% 14 box allocation +% 15 toks allocation +% ... +% +% Here it is given a symbolic name for convenience. Note that this allocation is +% needed even if only the yyfaststack.sty stack macros are used (it is used in the +% mechanism that makes \yy0{\the\yy1\the\yy2} assignments possible). + +\countdef\toptoks=15 % register responsible for token allocations + +% value and state stack access macros: these may be replaced by the macros in yyfaststack.sty + +\def\yyreadvstack#1\upto#2{% assume that #2 > 0 + \edef\sts{\noexpand\splitstack{\number#2}{\expandafter\xincrement\expandafter{\number\toptoks}}}#1\stackend#1% +} + +\long\def\splitstack#1#2#3{% + \expandafter\def\csname$'#1\endcsname{#3}% $ + \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers + \expandafter\toksdef\csname$$'#1\endcsname=#2 + \toks#2{#3}% + \fi + \ifnum#1=\@ne %we have read the values + \let\sts\scoopupstack + \else + \edef\sts{\noexpand\splitstack{\xdecrement{#1}}{\xincrement{#2}}}% + \fi +} + +\def\yypeekvstack#1\upto#2{% assume #2 > 0 + \edef\sts{\noexpand\peelstack{\number#2}{\expandafter\xincrement\expandafter{\number\toptoks}}}#1\relax% +} + +\long\def\peelstack#1#2#3{% + \expandafter\def\csname$'#1\endcsname{#3}% $ + \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers + \expandafter\toksdef\csname$$'#1\endcsname=#2 + \toks#2{#3}% + \fi + \ifnum#1=\@ne %we have read the values + \let\sts\eatone + \else + \edef\sts{\noexpand\peelstack{\xdecrement{#1}}{\xincrement{#2}}}% + \fi +} + +% macros to read the stack in `natural order' (see also yyfaststack.sty) +\def\yypeekustack#1{% we do not compute anything unless the postprocessor + % detected an implicit rule + \ifnum\number\yycomputeilength{\number\yyn}>\z@ + \yybreak{\edef\sts{\noexpand\peelstackreverse{1}{\expandafter + \xincrement\expandafter{\number\toptoks}}}#1\relax}% + \else + \yybreak{}% + \yycontinue +} + +\long\def\peelstackreverse#1#2#3{% + \ifnum#2<\@cclvi % we have not reached the maximum allocated number of token registers + \expandafter\toksdef\csname$$$'#1\endcsname=#2 + \toks#2{#3}% + \fi + \ifnum\number\yycomputeilength{\number\yyn}>#1 % + \edef\sts{\noexpand\peelstack{\xincrement{#1}}{\xincrement{#2}}}% + \else + \let\sts\eatone + \fi +} + +\def\yyimplicitlengthset#1#2{\expandafter\def\csname ilength$$[#1]\endcsname{#2}} + +\def\yycomputeilength#1{% + \expandafter\ifx\csname ilength$$[#1]\endcsname\relax + \yybreak{0 }% + \else + \yybreak{\csname ilength$$[#1]\endcsname\space}% + \yycontinue +} + +% macros to support new printing routines + +\def\yypeeksstack#1\upto#2\withprefix#3{% assume #2 > 0 + \edef\sts{\noexpand\peelsstack{\number#2}}% + \expandafter\def\expandafter\sts\expandafter{\sts{#3}{}}#1\relax% +} + +\long\def\peelsstack#1#2#3#4{% + \ifnum#1=\@ne %we have read the values + #3\let\sts\eatone + \else + \edef\sts{\noexpand\peelsstack{\xdecrement{#1}}}% + \expandafter\def\expandafter\sts\expandafter{\sts{#2}{#2{#4}#3}}% + \fi +} + % stack variable access \def\ym#1){% @@ -1516,14 +1586,14 @@ \def\p@twwassignment#1#2{% \edef\sts{\noexpand\p@@wwassignment{\expandafter\xdecrement\expandafter{\number#1}}}% - \expandafter\def\expandafter\sts\expandafter{\sts{#2}}% - \yyvsa\empty + \expandafter\def\expandafter\sts\expandafter{\sts{#2}}% define the stack iterator + \yyvsa\empty % execute the stack } \def\p@@wwassignment#1#2#3{% - \ifnum#1=\z@ %we have got to the element we need + \ifnum#1=\z@ % we have got to the element we need \yybreak{\yystringempty{#2}{#3}{#2{#3}}\let\sts\eatone}% - \else + \else % keep descending into the stack \yybreak{\edef\sts{\noexpand\p@@wwassignment{\xdecrement{#1}}}% \expandafter\def\expandafter\sts\expandafter{\sts{#2}}}% \yycontinue @@ -1545,17 +1615,35 @@ \yycontinue } -% a macro to access the value stack in direct order, i.e.\ from right to left +% a macro to access the value stack in the direct order, i.e.\ from right to left % no \yylen is necessary \def\bb#1#{% \ifnum#1<\@ne - \yybreak{\putyyval}% + \yybreak{\yyvalx}% \else \yybreak{\p@twwassignment{#1}}% \yycontinue } +% this macro should only be inserted by the preprocessor, it accesses +% the stack in a `natural' order which is the opposite of how `native' +% bison does it + +\def\yg#1#2#3{% #1 is the `native' bison index (e.g. for a: b c d rule, + % b is $1 + % #2 is the `natural' index (so b would be $3 for the + % rule above + % #3 is the implicit `yyilen' (see yyparse.sty for more information) + \ifnum\yyilen=\z@ % this is probably an inline action, so yyreduce + % will only generate the `natural' indexed token + % registers + \yybreak{\csname $$$'#2\endcsname}% + \else + \yybreak{\ym#1)}% save one level of expansion ... + \yycontinue +} + % symbolic name macros that prepare the environment for the use of the stack access macros above \def\setsymcs#1#2{% @@ -1587,3 +1675,4 @@ \def\ferrmessage#1{{\newlinechar`\^^J\immediate\write16{\parsernamespace::#1^^J}}} +\newif\ifbootstrapmode |