diff options
Diffstat (limited to 'support/splint/examples/count/count.sty')
-rw-r--r-- | support/splint/examples/count/count.sty | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/support/splint/examples/count/count.sty b/support/splint/examples/count/count.sty new file mode 100644 index 0000000000..bb8998e64f --- /dev/null +++ b/support/splint/examples/count/count.sty @@ -0,0 +1,552 @@ +% the sequences in this file have the eventual goal of implementing macros that count and compare token sequences +% (as either parameters or contents of token registers) in expandable manner. +% currently, a new sequence is prepared first, consisting of `markers' +% that indicate whether the token in the coresponding position of the +% original sequence is a potential blank space or brace (closing or +% opening); +% the macros then make the determination about the last possible blank +% on whether this is a true space or not; the goal is to make this +% macro independent of the value of \escapechar +% +% as of now the implementation is far from refined although an expandable conting macro +% can be easily produced + +\catcode`\@=11 +\input ../../tex/yycommon.sty +\input ../../tex/yymisc.sty + +%%%%%%%%%%%%% the material before this point should be included from appropriate files + +% #1 -- `call stack' +% #2 -- remaining sequence +% #3 -- `parsed' sequence + +\def\yypreparsetokensequenc@#1#2#3{% + \yystringempty{#2}{#1{#3}}{\yypreparsetokensequen@@{#1}{#2}{#3}}% +} + +\def\yypreparsetokensequen@@#1#2#3{% remaining sequence is nonempty + \yystartsinbrace{#2}{\yydealwithbracedgroup{#1}{#2}{#3}}{\yypreparsetokensequ@n@@{#1}{#2}{#3}}% +} + +\def\yydealwithbracedgroup#1#2#3{% the first token of the remaining sequence is a brace + \iffalse{\fi\yydealwithbracedgro@p#2}{#1}{#3}% +} + +\def\yydealwithbracedgro@p#1{% + \yypreparsetokensequenc@{\yyrepackagesequence}{#1}{}% +} + +% #1 -- parsed sequence +% this is a sequence to `propagate expansion' into the next parameter. +% the same can be achieved by packaging the whole sequence with a +% \csname ... \endcsname pair and using a simple \expandafter + +\def\yyrepackagesequence#1{% + \yyrepackagesequenc@{}#1\end +} + +% #1 -- `packaged' sequence (\expandafter\expandafter\expandafter ? ...) +% #2 -- the next category 12 character or \end + +\def\yyrepackagesequenc@#1#2{% + \ifx#2\end + \yybreak{\yyrepackagesequ@nc@{#1\expandafter\expandafter\expandafter}}% + \else + \yybreak{\yyrepackagesequenc@{#1\expandafter\expandafter\expandafter#2}}% + \yycontinue +} + +% #1 -- `packaged' sequence (\expandafter\expandafter\expandafter ? ...) +% this macro is followed by the remainder of the original sequence with a so far +% unmatched right brace, the `call stack' and the parsed sequence. + +\def\yyrepackagesequ@nc@#1{% + \expandafter\expandafter\expandafter\yyrepackagesequ@nc@swap#1{\expandafter\eatone\string}% +} + +% #1 -- parsed sequence without packaging + +\def\yyrepackagesequ@nc@swap#1#{% + \yyrepackagesequ@nc@sw@p{#1}% +} + +% #1 -- parsed `inner' sequence +% #2 -- remainder of the original sequence +% #3 -- `call stack' +% #4 -- parsed sequence so far + +\def\yyrepackagesequ@nc@sw@p#1#2#3#4{% + \yypreparsetokensequenc@{#3}{#2}{#4[#1]}% +} + +% `braced group' thread ends here + +% #1 -- `call stack' +% #2 -- remaining sequence +% #3 -- `parsed' sequence + +\def\yypreparsetokensequ@n@@#1#2#3{% the remaining group in #2 is nonempty and does not start with a brace + \yystartsinspace{#2}{\yyconsumetruespace{#1}{#2}{#3}}{\yypreparsetokenseq@@n@@{#1}{#2}{#3}}% +} + +\def\yyconsumetruespace#1#2#3{% + \expandafter\yyconsumetruespac@swap\expandafter{\eatonespace#2}{#1}{#3.}% +} + +\def\yyconsumetruespac@swap#1#2#3{% + \yypreparsetokensequenc@{#2}{#1}{#3}% +} + +% `group starting with a true (character code 32, category code 10) space' thread ends here + +% #1 -- `call stack' +% #2 -- remaining sequence +% #3 -- `parsed' sequence + +\def\yypreparsetokenseq@@n@@#1#2#3{% a nonempty group, that does not start with a brace or a true space + \yymatchblankspace{#2}{\yyrescanblankspace{#2}{#1}{#3}}{\yypreparsetokens@q@@n@@{#1}{#2}{#3}}% +} + +% #1 -- remaining sequence +% #2 -- `call stack' +% #3 -- `parsed' sequence + +\def\yyrescanblankspace#1#2#3{% + \expandafter\expandafter\expandafter + \yyrescanblankspac@swap + \expandafter\expandafter\expandafter{\expandafter\yynormalizeblankspac@\meaning#1}{#2}{#3*}% +} + +\def\yyrescanblankspac@swap#1#2#3{% + \yystartsinspace{#1}{% + \expandafter\yyrescanblankspac@sw@p\expandafter{\eatonespace#1}{#2}{#3}% + }{% + \expandafter\yyrescanblankspac@sw@p\expandafter{\eatone#1}{#2}{#3}% + }% +} + +\def\yyrescanblankspac@sw@p#1#2#3{% + \yypreparsetokensequenc@{#2}{#1}{#3}% +} + +% `group starting with a blank space' ends here + +% #1 -- `call stack' +% #2 -- remaining sequence +% #3 -- `parsed' sequence + +\def\yypreparsetokens@q@@n@@#1#2#3{% nonempty group starting with a non blank, non brace token + \expandafter\yypreparsetokens@q@@n@@swap\expandafter{\eatone#2}{#1}{#30}% +} + +\def\yypreparsetokens@q@@n@@swap#1#2#3{% + \yypreparsetokensequenc@{#2}{#1}{#3}% +} + +% #1 -- `call stack' +% #2 -- remaining sequence +% #3 -- `parsed' sequence + +\def\yydebracesequence#1#2#3{% + \yybracesleft#3[\end{#1}{#2}% +} + +% #1 -- tokens preceding the brace +% #2 -- tokens following the brace +% #3 -- `call stack' +% #4 -- remaining sequence + +\def\yybracesleft#1[#2\end#3#4{% + \if9#29% + \yybreak{\yyfirstoftwo}% + \else + \yybreak{\yysecondoftwo}% + \yycontinue{#3{#4}}{\yydebracesequenc@swap{#4}{#3}{#1#2}}% +} + +\def\yydebracesequenc@swap#1#2#3{% + \expandafter\expandafter\expandafter + \yydebracesequenc@sw@p + \expandafter\expandafter\expandafter{\yygrabprebrace#1}{#2}{#3}% +} + +\def\yydebracesequenc@sw@p#1#2#3{% + \yydebracesequ@nc@sw@p#3\end{#1}{#2}% +} + +\def\yydebracesequ@nc@sw@p#1[\end#2#3{% + \yydebracesequence{#3}{#2}{#1}% +} +\def\yygrabprebrace#1#{% + \yygrabprebrac@{#1}% +} + +\def\yygrabprebrac@#1#2{#1#2} + +% the `debracing group' ends here + +% string comparison macros below are woefully inefficient and can be replaced by a much +% shorter and faster version; they are easy to analyze, though; + +% #1 -- string of category code 12 or 10 characters +% #2 -- string of category code 12 or 10 characters + +\def\yycomparesimplestrings#1#2{% + \yystringempty{#1}{% + \yystringempty{#2}{\yyfirstoftwo}{\yysecondoftwo}% + }{\yycomparesimplestrings@{#1}{#2}}% +} + +\def\yycomparesimplestrings@#1#2{% the first string is nonempty + \yystringempty{#2}{\yysecondoftwo}{\yycomparesimplestrings@@{#1}{#2}}% +} + +\def\yycomparesimplestrings@@#1#2{% both strings are nonempty + \yystartsinspace{#1}{% + \yystartsinspace{#2}{\yyabsorbfirstspace{#1}{#2}}{\yysecondoftwo}% + }{% + \yystartsinspace{#2}{\yysecondoftwo}{\yyabsorbfirstnonspace{#1}{#2}}% + } +} + +\def\yyabsorbfirstspace#1#2{% + \expandafter\yyabsorbfirstspac@swap\expandafter{\eatonespace#1}{#2}% +} + +\def\yyabsorbfirstspac@swap#1#2{% + \expandafter\yyabsorbfirst@swap\expandafter{\eatonespace#2}{#1}% +} + +\def\yyabsorbfirstnonspace#1#2{% + \expandafter\yyabsorbfirstnonspac@swap\expandafter{\eatone#1}{#2}% +} + +\def\yyabsorbfirstnonspac@swap#1#2{% + \expandafter\yyabsorbfirst@swap\expandafter{\eatone#2}{#1}% +} + +\def\yyabsorbfirst@swap#1#2{% + \yycomparesimplestrings{#2}{#1}% +} + +% `compare strings of category code 12' thread ends here + +% #1 -- a balanced sequence of tokens +% #2 -- a `parsed version' of the same sequence +% +% #1 should be such that \eatone#1 does not lead to an immediate error + +\def\yycomparetailsignatures#1#2{% + \yypreparsetokensequenc@{\yycomparesimplestrings{#2}}{#1}{}% +} + +% #1 -- `call stack' +% #2 -- remaining sequence +% #3 -- remaining parsed sequence +% #4 -- resolved sequence + +\def\yyresolvespaces#1#2#3#4{% + \yystringempty{#2}{#1{#4}}{\yyresolveoneblank#3\end{#2}{#4}{#1}}% +} + +\def\yyresolveoneblank#1{% + \if#1*% + \expandafter\yyfirstoftwo + \else + \expandafter\yysecondoftwo + \fi + {\yyresolveonebl@nk}{% + \ifx#1.% + \expandafter\yyfirstoftwo + \else + \expandafter\yysecondoftwo + \fi + {\yyresolveonebl@nk}% + {\yyconsumebothnonblanks}% + }% +} + +% #1 -- the remainder of the parsed sequence +% #2 -- remaining sequence +% #3 -- resolved sequence + +\def\yyresolveonebl@nk#1\end#2#3{% + \expandafter\yycomparetailsignatures\expandafter{\eatone#2}{#1}% + {\expandafter\yyresolvespac@sswap\expandafter{\eatone#2}{#1}{#3+}}% + {\expandafter\yyresolveonebl@nklight\expandafter{\eatone#2}{#1}{#3-}}% +} + +% #1 -- remaining sequence +% #2 -- remaining parsed sequence +% #3 -- resolved sequence +% #4 -- `call stack' + +\def\yyresolvespac@sswap#1#2#3#4{% + \yyresolvespaces{#4}{#1}{#2}{#3}% +} + +\def\yyconsumebothnonblanks#1\end#2#3{% + \expandafter\yyconsumebothnonblanksswap\expandafter{\eatone#2}{#1}{#30}% +} + +\def\yyconsumebothnonblanksswap#1#2#3#4{% + \yyresolvespaces{#4}{#1}{#2}{#3}% +} + +% #1 -- remaining sequence +% #2 -- the remainder of the parsed sequence +% #3 -- resolved sequence + +\def\yyresolveonebl@nklight#1#2#3{% + \yyresolveonebl@nklighttest#2\end{#1}{#3}% +} + +\def\yyresolveonebl@nklighttest#1#2\end#3#4{% + \yycomparetailsignatures{#3}{#2}% + {% + \if#1*% + \expandafter\yyfirstoftwo + \else + \expandafter\yysecondoftwo + \fi + {\yyresolvespac@sswap{#3}{#2}{#4+}}% + {\yyresolvespac@sswap{#3}{#2}{#40}}% + }% + {\yyresolveonebl@nklight{#3}{#2}{#4-}}% +} + +% `space resolution code' ends here + +% #1 -- remaining parsed sequence +% #2 -- analysed sequence + +\def\yyanalysetokens@#1#2{% + \yystringempty{#1}{{#2}}% + {\yyanalysetok@ns@#1\end{#2}}% +} + +\def\yyanalysetok@ns@#1#2\end{% + \ifx#1.% + \expandafter\yyfirstoftwo + \else + \expandafter\yysecondoftwo + \fi + {\yygrabablank{#2}}% + {% + \ifx#1[% not a space, an opening brace + \expandafter\yyfirstoftwo + \else + \expandafter\yysecondoftwo + \fi + {% + \yydisableobrace{#2}% + }{% + \ifx#1]% not a space, a closing brace + \expandafter\yyfirstoftwo + \else + \expandafter\yysecondoftwo + \fi + {% + \yydisablecbrace{#2}% + }{% neither space nor brace + \yygrabtokenraw{#2}% + }% + }% + }% +} + +% #1 -- remaining parsed sequence +% #2 -- analysed sequence +% #3 -- next token + +\def\yygrabtokenraw#1#2#3{% + \expandafter\yyanalysetokens@swap\expandafter{\meaning#3}{#1}{#2}% +} + +\def\yyanalysetokens@swap#1#2#3{% + \yyanalysetokens@{#2}{#3t#1e}% +} + +\def\yygrabablank#1#2 {% + \yyanalysetokens@{#1}{#2s0e}% +} + +% #1 -- remaining parsed sequence +% #2 -- analysed sequence + +\def\yydisablecbrace#1#2{% + \yydisablecbrac@{}#1\relax#2\end +} + + +\def\yydisablecbrac@#1#2{% + \ifx#2\end + \yybreak{\yydisablecbrac@@{#1\expandafter\expandafter\expandafter}}% + \else + \yybreak{\yydisablecbrac@{#1\expandafter\expandafter\expandafter#2}}% + \yycontinue +} + +\def\yydisablecbrac@@#1{% + \expandafter\expandafter\expandafter + \yydisablecbrace@@@#1\end + \expandafter\expandafter\expandafter + {\iffalse}\fi\string +} + +\def\yydisablecbrace@@@#1\relax#2\end#3{% + \yystartsinspace{#3}% + {\expandafter\yyanalysetok@nsswap\expandafter{\eatonespace#3}{#1}{#2c1e}}% + {\expandafter\yyanalysetok@nsswap\expandafter{\eatone#3}{#1}{#2c2e}}% +} + +\def\yyanalysetok@nsswap#1#2#3{% + \iffalse{\fi\yyanalysetokens@{#2}{#3}#1}% +} + +% #1 -- remaining parsed sequence +% #2 -- analysed sequence + +\def\yydisableobrace#1#2{% + \yydisableobrac@{}#1\relax#2\end +} + + +\def\yydisableobrac@#1#2{% + \ifx#2\end + \yybreak{\yydisableobrac@@{#1\expandafter\expandafter\expandafter}}% + \else + \yybreak{\yydisableobrac@{#1\expandafter\expandafter\expandafter#2}}% + \yycontinue +} + +\def\yydisableobrac@@#1{% + \expandafter\expandafter\expandafter + \yydisableobrace@@@#1\end + \expandafter\expandafter\expandafter + {\iffalse}\fi\string +} + +\def\yydisableobrace@@@#1\relax#2\end#3{% + \yystartsinspace{#3}% + {\expandafter\yyanalysetok@nsswap\expandafter{\eatonespace#3}{#1}{#2o1e}}% + {\expandafter\yyanalysetok@nsswap\expandafter{\eatone#3}{#1}{#2o2e}}% +} + +% \ifx1\expandafter\eatone\string\11% check if \escapechar is nontrivial + +\uccode`\ =`\- + +\uppercase{\def\dotspace{ }} + +\toksa\expandafter\expandafter\expandafter{\expandafter\meaning\dotspace} + +\toksb{-} + +\toksc{#2} + +\toksd\toksa + +\yyreplacestring\toksb\in\toksa\with\toksc + +\toksc{} +\yyreplacestring\toksb\in\toksd\with\toksc + +\expandafter\def\expandafter\yymatchblankspac@\expandafter#\expandafter1\the\toksd{% + \yystringempty{#1}{\expandafter\yysecondofthree\expandafter{\string}}% + {\expandafter\yythirdofthree\expandafter{\string}}% +} + +\edef\yymatchblankspace#1{% is it \catcode 10 token? + \noexpand\iffalse{\noexpand\fi + \noexpand\expandafter + \noexpand\yymatchblankspac@ + \noexpand\meaning#1\the\toksd}% +} + +% the idea behind the sequence below is that a leading character of category code 10 +% is replaced either by a character of category code 10 and charachter code 32 or a character +% of category code 12 and character code other than 32 +% note that while it is tempting to replace the definition below by something that ends in +% ... blank space #2{ ... with the hope of absorbing the result of \meaning in one step, +% this will not give the desired result in case of an active character, +% say, `~' that had been \let to the normal blank space + +\expandafter\def\expandafter\yynormalizeblankspac@\expandafter#\expandafter1\the\toksd{} + +%% test code begins here + +\tracingmacros=3 +\tracingonline=3 + +\catcode`\ =13\relax% +\def\actspace{ }% +\catcode`\ =10\relax% + +\catcode`\.=13\relax% +\def\actdotspace{.}% +\catcode`\.=12\relax% + +\edef\makefunkydotspace{\let\expandafter\noexpand\actdotspace= \dotspace} +\edef\makefunkyspace{\let\expandafter\noexpand\actspace= \space} + +\makefunkyspace +\makefunkydotspace + +\def\identity#1{#1} + +%\def\tempseq{\space\dotspace\space\space\dotspace\expandafter\noexpand\actspace\expandafter\noexpand\actdotspace +% \end\noexpand\fi\noexpand\else\noexpand\iffalse} +%\def\tempseq{\space\dotspace e} + +%\edef\mypars@{% +% \noexpand\yypreparsetokensequenc@{\noexpand\identity}% +% {\tempseq}% +% {}% +%} + +%\edef\myparse{\mypars@} + +%\toksa\expandafter{\myparse} + +%\showthe\toksa + +%\edef\myresolve{\noexpand\yyresolvespaces{\errmessage}% +% {\tempseq}% +% {\the\toksa}{} +%} + +%\show\myresolve + +%\myresolve + +\catcode`\<=1 +\catcode`\>=2 +\uccode`\<=32 +\uccode`\>=32 + +\uppercase{\edef\temptest{<> \space\space\dotspace\expandafter\noexpand\actspace\expandafter\noexpand\actdotspace{{} {{}{{ u o l k kk + \end\noexpand\fi\noexpand\else\noexpand\iffalse{}} }}}}} + +%\uppercase{\edef\temptest{\dotspace E <>}} + +\show\temptest + +\def\displaypreparse#1{% + \expandafter\errmessage\expandafter{\romannumeral-1\yypreparsetokensequenc@{\yyanalysetokens@}{#1}{}{}#1}% +} + +%\def\displaydebraceparse#1{% +% \yypreparsetokensequenc@{\yydebracesequence{\displayseq}{#1}}{#1}{}% +%} + +%\def\displayseq#1{\toksa{#1}\showthe\toksa} + +\expandafter\displaypreparse\expandafter{\temptest} + +\errmessage{stop!} + +%\expandafter\displaydebraceparse\expandafter{\temptest} + +\end |