[latex3-commits] [l3svn] r7375 - Breaking change: finally make boolean expressions eager (fixes #217)

noreply at latex-project.org noreply at latex-project.org
Sun Jul 16 00:09:40 CEST 2017


Author: bruno
Date: 2017-07-16 00:09:40 +0200 (Sun, 16 Jul 2017)
New Revision: 7375

Modified:
   trunk/l3kernel/l3prg.dtx
   trunk/l3kernel/testfiles/m3expl001.luatex.tlg
   trunk/l3kernel/testfiles/m3expl001.ptex.tlg
   trunk/l3kernel/testfiles/m3expl001.tlg
   trunk/l3kernel/testfiles/m3expl001.uptex.tlg
   trunk/l3kernel/testfiles/m3expl001.xetex.tlg
   trunk/l3kernel/testfiles/m3expl003.luatex.tlg
   trunk/l3kernel/testfiles/m3expl003.ptex.tlg
   trunk/l3kernel/testfiles/m3expl003.tlg
   trunk/l3kernel/testfiles/m3expl003.uptex.tlg
   trunk/l3kernel/testfiles/m3expl003.xetex.tlg
   trunk/l3kernel/testfiles/m3prg003.lvt
   trunk/l3kernel/testfiles/m3prg003.tlg
   trunk/l3kernel/testfiles/m3seq004.lvt
Log:
Breaking change: finally make boolean expressions eager (fixes #217)

We still had a few test files relying on lazyness so I fixed them.
The contrib tests fail but just need fontspec to take in a three-line
pull request.


Modified: trunk/l3kernel/l3prg.dtx
===================================================================
--- trunk/l3kernel/l3prg.dtx	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/l3prg.dtx	2017-07-15 22:09:40 UTC (rev 7375)
@@ -270,7 +270,7 @@
 %   Sets \meta{boolean_1} to the current value of \meta{boolean_2}.
 % \end{function}
 %
-% \begin{function}[updated = 2012-07-08]
+% \begin{function}[updated = 2017-07-15]
 %   {\bool_set:Nn, \bool_set:cn, \bool_gset:Nn, \bool_gset:cn}
 %   \begin{syntax}
 %     \cs{bool_set:Nn} \meta{boolean} \Arg{boolexpr}
@@ -296,7 +296,7 @@
 %   Displays the logical truth of the \meta{boolean} on the terminal.
 % \end{function}
 %
-% \begin{function}[added = 2012-02-09, updated = 2015-08-07]{\bool_show:n}
+% \begin{function}[added = 2012-02-09, updated = 2017-07-15]{\bool_show:n}
 %   \begin{syntax}
 %     \cs{bool_show:n} \Arg{boolean expression}
 %   \end{syntax}
@@ -311,7 +311,7 @@
 %   Writes the logical truth of the \meta{boolean} in the log file.
 % \end{function}
 %
-% \begin{function}[added = 2014-08-22, updated = 2015-08-07]{\bool_log:n}
+% \begin{function}[added = 2014-08-22, updated = 2017-07-15]{\bool_log:n}
 %   \begin{syntax}
 %     \cs{bool_log:n} \Arg{boolean expression}
 %   \end{syntax}
@@ -354,8 +354,7 @@
 % \meta{true} or \meta{false}. It supports the logical operations And,
 % Or and Not as the well-known infix operators |&&| and \verb"||" and prefix~|!|
 % with their usual precedences (namely, |&&| binds more tightly than
-% \verb"||"). In
-% addition to this, parentheses can be used to isolate
+% \verb"||"). In addition to this, parentheses can be used to isolate
 % sub-expressions. For example,
 % \begin{verbatim}
 %     \int_compare_p:n { 1 = 1 } &&
@@ -368,18 +367,22 @@
 % \end{verbatim}
 % is a valid boolean expression.
 %
-% At present, the infix operators |&&| and \verb"||" perform lazy
-% evaluation, but this will change in the near future.
 % Contrarily to some other programming languages, the operators |&&| and
-% \verb"||" will evaluate both operands in all cases, even when the first
+% \verb"||" evaluate both operands in all cases, even when the first
 % operand is enough to determine the result.  This \enquote{eager}
 % evaluation should be contrasted with the \enquote{lazy} evaluation of
 % \cs[no-index]{bool_lazy_\ldots{}} functions.
 %
 % \begin{texnote}
 %   The eager evaluation of boolean expressions is unfortunately
-%   necessary.  Indeed, a lazy parser can get confused if |&&| and
-%   \verb"||" appear as (unbraced) arguments of some predicates.
+%   necessary in \TeX{}.  Indeed, a lazy parser can get confused if |&&|
+%   or \verb"||" or parentheses appear as (unbraced) arguments of some
+%   predicates.  For instance, the innocuous-looking expression below
+%   would break (in a lazy parser) if |#1| were a closing parenthesis
+%   and \cs[no-index]{l_tmpa_bool} were \texttt{true}.
+%   \begin{verbatim}
+%     ( \l_tmpa_bool || \token_if_eq_meaning_p:NN X #1 )
+%   \end{verbatim}
 % \end{texnote}
 %
 % Minimal (lazy) evaluation can be obtained using the conditionals
@@ -405,7 +408,7 @@
 % line is expanded because its logical value is needed to determine the
 % result of \cs{bool_lazy_and_p:nn}.
 %
-% \begin{function}[EXP, pTF, updated = 2012-07-08]{\bool_if:n}
+% \begin{function}[EXP, pTF, updated = 2017-07-15]{\bool_if:n}
 %   \begin{syntax}
 %     \cs{bool_if_p:n} \Arg{boolean expression}
 %     \cs{bool_if:nTF} \Arg{boolean expression} \Arg{true code} \Arg{false code}
@@ -418,8 +421,8 @@
 %   |!| (\enquote{Not}) and parentheses.  The logical Not applies to
 %   the next predicate or group.
 % \end{function}
-%   
-% \begin{function}[EXP, pTF, added = 2015-11-15]{\bool_lazy_all:n}
+%
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_all:n}
 %   \begin{syntax}
 %     \cs{bool_lazy_all_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \}
 %     \cs{bool_lazy_all:nTF} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \} \Arg{true code} \Arg{false code}
