diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx | 179 |
1 files changed, 176 insertions, 3 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index 6c65d33db05..d9a3202c949 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx @@ -38,7 +38,7 @@ \documentclass[full]{l3doc} %</driver> %<*driver|package> -\GetIdInfo$Id: l3candidates.dtx 6039 2015-09-23 12:41:26Z joseph $ +\GetIdInfo$Id: l3candidates.dtx 6208 2015-10-09 20:01:54Z joseph $ {L3 Experimental additions to l3kernel} %</driver|package> %<*driver> @@ -576,6 +576,98 @@ % % \section{Additions to \pkg{l3prg}} % +% Minimal (lazy) evaluation can be obtained using the functions +% \cs{bool_all_p:n}, \cs{bool_and_p:nn}, \cs{bool_any_p:n}, or +% \cs{bool_or_p:nn}, which only evaluate their boolean expression +% arguments when they are needed to determine the resulting truth +% value. For example, when evaluating the boolean expression +% \begin{verbatim} +% \bool_and_p:nn +% { +% \bool_any_p:n +% { +% { \int_compare_p:n { 2 = 3 } } +% { \int_compare_p:n { 4 <= 4 } } +% { \int_compare_p:n { 1 = \error } } % is skipped +% } +% } +% { ! \int_compare_p:n { 2 = 4 } } +% \end{verbatim} +% the line marked with |is skipped| is not expanded because the result +% of \cs{bool_any_p:n} is known once the second boolean expression is +% found to be logically \texttt{true}. On the other hand, the last +% line is expanded because its logical value is needed to determine the +% result of \cs{bool_and_p:nn}. +% +% \begin{function}[EXP, added = 2015-09-28]{\bool_all_p:n} +% \begin{syntax} +% \cs{bool_all_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \} +% \end{syntax} +% Implements the \enquote{And} operation on the \meta{boolean +% expressions}, hence is \texttt{true} if all of them are +% \texttt{true} and \texttt{false} if any of them is \texttt{false}. +% Contrarily to the infix operator |&&|, only the \meta{boolean +% expressions} which are needed to determine the result of +% \cs{bool_all_p:n} will be evaluated. See also \cs{bool_and_p:nn} +% when there are only two \meta{boolean expressions}. +% \end{function} +% +% \begin{function}[EXP, added = 2015-09-28]{\bool_and_p:nn} +% \begin{syntax} +% \cs{bool_and_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2} +% \end{syntax} +% Implements the \enquote{And} operation between two boolean +% expressions, hence is \texttt{true} if both are \texttt{true}. +% Contrarily to the infix operator |&&|, the \meta{boolexpr_2} will +% only be evaluated if it is needed to determine the result of +% \cs{bool_and_p:nn}. See also \cs{bool_all_p:n} when there are more +% than two \meta{boolean expressions}. +% \end{function} +% +% \begin{function}[EXP, added = 2015-09-28]{\bool_any_p:n} +% \begin{syntax} +% \cs{bool_any_p:n} \{ \Arg{boolexpr_1} \Arg{boolexpr_2} $\cdots$ \Arg{boolexpr_N} \} +% \end{syntax} +% Implements the \enquote{Or} operation on the \meta{boolean +% expressions}, hence is \texttt{true} if any of them is +% \texttt{true} and \texttt{false} if all of them are \texttt{false}. +% Contrarily to the infix operator \verb"||", only the \meta{boolean +% expressions} which are needed to determine the result of +% \cs{bool_any_p:n} will be evaluated. See also \cs{bool_or_p:nn} +% when there are only two \meta{boolean expressions}. +% \end{function} +% +% \begin{function}[EXP, updated = 2012-07-08]{\bool_not_p:n} +% \begin{syntax} +% \cs{bool_not_p:n} \Arg{boolean expression} +% \end{syntax} +% Function version of |!(|\meta{boolean expression}|)| within a boolean +% expression. +% \end{function} +% +% \begin{function}[EXP, added = 2015-09-28]{\bool_or_p:nn} +% \begin{syntax} +% \cs{bool_or_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2} +% \end{syntax} +% Implements the \enquote{Or} operation between two boolean +% expressions, hence is \texttt{true} if either one is \texttt{true}. +% Contrarily to the infix operator \verb"||", the \meta{boolexpr_2} +% will only be evaluated if it is needed to determine the result of +% \cs{bool_or_p:nn}. See also \cs{bool_any_p:n} when there are more +% than two \meta{boolean expressions}. +% \end{function} +% +% \begin{function}[EXP, updated = 2012-07-08]{\bool_xor_p:nn} +% \begin{syntax} +% \cs{bool_xor_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_2} +% \end{syntax} +% Implements an \enquote{exclusive or} operation between two boolean +% expressions. There is no infix operation for this logical +% operator. +% \end{function} +% + +% % \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\bool_log:N, \bool_log:c} % \begin{syntax} % \cs{bool_log:N} \meta{boolean} @@ -1057,7 +1149,7 @@ % \end{itemize} % and other values will raise an error. % -% The \meta{catcode} may be any one valid for the engine in use. Note +% The \meta{charcode} may be any one valid for the engine in use. Note % however that for \XeTeX{} releases prior to 0.99992 only the 8-bit % range ($0$ to $255$) is accepted due to engine limitations. % \end{function} @@ -2484,6 +2576,86 @@ %<@@=bool> % \end{macrocode} % +% \begin{macro}{\bool_all_p:n} +% \begin{macro}[aux]{\@@_all_aux:n} +% Go through the list of expressions, stopping whenever an expression +% is \texttt{false}. If the end is reached without finding any +% \texttt{false} expression, then the result is \texttt{true}. +% \begin{macrocode} +\cs_new:Npn \bool_all_p:n #1 + { \@@_all_aux:n #1 \q_recursion_tail \q_recursion_stop } +\cs_new:Npn \@@_all_aux:n #1 + { + \quark_if_recursion_tail_stop_do:nn {#1} { \c_true_bool } + \bool_if:nF {#1} + { \use_i_delimit_by_q_recursion_stop:nw { \c_false_bool } } + \@@_all_aux:n + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bool_and_p:nn} +% Only evaluate the second expression if the first is \texttt{true}. +% \begin{macrocode} +\cs_new:Npn \bool_and_p:nn #1#2 + { \bool_if:nTF {#1} { \bool_if_p:n {#2} } { \c_false_bool } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bool_any_p:n} +% \begin{macro}[aux]{\@@_any_aux:n} +% Go through the list of expressions, stopping whenever an expression +% is \texttt{true}. If the end is reached without finding any +% \texttt{true} expression, then the result is \texttt{false}. +% \begin{macrocode} +\cs_new:Npn \bool_any_p:n #1 + { \@@_any_aux:n #1 \q_recursion_tail \q_recursion_stop } +\cs_new:Npn \@@_any_aux:n #1 + { + \quark_if_recursion_tail_stop_do:nn {#1} { \c_false_bool } + \bool_if:nT {#1} + { \use_i_delimit_by_q_recursion_stop:nw { \c_true_bool } } + \@@_any_aux:n + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\bool_not_p:n} +% \UnitTested +% The Not variant just reverses the outcome of \cs{bool_if_p:n}. Can +% be optimized but this is nice and simple and according to the +% implementation plan. Not even particularly useful to have it when +% the infix notation is easier to use. +% \begin{macrocode} +\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bool_or_p:nn} +% Only evaluate the second expression if the first is \texttt{false}. +% \begin{macrocode} +\cs_new:Npn \bool_or_p:nn #1#2 + { \bool_if:nTF {#1} { \c_true_bool } { \bool_if_p:n {#2} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\bool_xor_p:nn} +% \UnitTested +% Exclusive or. If the boolean expressions have same truth value, +% return false, otherwise return true. +% \begin{macrocode} +\cs_new:Npn \bool_xor_p:nn #1#2 + { + \int_compare:nNnTF { \bool_if_p:n {#1} } = { \bool_if_p:n {#2} } + \c_false_bool + \c_true_bool + } +% \end{macrocode} +% \end{macro} +% +% % \begin{macro}{\bool_log:N, \bool_log:c, \bool_log:n} % Redirect output of \cs{bool_show:N} to the log. % \begin{macrocode} @@ -4418,7 +4590,8 @@ \char_set_lccode:nn { 32 } {#1} \exp_args:Nx \tex_lowercase:D { - \tl_const:cn { c_@@_ \__int_to_roman:w #1 _tl } + \tl_const:Nn + \exp_not:c { c_@@_ \__int_to_roman:w #1 _tl } { \exp_not:o \l_@@_tmp_tl } } } |