[latex3-commits] [git/LaTeX3-latex3-latex3] fast-false-true: Optimise reverse-logic conditionals (a8d219fed)
Phelype Oleinik
phe.h.o1 at gmail.com
Tue Oct 29 14:20:48 CET 2019
Repository : https://github.com/latex3/latex3
On branch : fast-false-true
Link : https://github.com/latex3/latex3/commit/a8d219fed749e1938aa0b7b80e5c54a465e4fa7e
>---------------------------------------------------------------
commit a8d219fed749e1938aa0b7b80e5c54a465e4fa7e
Author: Phelype Oleinik <phe.h.o1 at gmail.com>
Date: Tue Oct 29 10:20:48 2019 -0300
Optimise reverse-logic conditionals
Applied the same logic as in `\if... <true>\else<false>\fi` conditionals for tests like `\if... <false>\else<true>\fi`.
>---------------------------------------------------------------
a8d219fed749e1938aa0b7b80e5c54a465e4fa7e
l3kernel/l3basics.dtx | 88 +++++++++++++++++++++++++++++++++++++++------------
1 file changed, 68 insertions(+), 20 deletions(-)
diff --git a/l3kernel/l3basics.dtx b/l3kernel/l3basics.dtx
index 373850f66..ffaf0825b 100644
--- a/l3kernel/l3basics.dtx
+++ b/l3kernel/l3basics.dtx
@@ -1950,6 +1950,10 @@
% \@@_generate_conditional:NNnnnnNw,
% \@@_generate_conditional_test:w,
% \@@_generate_conditional_fast:nw,
+% \@@_generate_conditional_test_aux:nw,
+% \@@_generate_conditional_test_auxi:w,
+% \@@_generate_conditional_test_auxii:w,
+% \@@_generate_conditional_fast_reverse:nw,
% }
% The workhorse here is going through a list of desired forms, \emph{i.e.},
% |p|, |TF|, |T| and |F|. The first three arguments come from splitting up
@@ -1963,11 +1967,18 @@
% The use of \cs{tl_to_str:n} makes the later loop more robust.
%
% A large number of our low-level conditionals look like \meta{code}
-% \cs{prg_return_true:} \cs{else:} \cs{prg_return_false:} \cs{fi:} so
-% we optimize this special case by calling
-% \cs{@@_generate_conditional_fast:nw} \Arg{code}. This passes
-% \cs{use_i:nn} instead of \cs{use_i_ii:nnn} to functions such as
-% \cs{@@_generate_p_form:wNNnnnnN}.
+% \cs{prg_return_true:} \cs{else:} \cs{prg_return_false:} \cs{fi:}, and
+% a few reversed logic conditionals, which look like \meta{code}
+% \cs{prg_return_false:} \cs{else:} \cs{prg_return_true:} \cs{fi:}.
+% We optimize these special cases by calling
+% \cs{@@_generate_conditional_fast:nw} \Arg{code} or,
+% \cs{@@_generate_conditional_fast_reverse:nw} \Arg{code}, respectively,
+% which pass \cs{@@_generate_conditional_fast_TF_form:nnnn} or
+% \cs{@@_generate_conditional_fast_FT_form:nnnn} to functions such as
+% \cs{@@_generate_p_form:wNNnnnnN}. If the code doesn't match the
+% patterns above, then the
+% \cs[no-index]{@@_generate_(p|TF|T|F)_form:wNNnnnnN} receives
+% \cs{@@_generate_conditional_slow_form:nnnn} instead.
% \begin{macrocode}
\cs_set_protected:Npn \@@_generate_conditional:nnNNNnnn #1#2#3#4#5#6#7#8
{
@@ -1984,8 +1995,8 @@
#8 \q_mark
\@@_generate_conditional_fast:nw
\prg_return_true: \else: \prg_return_false: \fi: \q_mark
- \use_none:n
- \exp_not:n { {#8} \use_i_ii:nnn }
+ \@@_generate_conditional_test_aux:nw
+ \exp_not:n { {#8} \@@_generate_conditional_slow_form:nnnn }
\tl_to_str:n {#7}
\exp_not:n { , \q_recursion_tail , \q_recursion_stop }
}
@@ -1994,7 +2005,23 @@
#1 \prg_return_true: \else: \prg_return_false: \fi: \q_mark #2
{ #2 {#1} }
\cs_set:Npn \@@_generate_conditional_fast:nw #1#2 \exp_not:n #3
- { \exp_not:n { {#1} \use_i:nn } }
+ { \exp_not:n { {#1} \@@_generate_conditional_fast_TF_form:nnnn } }
+\cs_set:Npn \@@_generate_conditional_test_aux:nw #1
+ { \@@_generate_conditional_test_auxi:w #1 }
+\cs_set:Npn \@@_generate_conditional_test_auxi:w #1
+ \q_mark \@@_generate_conditional_fast:nw
+ {
+ \@@_generate_conditional_test_auxii:w
+ #1 \q_mark
+ \@@_generate_conditional_fast_reverse:nw
+ \prg_return_false: \else: \prg_return_true: \fi: \q_mark
+ \use_none:n
+ }
+\cs_set:Npn \@@_generate_conditional_test_auxii:w
+ #1 \prg_return_false: \else: \prg_return_true: \fi: \q_mark #2
+ { #2 {#1} }
+\cs_set:Npn \@@_generate_conditional_fast_reverse:nw #1#2 \exp_not:n #3
+ { \exp_not:n { {#1} \@@_generate_conditional_fast_FT_form:nnnn } }
% \end{macrocode}
% Looping through the list of desired forms. First are six arguments
% and seventh is the form. Use the form to call the
@@ -2029,15 +2056,23 @@
% \@@_generate_p_form:wNNnnnnN,
% \@@_generate_TF_form:wNNnnnnN,
% \@@_generate_T_form:wNNnnnnN,
-% \@@_generate_F_form:wNNnnnnN
+% \@@_generate_F_form:wNNnnnnN,
+% }
+% \begin{macro}[EXP]{\@@_p_true:w,\@@_p_false:w}
+% \begin{macro}[EXP]
+% {
+% \@@_generate_conditional_slow_form:nnnn,
+% \@@_generate_conditional_fast_TF_form:nnnn,
+% \@@_generate_conditional_fast_FT_form:nnnn,
+% \@@_generate_generic_define:nn,
% }
-% \begin{macro}[EXP]{\@@_p_true:w}
% How to generate the various forms. Those functions take the
% following arguments: 1: junk, 2: \cs{cs_set:Npn} or similar, 3: |p|
% (for protected conditionals) or |e|, 4: function name, 5: signature,
% 6: parameter text, 7: replacement (possibly trimmed by
-% \cs{@@_generate_conditional_fast:nw}), 8: \cs{use_i_ii:nnn} or
-% \cs{use_i:nn} (for \enquote{fast} conditionals). Remember that the
+% \cs{@@_generate_conditional_fast:nw}), 8:
+% \cs[no-index]{\@@_generate_conditional_(slow|fast_(TF|FT))_form:nnnn}.
+% Remember that the
% logic-returning functions expect two arguments to be present after
% \cs{exp_end:}: notice the construction of the different variants
% relies on this, and that the |TF| and |F| variants will be slightly
@@ -2061,9 +2096,10 @@
\fi:
{
#8
- { \exp_args:Nc #2 { #4 _p: #5 } #6 }
{ { #7 \exp_end: \c_true_bool \c_false_bool } }
- { #7 \@@_p_true:w \fi: \c_false_bool }
+ { { #7 \@@_p_true:w \fi: \c_false_bool } }
+ { { #7 \@@_p_false:w \fi: \c_true_bool } }
+ { \exp_args:Nc #2 { #4 _p: #5 } #6 }
}
{
\__kernel_msg_error:nnx { kernel } { protected-predicate }
@@ -2074,30 +2110,42 @@
#1 \q_stop #2#3#4#5#6#7#8
{
#8
- { \exp_args:Nc #2 { #4 : #5 T } #6 }
{ { #7 \exp_end: \use:n \use_none:n } }
- { #7 \exp_after:wN \use_ii:nn \fi: \use_none:n }
+ { { #7 \exp_after:wN \use_ii:nn \fi: \use_none:n } }
+ { { #7 \exp_after:wN \use_none:nn \fi: \use:n } }
+ { \exp_args:Nc #2 { #4 : #5 T } #6 }
}
\cs_set_protected:Npn \@@_generate_F_form:wNNnnnnN
#1 \q_stop #2#3#4#5#6#7#8
{
#8
- { \exp_args:Nc #2 { #4 : #5 F } #6 }
{ { #7 \exp_end: { } } }
- { #7 \exp_after:wN \use_none:nn \fi: \use:n }
+ { { #7 \exp_after:wN \use_none:nn \fi: \use:n } }
+ { { #7 \exp_after:wN \use_ii:nn \fi: \use_none:n } }
+ { \exp_args:Nc #2 { #4 : #5 F } #6 }
}
\cs_set_protected:Npn \@@_generate_TF_form:wNNnnnnN
#1 \q_stop #2#3#4#5#6#7#8
{
#8
- { \exp_args:Nc #2 { #4 : #5 TF } #6 }
{ { #7 \exp_end: } }
- { #7 \exp_after:wN \use_ii:nnn \fi: \use_ii:nn }
+ { { #7 \exp_after:wN \use_ii:nnn \fi: \use_ii:nn } }
+ { { #7 \exp_after:wN \use_iii:nnn \fi: \use_i:nn } }
+ { \exp_args:Nc #2 { #4 : #5 TF } #6 }
}
\cs_set:Npn \@@_p_true:w \fi: \c_false_bool { \fi: \c_true_bool }
+\cs_set:Npn \@@_p_false:w \fi: \c_true_bool { \fi: \c_false_bool }
+\cs_set:Npn \@@_generate_conditional_slow_form:nnnn
+ { \exp_after:wN \@@_generate_generic_define:nn \use_i:nnn }
+\cs_set:Npn \@@_generate_conditional_fast_TF_form:nnnn
+ { \exp_after:wN \@@_generate_generic_define:nn \use_ii:nnn }
+\cs_set:Npn \@@_generate_conditional_fast_FT_form:nnnn
+ { \exp_after:wN \@@_generate_generic_define:nn \use_iii:nnn }
+\cs_set:Npn \@@_generate_generic_define:nn #1#2 { #2{#1} }
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\prg_set_eq_conditional:NNn, \prg_new_eq_conditional:NNn}
% \begin{macro}{\@@_set_eq_conditional:NNNn}
More information about the latex3-commits
mailing list