@@ -433,7 +436,7 @@
 %   when there are only two \meta{boolean expressions}.
 % \end{function}
 %
-% \begin{function}[EXP, pTF, added = 2015-11-15]{\bool_lazy_and:nn}
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_and:nn}
 %   \begin{syntax}
 %     \cs{bool_lazy_and_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
 %     \cs{bool_lazy_and:nnTF} \Arg{boolexpr_1} \Arg{boolexpr_2} \Arg{true code} \Arg{false code}
@@ -446,7 +449,7 @@
 %   than two \meta{boolean expressions}.
 % \end{function}
 %
-% \begin{function}[EXP, pTF, added = 2015-11-15]{\bool_lazy_any:n}
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_any:n}
 %   \begin{syntax}
 %     \cs{bool_lazy_any_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \}
 %     \cs{bool_lazy_any:nTF} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \} \Arg{true code} \Arg{false code}
@@ -460,7 +463,7 @@
 %   when there are only two \meta{boolean expressions}.
 % \end{function}
 %
-% \begin{function}[EXP, pTF, added = 2015-11-15]{\bool_lazy_or:nn}
+% \begin{function}[EXP, pTF, added = 2015-11-15, updated = 2017-07-15]{\bool_lazy_or:nn}
 %   \begin{syntax}
 %     \cs{bool_lazy_or_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
 %     \cs{bool_lazy_or:nnTF} \Arg{boolexpr_1} \Arg{boolexpr_2} \Arg{true code} \Arg{false code}
@@ -473,7 +476,7 @@
 %   than two \meta{boolean expressions}.
 % \end{function}
 %
-% \begin{function}[EXP, updated = 2012-07-08]{\bool_not_p:n}
+% \begin{function}[EXP, updated = 2017-07-15]{\bool_not_p:n}
 %   \begin{syntax}
 %      \cs{bool_not_p:n} \Arg{boolean expression}
 %   \end{syntax}
@@ -481,7 +484,7 @@
 %   expression.
 % \end{function}
 %
-% \begin{function}[EXP, updated = 2012-07-08]{\bool_xor_p:nn}
+% \begin{function}[EXP, updated = 2017-07-15]{\bool_xor_p:nn}
 %   \begin{syntax}
 %     \cs{bool_xor_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2}
 %   \end{syntax}
@@ -538,7 +541,7 @@
 %   until the \meta{boolean} is \texttt{false}.
 % \end{function}
 %
-% \begin{function}[rEXP, updated = 2012-07-08]{\bool_do_until:nn}
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_do_until:nn}
 %   \begin{syntax}
 %     \cs{bool_do_until:nn} \Arg{boolean expression} \Arg{code}
 %   \end{syntax}
@@ -550,7 +553,7 @@
 %   \texttt{true}.
 % \end{function}
 %
-% \begin{function}[rEXP, updated = 2012-07-08]{\bool_do_while:nn}
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_do_while:nn}
 %   \begin{syntax}
 %     \cs{bool_do_while:nn} \Arg{boolean expression} \Arg{code}
 %   \end{syntax}
@@ -562,7 +565,7 @@
 %   \texttt{false}.
 % \end{function}
 %
