[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