Function texlang_stdlib::expansion::get_expandafter_optimized
source · pub fn get_expandafter_optimized<S: TexlangState>() -> BuiltIn<S>
Expand description
Get the optimized \expandafter
command.
This is a more complex implementation of \expandafter
that is optimized for handling
repeated \expandafter
tokens.
It contains two optimizations, as described below.
These optimizations where developed “theoretically” and with no benchmarking, so it
remains to be seen if they actually make expansion faster.
For this reason both the optimized and simple \expandafter
implementations are maintained.
We now describe the two optimizations.
First, \expandafter
control sequences are often linked together in the following format:
\expandafter<token 1>\expandafter<token 2>...\expandafter<token n><token n+1>
Here, to expand the first \expandafter
we just need to expand <token n+1>
.
In the original implementation of TeX this works via recursion: the ith \expandafter
requests expansion of the second-to-next token, which is the (i+1)th \expandafter
.
After n recursions, the last token is finally expanded.
In the optimized implementation here, the token stream is scanned ahead for as long as the pattern
\expandafter<token i>
repeats.
The token <token n+1>
is expanded and the intermediate \expandafter
tokens are dropped from the input.
This is still an O(n) operation, but results in only 1 Rust function stack being used, rather than n.
Second, \expandafter
commands are often grouped together like this:
\expandafter\expandafter\expandafter\A\expandafter\B\C
This TeX code causes \C
to be expanded first, then \B\
and finally \A
.
When the leading \expandafter
is expanded, the first optimization kicks in and \C
will be expanded, leaving:
\expandafter\A\B\Cexpanded
The second optimization is that the leading \expandafter
that is left over will also be expanded
without yielding control to the main expansion loop.
If, after this pass, the leading token is again an \expandafter
token, it will be expanded too.
This process continues repeatedly until no \expandafter
tokens are left at the start of the token stream.