-% \begin{function}[rEXP, updated = 2012-07-08]{\bool_until_do:nn}
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_until_do:nn}
 %   \begin{syntax}
 %     \cs{bool_until_do:nn} \Arg{boolean expression} \Arg{code}
 %   \end{syntax}
@@ -574,7 +577,7 @@
 %   then loops until the \meta{boolean expression} is \texttt{true}.
 % \end{function}
 %
-% \begin{function}[rEXP, updated = 2012-07-08]{\bool_while_do:nn}
+% \begin{function}[rEXP, updated = 2017-07-15]{\bool_while_do:nn}
 %   \begin{syntax}
 %     \cs{bool_while_do:nn} \Arg{boolean expression} \Arg{code}
 %   \end{syntax}
@@ -871,7 +874,7 @@
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \bool_if:N #1 { p , T , F , TF }
   {
-    \if_meaning:w \c_true_bool #1
+    \if_bool:N #1
       \prg_return_true:
     \else:
       \prg_return_false:
@@ -942,7 +945,8 @@
 %   input syntax somewhat similar to the one found in other programming
 %   languages with |(| and |)| for grouping, |!| for logical
 %   \enquote{Not}, |&&| for logical \enquote{And} and \verb"||" for
-%   logical \enquote{Or}.  We shall use the terms Not, And, Or, Open and
+%   logical \enquote{Or}.  However, they perform eager evaluation.
+%   We shall use the terms Not, And, Or, Open and
 %   Close for these operations.
 %
 %   Any expression is terminated by a Close operation. Evaluation
@@ -951,9 +955,8 @@
 %   \begin{itemize}
 %     \item If an Open is seen, start evaluating a new expression using
 %       the Eval function and call GetNext again.
-%     \item If a Not is seen, remove the |!| and call a GetNotNext
-%       function, which eventually reverses the logic compared to
-%       GetNext.
+%     \item If a Not is seen, remove the |!| and call a GetNext
+%       function with the logic reversed.
 %     \item If none of the above, reinsert the token found (this is
 %       supposed to be a predicate function) in front of an Eval
 %       function, which evaluates it to the boolean value \meta{true} or
@@ -968,11 +971,11 @@
 %       seen, continue with GetNext to examine truth value of next
 %       boolean (sub-)expression.
 %     \item[\meta{false}And] Current truth value is false, logical And
-%       seen, stop evaluating the predicates within this sub-expression
-%       and break to the nearest Close. Then return \meta{false}.
-%     \item[\meta{true}Or] Current truth value is true, logical Or
-%       seen, stop evaluating the predicates within this sub-expression
-%       and break to the nearest Close. Then return \meta{true}.
+%       seen, stop using the values of predicates within this
+%       sub-expression until the next Close. Then return \meta{false}.
+%     \item[\meta{true}Or] Current truth value is true, logical Or seen,
+%       stop using the values of predicates within this sub-expression
+%       until the nearest Close. Then return \meta{true}.
 %     \item[\meta{false}Or] Current truth value is false, logical Or
 %       seen, continue with GetNext to examine truth value of next
 %       boolean (sub-)expression.
@@ -981,15 +984,6 @@
 %     \item[\meta{false}Close] Current truth value is false, Close
 %       seen, return \meta{false}.
 %   \end{description}
-%   We introduce an additional Stop operation with the same
-%   semantics as the Close operation.
-%   \begin{description}
-%     \item[\meta{true}Stop] Current truth value is true, return
-%       \meta{true}.
-%     \item[\meta{false}Stop] Current truth value is false, return
-%       \meta{false}.
-%   \end{description}
-%   The reasons for this follow below.
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \bool_if:n #1 { T , F , TF }
   {
@@ -1003,82 +997,40 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\bool_if_p:n}
-% \begin{macro}[EXP, aux]
-%   {
-%     \@@_if_left_parentheses:wwwn ,
-%     \@@_if_right_parentheses:wwwn ,
-%     \@@_if_or:wwwn
-%   }
-%   First issue a \cs{group_align_safe_begin:} as we are using |&&|
-%   as syntax shorthand for the And operation and we need to hide it for
-%   \TeX{}.  This is closed at the end of the expression parsing
-%   (see |S| below).
-%
-%   Minimal (\enquote{short-circuit}) evaluation of boolean expressions
-%   requires skipping to the end of the current parenthesized group when
-%   \meta{true}\verb"||" is seen, but to the next \verb"||" or closing
-%   parenthesis when \meta{false}|&&| is seen.  To avoid having separate
-%   functions for the two cases, we transform the boolean expression by
-%   doubling each parenthesis and adding parenthesis around each
-%   \verb"||".  This ensures that |&&| binds tighter than \verb"||".
-%
-%   The replacement is done in three passes, for left and right
-%   parentheses and for \verb"||".  At each pass, the part of the
-%   expression that has been transformed is stored before \cs{q_nil},
-%   the rest lies until the first \cs{q_mark}, followed by an empty
-%   brace group.  A trailing marker ensures that the auxiliaries'
-%   delimited arguments do not run-away.  As long as the delimiter
-%   matches inside the expression, material is moved before \cs{q_nil}
-%   and we continue.  Afterwards, the trailing marker is taken as a
-%   delimiter, |#4| is the next auxiliary, immediately followed by a new
-%   \cs{q_nil} delimiter, which indicates that nothing has been treated
-%   at this pass.  The last step calls \cs{@@_if_parse:NNNww} which
-%   cleans up and triggers the evaluation of the expression itself.
+%   First issue a \cs{group_align_safe_begin:} as we are using |&&| as
+%   syntax shorthand for the And operation and we need to hide it for
+%   \TeX{}.  This group is closed after \cs{@@_get_next:NN} returns
+%   \cs{c_true_bool} or \cs{c_false_bool}.  That function requires the
+%   trailing parenthesis to know where the expression ends.
 %    \begin{macrocode}
 \cs_new:Npn \bool_if_p:n #1
   {
     \group_align_safe_begin:
-    \@@_if_left_parentheses:wwwn \q_nil
-      #1 \q_mark { }
-      (  \q_mark { \@@_if_right_parentheses:wwwn \q_nil }
-      )  \q_mark { \@@_if_or:wwwn \q_nil }
-      || \q_mark \@@_if_parse:NNNww
-    \q_stop
+    \exp_after:wN
+    \group_align_safe_end:
+    \exp:w \exp_end_continue_f:w % (
+    \@@_get_next:NN \use_i:nnnn #1 )
   }
-\cs_new:Npn \@@_if_left_parentheses:wwwn #1 \q_nil #2 ( #3 \q_mark #4
-  { #4 \@@_if_left_parentheses:wwwn #1 #2 (( \q_nil #3 \q_mark {#4} }
-\cs_new:Npn \@@_if_right_parentheses:wwwn #1 \q_nil #2 ) #3 \q_mark #4
-  { #4 \@@_if_right_parentheses:wwwn #1 #2 )) \q_nil #3 \q_mark {#4} }
-\cs_new:Npn \@@_if_or:wwwn #1 \q_nil #2 || #3 \q_mark #4
-  { #4 \@@_if_or:wwwn #1 #2 )||( \q_nil #3 \q_mark {#4} }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
-% \begin{macro}[EXP, aux]{\@@_if_parse:NNNww}
-%   After removing extra tokens from the transformation phase, start
-%   evaluating.  At the end, we need to finish the special
-%   \texttt{align_safe} group before finally
-%   returning a \cs{c_true_bool} or \cs{c_false_bool} as there might
-%   otherwise be something left in front in the input stream. For this
-%   we call the Stop operation, denoted simply by a |S| following the
-%   last Close operation.
-%    \begin{macrocode}
-\cs_new:Npn \@@_if_parse:NNNww #1#2#3#4 \q_mark #5 \q_stop
-  {
-    \__bool_get_next:NN \use_i:nn (( #4 )) S
-  }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}[aux]{\@@_get_next:NN}
-%   The GetNext operation.  This is a switch: if what follows is neither
-%   |!| nor |(|, we assume it is a predicate.  The first argument is
-%   \cs{use_ii:nn} if the logic must eventually be reversed (after a
-%   |!|), otherwise it is \cs{use_i:nn}.  This function eventually
-%   expand to the truth value \cs{c_true_bool} or \cs{c_false_bool} of
-%   the expression which follows until the next unmatched closing
-%   parenthesis.
+%   The GetNext operation.  Its first argument is \cs{use_i:nnnn},
+%   \cs{use_ii:nnnn}, \cs{use_iii:nnnn}, or \cs{use_iv:nnnn} (we call
+%   these \enquote{states}).  In the first state, this function
+%   eventually expand to the truth value \cs{c_true_bool} or
+%   \cs{c_false_bool} of the expression which follows until the next
+%   unmatched closing parenthesis.  For instance
+%   \enquote{\cs{@@_get_next:NN} \cs{use_i:nnnn} \cs{c_true_bool}
+%   \texttt{\&\&} \cs{c_true_bool} \texttt{)}} (including the closing
+%   parenthesis) expands to \cs{c_true_bool}.  In the second state
+%   (after a |!|) the logic is reversed.  We call these two states
+%   \enquote{normal} and the next two \enquote{skipping}.  In the third
+%   state (after \cs{c_true_bool}\verb"||") it always returns
+%   \cs{c_true_bool}.  In the fourth state (after \cs{c_false_bool}|&&|)
+%   it always returns \cs{c_false_bool} and also stops when encountering
+%   \verb"||", not only parentheses.  This code itself is a switch: if
+%   what follows is neither |!| nor |(|, we assume it is a predicate.
 %    \begin{macrocode}
 \cs_new:Npn \@@_get_next:NN #1#2
   {
@@ -1094,23 +1046,31 @@
 % \end{macro}
 %
 % \begin{macro}[aux]{\@@_!:Nw}
-%   The Not operation reverses the logic: discard the |!| token and call
-%   the GetNext operation with its first argument reversed.
+%   The Not operation reverses the logic: it discards the |!|~token and
+%   calls the GetNext operation with the appropriate first argument.
+%   Namely the first and second states are interchanged, but after
+%   \cs{c_true_bool}\verb"||" or \cs{c_false_bool}|&&| the |!|~is
+%   ignored.
 %    \begin{macrocode}
 \cs_new:cpn { @@_!:Nw } #1#2
-  { \exp_after:wN \@@_get_next:NN #1 \use_ii:nn \use_i:nn }
+  {
+    \exp_after:wN \@@_get_next:NN
+    #1 \use_ii:nnnn \use_i:nnnn \use_iii:nnnn \use_iv:nnnn
+  }
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}[aux]{\@@_(:Nw}
-%   The Open operation starts a sub-expression after discarding the
-%   token.  This is done by calling GetNext, with a post-processing step
-%   which looks for And, Or or Close afterwards.
+%   The Open operation starts a sub-expression after discarding the open
+%   parenthesis.  This is done by calling GetNext (which eventually
+%   discards the corresponding closing parenthesis), with a
+%   post-processing step which looks for And, Or or Close after the
+%   group.
 %    \begin{macrocode}
 \cs_new:cpn { @@_(:Nw } #1#2
   {
     \exp_after:wN \@@_choose:NNN \exp_after:wN #1
-    \__int_value:w \@@_get_next:NN \use_i:nn
+    \__int_value:w \@@_get_next:NN \use_i:nnnn
   }
 %    \end{macrocode}
 % \end{macro}
@@ -1118,8 +1078,8 @@
 % \begin{macro}[aux]{\@@_p:Nw}
 %   If what follows GetNext is neither |!| nor |(|, evaluate the
 %   predicate using the primitive \cs{__int_value:w}.  The canonical
-%   true and false values have numerical values $1$ and $0$
-%   respectively.  Look for And, Or or Close afterwards.
+%   \texttt{true} and \texttt{false} values have numerical values $1$
+%   and $0$ respectively.  Look for And, Or or Close afterwards.
 %    \begin{macrocode}
 \cs_new:cpn { @@_p:Nw } #1
   { \exp_after:wN \@@_choose:NNN \exp_after:wN #1 \__int_value:w }
@@ -1127,152 +1087,66 @@
 % \end{macro}
 %
 % \begin{macro}[aux]{\@@_choose:NNN}
-%   Branching the eight-way switch.  The arguments are 1: \cs{use_i:nn}
-%   or \cs{use_ii:nn}, 2: $0$ or $1$ encoding the current truth value,
-%   3: the next operation, And, Or, Close or Stop.  If |#1| is
-%   \cs{use_ii:nn}, the logic of |#2| must be reversed.
+% \begin{macro}[aux]+\@@_)_0:+
+% \begin{macro}[aux]+\@@_)_1:+
+% \begin{macro}[aux]+\@@_)_2:+
+% \begin{macro}[aux]+\@@_&_0:+
+% \begin{macro}[aux]+\@@_&_1:+
+% \begin{macro}[aux]+\@@_&_2:+
+% \begin{macro}[aux]+\@@_|_0:+
+% \begin{macro}[aux]+\@@_|_1:+
+% \begin{macro}[aux]+\@@_|_2:+
+%   The arguments are |#1|: a function such as \cs{use_i:nnnn}, |#2|:
+%   $0$ or $1$ encoding the current truth value, |#3|: the next
+%   operation, And, Or or Close.  We distinguish three cases according
+%   to a combination of |#1| and |#2|.  Case~2 is when |#1| is
+%   \cs{use_iii:nnnn} (state~3), namely after
+%   \cs{c_true_bool}~\verb"||".  Case~1 is when |#1| is \cs{use_i:nnnn}
+%   and |#2| is \texttt{true} or when |#1| is \cs{use_ii:nnnn} and |#2|
+%   is \texttt{false}, for instance for |!|\cs{c_false_bool}.  Case~0
+%   includes the same with \texttt{true}/\texttt{false} interchanged and
+%   the case where |#1| is \cs{use_iv:nnnn} namely after
+%   \cs{c_false_bool}~|&&|.
+%
+%   When seeing~|)| the current subexpression is done, leave the
+%   appropriate boolean.  When seeing~|&| in case~0 go into state~4,
+%   equivalent to having seen \cs{c_false_bool}~|&&|.  In case~1, namely
+%   when the argument is \texttt{true} and we are in a normal state
+%   continue in the normal state~1.  In case~2, namely when skipping
+%   alternatives in an Or, continue in the same state.  When
+%   seeing~\verb"|" in case~0, continue in a normal state; in particular
+%   stop skipping for \cs{c_false_bool}~|&&| because that binds more
+%   tightly than~\verb"||".  In the other two cases start skipping for
+%   \cs{c_true_bool}~\verb"||".
 %    \begin{macrocode}
 \cs_new:Npn \@@_choose:NNN #1#2#3
   {
     \use:c
       {
-        @@_ #3 _
-        #1 #2 { \if_meaning:w 0 #2 1 \else: 0 \fi: }
-        :w
+        @@_ \token_to_str:N #3 _
+        #1 #2 { \if_meaning:w 0 #2 1 \else: 0 \fi: } 2 0 :
       }
   }
+\cs_new:cpn { @@_)_0: } { \c_false_bool }
+\cs_new:cpn { @@_)_1: } { \c_true_bool }
+\cs_new:cpn { @@_)_2: } { \c_true_bool }
+\cs_new:cpn { @@_&_0: } & { \@@_get_next:NN \use_iv:nnnn }
+\cs_new:cpn { @@_&_1: } & { \@@_get_next:NN \use_i:nnnn }
+\cs_new:cpn { @@_&_2: } & { \@@_get_next:NN \use_iii:nnnn }
+\cs_new:cpn { @@_|_0: } | { \@@_get_next:NN \use_i:nnnn }
+\cs_new:cpn { @@_|_1: } | { \@@_get_next:NN \use_iii:nnnn }
+\cs_new:cpn { @@_|_2: } | { \@@_get_next:NN \use_iii:nnnn }
 %    \end{macrocode}
 % \end{macro}
-%
-% \begin{macro}[aux]
-%   {
-%     \@@_)_0:w,
-%     \@@_)_1:w,
-%     \@@_S_0:w,
-%     \@@_S_1:w,
-%   }
-%   Closing a group is just about returning the result. The Stop
-%   operation is similar except it closes the special alignment group
-%   before returning the boolean.
-%    \begin{macrocode}
-\cs_new:cpn { @@_)_0:w } { \c_false_bool }
-\cs_new:cpn { @@_)_1:w } { \c_true_bool }
-\cs_new:cpn { @@_S_0:w } { \group_align_safe_end: \c_false_bool }
-\cs_new:cpn { @@_S_1:w } { \group_align_safe_end: \c_true_bool }
-%    \end{macrocode}
 % \end{macro}
-%
-% \begin{macro}[aux]+\@@_&_1:w+
-% \begin{macro}[aux]+\@@_|_0:w+
-%   Two cases where we simply continue scanning.  We must remove the
-%   second |&| or \verb"|".
-%    \begin{macrocode}
-\cs_new:cpn { @@_&_1:w } & { \@@_get_next:NN \use_i:nn }
-\cs_new:cpn { @@_|_0:w } | { \@@_get_next:NN \use_i:nn }
-%    \end{macrocode}
 % \end{macro}
 % \end{macro}
-%
-% \begin{macro}[aux]+\@@_&_0:w+
-% \begin{macro}[aux]+\@@_|_1:w+
-% \begin{macro}[aux]
-%   {
-%     \@@_eval_skip_to_end_auxi:Nw,
-%     \@@_eval_skip_to_end_auxii:Nw,
-%     \@@_eval_skip_to_end_auxiii:Nw
-%   }
-%   When the truth value has already been decided, we have to throw away
-%   the remainder of the current group as we are doing minimal
-%   evaluation. This is slightly tricky as there are no braces so we
-%   have to play match the |()| manually.
-%    \begin{macrocode}
-\cs_new:cpn { @@_&_0:w } &
-  { \@@_eval_skip_to_end_auxi:Nw \c_false_bool }
-\cs_new:cpn { @@_|_1:w } |
-  { \@@_eval_skip_to_end_auxi:Nw \c_true_bool }
-%    \end{macrocode}
-%   There is always at least one |)| waiting, namely the outer
-%   one. However, we are facing the problem that there may be more than
-%   one that need to be finished off and we have to detect the correct
-%   number of them. Here is a complicated example showing how this is
-%   done. After evaluating the following, we realize we must skip
-%   everything after the first And. Note the extra Close at the end.
-%   \begin{quote}
-%     |\c_false_bool  && ((abc) && xyz) && ((xyz) && (def)))|
-%   \end{quote}
-%   First read up to the first Close. This gives us the list we first
-%   read up until the first right parenthesis so we are looking at the
-%   token list
-%   \begin{quote}
-%     |((abc|
-%   \end{quote}
-%   This contains two Open markers so we must remove two groups. Since
-%   no evaluation of the contents is to be carried out, it doesn't
-%   matter how we remove the groups as long as we wind up with the
-%   correct result. We therefore first remove a |()| pair and what
-%   preceded the Open -- but leave the contents as it may contain Open
-%   tokens itself -- leaving
-%   \begin{quote}
-%     |(abc && xyz) && ((xyz) && (def)))|
-%   \end{quote}
-%   Another round of this gives us
-%   \begin{quote}
-%     |(abc && xyz|
-%   \end{quote}
-%   which still contains an Open so we remove another |()| pair, giving us
-%   \begin{quote}
-%     |abc && xyz && ((xyz) && (def)))|
-%   \end{quote}
-%   Again we read up to a Close and again find Open tokens:
-%   \begin{quote}
-%     |abc && xyz && ((xyz|
-%   \end{quote}
-%   Further reduction gives us
-%   \begin{quote}
-%     |(xyz && (def)))|
-%   \end{quote}
-%   and then
-%   \begin{quote}
-%     |(xyz && (def|
-%   \end{quote}
-%   with reduction to
-%   \begin{quote}
-%     |xyz && (def))|
-%   \end{quote}
-%   and ultimately we arrive at no Open tokens being skipped and we can
-%   finally close the group nicely.
-%    \begin{macrocode}
-%% (
-\cs_new:Npn \@@_eval_skip_to_end_auxi:Nw #1#2 )
-  {
-    \@@_eval_skip_to_end_auxii:Nw #1#2 ( % )
-    \q_no_value \q_stop
-    {#2}
-  }
-%    \end{macrocode}
-%   If no right parenthesis, then |#3| is no_value and we are done, return
-%   the boolean |#1|.  If there is, we need to grab a |()| pair and then
-%   recurse
-%    \begin{macrocode}
-\cs_new:Npn \@@_eval_skip_to_end_auxii:Nw #1#2 ( #3#4 \q_stop #5 % )
-  {
-    \quark_if_no_value:NTF #3
-    {#1}
-    { \@@_eval_skip_to_end_auxiii:Nw #1 #5 }
-  }
-%    \end{macrocode}
-%   Keep the boolean, throw away anything up to the |(| as it is
-%   irrelevant, remove a |()| pair but remember to reinsert |#3| as it may
-%   contain |(| tokens!
-%    \begin{macrocode}
-\cs_new:Npn \@@_eval_skip_to_end_auxiii:Nw #1#2 ( #3 )
-  { % (
-    \@@_eval_skip_to_end_auxi:Nw #1#3 )
-  }
-%    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}[pTF]{\bool_lazy_all:n}
 % \begin{macro}[aux]{\@@_lazy_all:n}

Modified: trunk/l3kernel/testfiles/m3expl001.luatex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl001.luatex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl001.luatex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1804,26 +1804,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl001.ptex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl001.ptex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl001.ptex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1536,26 +1536,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl001.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl001.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl001.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1536,26 +1536,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl001.uptex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl001.uptex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl001.uptex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1536,26 +1536,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl001.xetex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl001.xetex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl001.xetex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1802,26 +1802,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl003.luatex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl003.luatex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl003.luatex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1804,26 +1804,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl003.ptex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl003.ptex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl003.ptex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1536,26 +1536,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl003.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl003.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl003.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1536,26 +1536,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl003.uptex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl003.uptex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl003.uptex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1536,26 +1536,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3expl003.xetex.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3expl003.xetex.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3expl003.xetex.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1802,26 +1802,20 @@
 Defining \bool_if:nF on line ...
 Defining \bool_if:nTF on line ...
 Defining \bool_if_p:n on line ...
-Defining \__bool_if_left_parentheses:wwwn on line ...
-Defining \__bool_if_right_parentheses:wwwn on line ...
-Defining \__bool_if_or:wwwn on line ...
-Defining \__bool_if_parse:NNNww on line ...
 Defining \__bool_get_next:NN on line ...
 Defining \__bool_!:Nw on line ...
 Defining \__bool_(:Nw on line ...
 Defining \__bool_p:Nw on line ...
 Defining \__bool_choose:NNN on line ...
-Defining \__bool_)_0:w on line ...
-Defining \__bool_)_1:w on line ...
-Defining \__bool_S_0:w on line ...
-Defining \__bool_S_1:w on line ...
-Defining \__bool_&_1:w on line ...
-Defining \__bool_|_0:w on line ...
-Defining \__bool_&_0:w on line ...
-Defining \__bool_|_1:w on line ...
-Defining \__bool_eval_skip_to_end_auxi:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxii:Nw on line ...
-Defining \__bool_eval_skip_to_end_auxiii:Nw on line ...
+Defining \__bool_)_0: on line ...
+Defining \__bool_)_1: on line ...
+Defining \__bool_)_2: on line ...
+Defining \__bool_&_0: on line ...
+Defining \__bool_&_1: on line ...
+Defining \__bool_&_2: on line ...
+Defining \__bool_|_0: on line ...
+Defining \__bool_|_1: on line ...
+Defining \__bool_|_2: on line ...
 Defining \bool_lazy_all_p:n on line ...
 Defining \bool_lazy_all:nT on line ...
 Defining \bool_lazy_all:nF on line ...

Modified: trunk/l3kernel/testfiles/m3prg003.lvt
===================================================================
--- trunk/l3kernel/testfiles/m3prg003.lvt	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3prg003.lvt	2017-07-15 22:09:40 UTC (rev 7375)
@@ -70,13 +70,13 @@
 }
 
 
-\TESTEXP{Lazy~evaluation}{
+\TESTEXP{Eager~evaluation}{
   \bool_if_p:n{
     \int_compare_p:nNn 1=1 &&
     \bool_if_p:n {
       \int_compare_p:nNn 2=3 ||
       \int_compare_p:nNn 4=4 ||
-      \int_compare_p:nNn 1=\ERROR % is skipped
+      \int_compare_p:nNn 1={2\expectedError} % is not skipped any longer
     } &&
     \int_compare_p:nNn 2=2
   }
@@ -96,7 +96,7 @@
     \bool_if_p:n {
       \int_compare_p:nNn 2=3 ||
       \int_compare_p:nNn 4=4 ||
-      \int_compare_p:nNn 1=\ERROR % is skipped
+      \int_compare_p:nNn 1={2\expectedError} % is not skipped any longer
     } &&
     \int_compare_p:nNn 2=2
   }

Modified: trunk/l3kernel/testfiles/m3prg003.tlg
===================================================================
--- trunk/l3kernel/testfiles/m3prg003.tlg	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3prg003.tlg	2017-07-15 22:09:40 UTC (rev 7375)
@@ -64,8 +64,16 @@
 \c_false_bool 
 ============================================================
 ============================================================
-TEST 6: Lazy evaluation
+TEST 6: Eager evaluation
 ============================================================
+! Undefined control sequence.
+<argument> 2\expectedError 
+l. ...}
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
 \c_true_bool 
 ============================================================
 ============================================================
@@ -79,6 +87,14 @@
 ============================================================
 TEST 8: bool_set
 ============================================================
+! Undefined control sequence.
+<argument> 2\expectedError 
+l. ...}
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
 TRUE
 ============================================================
 ============================================================

Modified: trunk/l3kernel/testfiles/m3seq004.lvt
===================================================================
--- trunk/l3kernel/testfiles/m3seq004.lvt	2017-07-15 17:45:31 UTC (rev 7374)
+++ trunk/l3kernel/testfiles/m3seq004.lvt	2017-07-15 22:09:40 UTC (rev 7375)
@@ -1,5 +1,5 @@
 %
-% Copyright (C) 2011-2013,2015 The LaTeX Project
+% Copyright (C) 2011-2013,2015,2017 The LaTeX Project
 %
 \documentclass{minimal}
 \input{regression-test}
@@ -65,7 +65,11 @@
 \TEST{seq_set_(filter|map):NNn}{
   \seq_set_from_clist:Nn \l_my_seq { 1,2,34,4,abcd,5 }
   \seq_set_filter:NNn \l_my_seq \l_my_seq
-    { ! ( \tl_if_head_eq_meaning_p:nN {#1} a || \int_compare_p:n { #1 < 2 } ) }
+    {
+      ! \bool_lazy_or_p:nn
+          { \tl_if_head_eq_meaning_p:nN {#1} a }
+          { \int_compare_p:n { #1 < 2 } }
+    }
   \seq_set_map:NNn \l_my_seq \l_my_seq { \int_eval:n { #1 * #1 } }
   \seq_set_map:NNn \l_my_seq \l_my_seq { \exp_not:c {#1} }
   \seq_log:N \l_my_seq



More information about the latex3-commits mailing list