diff options
author | Karl Berry <karl@freefriends.org> | 2018-03-07 21:50:56 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2018-03-07 21:50:56 +0000 |
commit | f11f49763fc33ac8427d8c175d98a8d1275e4c5c (patch) | |
tree | 79aacd4b6ab168db69112977f42c2c99204e1621 /Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx | |
parent | fb72b3560bdc8a98d78bf919da56c3316fa7723d (diff) |
l3 (6mar18)
git-svn-id: svn://tug.org/texlive/trunk@46875 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx | 174 |
1 files changed, 123 insertions, 51 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 678c76cdf7c..77a092f8f00 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx @@ -38,7 +38,7 @@ % {latex-team@latex-project.org}^^A % }^^A % } -% \date{Released 2018/02/21} +% \date{Released 2018/03/05} % % \maketitle % @@ -96,16 +96,20 @@ % \begin{macro}[pTF, EXP]{\fp_compare:n} % \begin{macro}[EXP]{\@@_compare_return:w} % Within floating point expressions, comparison operators are treated -% as operations, so we evaluate |#1|, then compare with $0$. +% as operations, so we evaluate |#1|, then compare with $\pm 0$. +% Tuples are \texttt{true}. % \begin{macrocode} \prg_new_conditional:Npnn \fp_compare:n #1 { p , T , F , TF } { \exp_after:wN \@@_compare_return:w \exp:w \exp_end_continue_f:w \@@_parse:n {#1} } -\cs_new:Npn \@@_compare_return:w \s_@@ \@@_chk:w #1#2; +\cs_new:Npn \@@_compare_return:w #1#2#3; { - \if_meaning:w 0 #1 + \if_charcode:w 0 + \@@_if_type_fp:NTwFw + #1 { \use_i_delimit_by_q_stop:nw #3 \q_stop } + \s_@@ 1 \q_stop \prg_return_false: \else: \prg_return_true: @@ -118,7 +122,7 @@ % \begin{macro}[pTF, EXP]{\fp_compare:nNn} % \begin{macro}[EXP]{\@@_compare_aux:wn} % Evaluate |#1| and |#3|, using an auxiliary to expand both, and feed -% the two floating point numbers swapped to \cs{@@_compare_back:ww}, +% the two floating point numbers swapped to \cs{@@_compare_back_any:ww}, % defined below. Compare the result with |`#2-`=|, which is $-1$ for % |<|, $0$ for |=|, $1$ for |>| and $2$ for |?|. % \begin{macrocode} @@ -135,16 +139,16 @@ } \cs_new:Npn \@@_compare_aux:wn #1; #2 { - \exp_after:wN \@@_compare_back:ww + \exp_after:wN \@@_compare_back_any:ww \exp:w \exp_end_continue_f:w \@@_parse:n {#2} #1; } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\@@_compare_back:ww, \@@_compare_nan:w} +% \begin{macro}[EXP]{\@@_compare_back_any:ww, \@@_compare_back:ww, \@@_compare_nan:w} % \begin{quote} -% \cs{@@_compare_back:ww} \meta{y} |;| \meta{x} |;| +% \cs{@@_compare_back_any:ww} \meta{y} |;| \meta{x} |;| % \end{quote} % Expands (in the same way as \cs{int_eval:n}) to $-1$ if $x<y$, $0$ % if $x=y$, $1$ if $x>y$, and $2$ otherwise (denoted as $x?y$). If @@ -157,6 +161,23 @@ % a different type, the highest type is a larger number. Finally, if % $y\leq 0$, then $x>y$, unless both are zero. % \begin{macrocode} +\cs_new:Npn \@@_compare_back_any:ww #1#2; #3 + { + \@@_if_type_fp:NTwFw + #1 { \@@_if_type_fp:NTwFw #3 \use_i:nn \s_@@ \use_ii:nn \q_stop } + \s_@@ \use_ii:nn \q_stop + \@@_compare_back:ww + { + \cs:w + @@ + \@@_type_from_scan:N #1 + _compare_back + \@@_type_from_scan:N #3 + :ww + \cs_end: + } + #1#2 ; #3 + } \cs_new:Npn \@@_compare_back:ww \s_@@ \@@_chk:w #1 #2 #3; \s_@@ \@@_chk:w #4 #5 #6; @@ -188,6 +209,46 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\@@_compare_back_tuple:ww, \@@_tuple_compare_back:ww, \@@_tuple_compare_back_tuple:ww} +% \begin{macro}[EXP]{\@@_tuple_compare_back_loop:w} +% Tuple and floating point numbers are not comparable so return $2$ in +% mixed cases or when tuples have a different number of items. +% Otherwise compare pairs of items with \cs{@@_compare_back_any:ww} +% and if any don't match return~$2$ (as \cs{__int_value:w} |02| +% \cs{exp_stop_f:}). +% \begin{macrocode} +\cs_new:Npn \@@_compare_back_tuple:ww #1; #2; { 2 } +\cs_new:Npn \@@_tuple_compare_back:ww #1; #2; { 2 } +\cs_new:Npn \@@_tuple_compare_back_tuple:ww + \s_@@_tuple \@@_tuple_chk:w #1; + \s_@@_tuple \@@_tuple_chk:w #2; + { + \int_compare:nNnTF { \@@_array_count:n {#1} } = { \@@_array_count:n {#2} } + { + \__int_value:w 0 + \@@_tuple_compare_back_loop:w + #1 { \s_@@ \__prg_break: } ; @ + #2 { \s_@@ \__prg_break: } ; + \__prg_break_point: + \exp_stop_f: + } + { 2 } + } +\cs_new:Npn \@@_tuple_compare_back_loop:w #1#2 ; #3 @ #4#5 ; + { + \use_none:n #1 + \use_none:n #4 + \if_int_compare:w + \@@_compare_back_any:ww #1 #2 ; #4 #5 ; = 0 \exp_stop_f: + \else: + 2 \exp_after:wN \__prg_break: + \fi: + \@@_tuple_compare_back_loop:w #3 @ + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[EXP]{\@@_compare_npos:nwnw} % \begin{macro}[EXP]{\@@_compare_significand:nnnnnnnn} % \begin{quote} @@ -309,7 +370,7 @@ % \end{macro} % % \begin{macro}[EXP]{\fp_step_function:nnnN, \fp_step_function:nnnc} -% \begin{macro}[EXP]{\@@_step:wwwN} +% \begin{macro}[EXP]{\@@_step:wwwN, \@@_step_fp:wwwN} % \begin{macro}[EXP]{\@@_step:NnnnnN, \@@_step:NfnnnN} % The approach here is somewhat similar to % \cs{int_step_function:nnnN}. There are two subtleties: we use the @@ -326,6 +387,7 @@ } \cs_generate_variant:Nn \fp_step_function:nnnN { nnnc } % \end{macrocode} +% Only floating point numbers (not tuples) are allowed arguments. % Only \enquote{normal} floating points (not $\pm 0$, % $\pm\texttt{inf}$, \texttt{nan}) can be used as step; if positive, % call \cs{@@_step:NnnnnN} with argument |>| otherwise~|<|. This @@ -334,7 +396,20 @@ % progress. Conversion to decimal is done just before calling the % user's function. % \begin{macrocode} -\cs_new:Npn \@@_step:wwwN #1 ; \s_@@ \@@_chk:w #2#3#4 ; #5; #6 +\cs_new:Npn \@@_step:wwwN #1#2; #3#4; #5#6; #7 + { + \@@_if_type_fp:NTwFw #1 { } \s_@@ \__prg_break: \q_stop + \@@_if_type_fp:NTwFw #3 { } \s_@@ \__prg_break: \q_stop + \@@_if_type_fp:NTwFw #5 { } \s_@@ \__prg_break: \q_stop + \use_i:nnnn { \@@_step_fp:wwwN #1#2; #3#4; #5#6; #7 } + \__prg_break_point: + \use:n + { + \@@_error:nfff { fp-step-tuple } { \fp_to_tl:n { #1#2 ; } } + { \fp_to_tl:n { #3#4 ; } } { \fp_to_tl:n { #5#6 ; } } + } + } +\cs_new:Npn \@@_step_fp:wwwN #1 ; \s_@@ \@@_chk:w #2#3#4 ; #5; #6 { \token_if_eq_meaning:NNTF #2 1 { @@ -410,6 +485,8 @@ % \end{macro} % % \begin{macrocode} +\__kernel_msg_new:nnn { kernel } { fp-step-tuple } + { Tuple~argument~in~fp_step_...~{#1}{#2}{#3}. } \__kernel_msg_new:nnn { kernel } { fp-bad-step } { Invalid~step~size~#2~in~step~function~#3. } \__kernel_msg_new:nnn { kernel } { fp-tiny-step } @@ -511,12 +588,12 @@ % % \subsection{Boolean operations} % -% \begin{macro}[EXP]{\@@_not_o:w} +% \begin{macro}[EXP]{\@@_not_o:w, \@@_tuple_not_o:w} % Return \texttt{true} or \texttt{false}, with two expansions, one to % exit the conditional, and one to please \pkg{l3fp-parse}. The first % argument is provided by \pkg{l3fp-parse} and is ignored. % \begin{macrocode} -\cs_new:cpn { @@_not_o:w } #1 \s_@@ \@@_chk:w #2#3; @ +\cs_new:Npn \@@_not_o:w #1 \s_@@ \@@_chk:w #2#3; @ { \if_meaning:w 0 #2 \exp_after:wN \exp_after:wN \exp_after:wN \c_one_fp @@ -524,11 +601,12 @@ \exp_after:wN \exp_after:wN \exp_after:wN \c_zero_fp \fi: } +\cs_new:Npn \@@_tuple_not_o:w #1 @ { \exp_after:wN \c_zero_fp } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]+\@@_&_o:ww+ -% \begin{macro}[EXP]+\@@_|_o:ww+ +% \begin{macro}[EXP]{\@@_&_o:ww, \@@_tuple_&_o:ww, \@@_&_tuple_o:ww, \@@_tuple_&_tuple_o:ww} +% \begin{macro}[EXP]{\@@_|_o:ww, \@@_tuple_|_o:ww, \@@_|_tuple_o:ww, \@@_tuple_|_tuple_o:ww} % \begin{macro}[EXP]{\@@_and_return:wNw} % For \texttt{and}, if the first number is zero, return it (with the % same sign). Otherwise, return the second one. For \texttt{or}, the @@ -547,9 +625,22 @@ \fi: \@@_exp_after_o:w } + \cs_new:Npn \@@_&_tuple_o:ww #1 \s_@@ \@@_chk:w #2#3; + { + \if_meaning:w 0 #2 #1 + \@@_and_return:wNw \s_@@ \@@_chk:w #2#3; + \fi: + \@@_exp_after_tuple_o:w + } + \cs_new:Npn \@@_tuple_&_o:ww #1; { \@@_exp_after_o:w } + \cs_new:Npn \@@_tuple_&_tuple_o:ww #1; { \@@_exp_after_tuple_o:w } \cs_new:Npn \@@_|_o:ww { \@@_&_o:ww \else: } + \cs_new:Npn \@@_|_tuple_o:ww { \@@_&_tuple_o:ww \else: } + \cs_new:Npn \@@_tuple_|_o:ww #1; #2; { \@@_exp_after_tuple_o:w #1; } + \cs_new:Npn \@@_tuple_|_tuple_o:ww #1; #2; { \@@_exp_after_tuple_o:w #1; } \group_end: -\cs_new:Npn \@@_and_return:wNw #1; \fi: #2#3; { \fi: #2 #1; } +\cs_new:Npn \@@_and_return:wNw #1; \fi: #2; + { \fi: \@@_exp_after_o:w #1; } % \end{macrocode} % \end{macro} % \end{macro} @@ -557,32 +648,28 @@ % % \subsection{Ternary operator} % -%^^A todo: understand and optimize. % \begin{macro}[EXP] % {\@@_ternary:NwwN, \@@_ternary_auxi:NwwN, \@@_ternary_auxii:NwwN} -% \begin{macro}[EXP] -% { -% \@@_ternary_loop_break:w, \@@_ternary_loop:Nw, -% \@@_ternary_map_break:, \@@_ternary_break_point:n -% } % The first function receives the test and the true branch of the |?:| -% ternary operator. It returns the true branch, unless the test -% branch is zero. In that case, the function returns a very specific -% \texttt{nan}. The second function receives the output of the first -% function, and the false branch. It returns the previous input, -% unless that is the special \texttt{nan}, in which case we return the -% false branch. +% ternary operator. It calls \cs{@@_ternary_auxii:NwwN} if the test +% branch is a floating point number $\pm 0$, and otherwise calls +% \cs{@@_ternary_auxi:NwwN}. These functions select one of their two +% arguments. % \begin{macrocode} -\cs_new:Npn \@@_ternary:NwwN #1 #2@ #3@ #4 +\cs_new:Npn \@@_ternary:NwwN #1 #2#3@ #4@ #5 { - \if_meaning:w \@@_parse_infix_::N #4 - \@@_ternary_loop:Nw - #2 - \s_@@ \@@_chk:w { \@@_ternary_loop_break:w } ; - \@@_ternary_break_point:n { \exp_after:wN \@@_ternary_auxi:NwwN } + \if_meaning:w \@@_parse_infix_::N #5 + \if_charcode:w 0 + \@@_if_type_fp:NTwFw + #2 { \use_i:nn \use_i_delimit_by_q_stop:nw #3 \q_stop } + \s_@@ 1 \q_stop + \exp_after:wN \exp_after:wN \exp_after:wN \@@_ternary_auxii:NwwN + \else: + \exp_after:wN \exp_after:wN \exp_after:wN \@@_ternary_auxi:NwwN + \fi: \exp_after:wN #1 \exp:w \exp_end_continue_f:w - \@@_exp_after_array_f:w #3 \s_@@_stop + \@@_exp_after_array_f:w #4 \s_@@_stop \exp_after:wN @ \exp:w \@@_parse_operand:Nw \c_@@_prec_colon_int @@ -593,25 +680,11 @@ \exp_after:wN \@@_parse_continue:NwN \exp_after:wN #1 \exp:w \exp_end_continue_f:w - \@@_exp_after_array_f:w #3 \s_@@_stop - \exp_after:wN #4 + \@@_exp_after_array_f:w #4 \s_@@_stop + \exp_after:wN #5 \exp_after:wN #1 \fi: } -\cs_new:Npn \@@_ternary_loop_break:w - #1 \fi: #2 \@@_ternary_break_point:n #3 - { - 0 = 0 \exp_stop_f: \fi: - \exp_after:wN \@@_ternary_auxii:NwwN - } -\cs_new:Npn \@@_ternary_loop:Nw \s_@@ \@@_chk:w #1#2; - { - \if_int_compare:w #1 > 0 \exp_stop_f: - \exp_after:wN \@@_ternary_map_break: - \fi: - \@@_ternary_loop:Nw - } -\cs_new:Npn \@@_ternary_map_break: #1 \@@_ternary_break_point:n #2 {#2} \cs_new:Npn \@@_ternary_auxi:NwwN #1#2@#3@#4 { \exp_after:wN \@@_parse_continue:NwN @@ -630,7 +703,6 @@ } % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macrocode} %</initex|package> |