summaryrefslogtreecommitdiff
path: root/support/splint/tex/yymisc.sty
diff options
context:
space:
mode:
Diffstat (limited to 'support/splint/tex/yymisc.sty')
-rw-r--r--support/splint/tex/yymisc.sty435
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