diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx | 654 |
1 files changed, 249 insertions, 405 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index a25ce0967a0..1eba331f0fd 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -22,8 +22,8 @@ % %<*driver> \documentclass[full]{l3doc} -\GetIdInfo$Id: l3fp-parse.dtx 6987 2017-03-11 01:06:52Z bruno $ - {L3 Floating-point expression parsing} +\def\ExplFileDate{2017/03/18} +\def\ExplFileVersion{7019} \begin{document} \DocInput{\jobname.dtx} \end{document} @@ -655,12 +655,12 @@ { \exp_not:N \exp_after:wN \exp_not:N \@@_type_from_scan:w \exp_not:N \token_to_str:N #1 \exp_not:N \q_mark - \tl_to_str:n { s__fp _? } \exp_not:N \q_mark \exp_not:N \q_stop + \tl_to_str:n { s_@@ _? } \exp_not:N \q_mark \exp_not:N \q_stop } \use:x { \cs_new:Npn \exp_not:N \@@_type_from_scan:w - ##1 \tl_to_str:n { s__fp } ##2 \exp_not:N \q_mark ##3 \exp_not:N \q_stop + ##1 \tl_to_str:n { s_@@ } ##2 \exp_not:N \q_mark ##3 \exp_not:N \q_stop {##2} } % \end{macrocode} @@ -721,7 +721,8 @@ % % \begin{macro}[aux, EXP]{\@@_parse_one:Nw} % This function finds one number, and packs the symbol which follows -% in an |\..._infix_...| csname. |#1|~is the previous \meta{precedence}, +% in an \cs[no-index]{@@_parse_infix_\ldots{}} csname. +% |#1|~is the previous \meta{precedence}, % and |#2|~the first token of the operand. We distinguish four cases: % |#2|~is equal to \cs{scan_stop:} in meaning, |#2|~is a different % control sequence, |#2|~is a digit, and |#2|~is something else (this @@ -774,11 +775,11 @@ % \item \cs{s_@@_mark} is a premature end, we call % \cs{@@_exp_after_mark_f:nw}, which triggers an |fp-early-end| % error. -% \item For a control sequence not containing |\s__fp|, we call +% \item For a control sequence not containing \cs[no-index]{s_@@}, we call % \cs{@@_exp_after_?_f:nw}, causing a |bad-variable| error. % \end{itemize} % This scheme is extensible: additional types can be added by starting -% the variables with a scan mark of the form |\s__fp_|\meta{type} and +% the variables with a scan mark of the form \cs[no-index]{s_@@_\meta{type}} and % defining |\__fp_exp_after_|\meta{type}|_f:nw|. In all cases, we % make sure that the second argument of \cs{@@_parse_infix:NN} is % correctly expanded. @@ -809,22 +810,23 @@ \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w #1 } %<*package> -\group_begin: - \char_set_catcode_letter:N \@ - \cs_if_exist:NT \@unexpandable@protect - { - \cs_gset:cpn { @@_exp_after_?_f:nw } #1#2 - { - \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w #1 - \str_if_eq:nnTF {#2} { \protect } - { - \cs_if_eq:NNTF #2 \@unexpandable@protect { \use_i:nn } { \use:n } - { \__msg_kernel_expandable_error:nnn { kernel } { fp-robust-cmd } } - } - { \__msg_kernel_expandable_error:nnn { kernel } { bad-variable } {#2} } - } - } -\group_end: +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_if_exist:NT #1 + { + \cs_gset:cpn { @@_exp_after_?_f:nw } ##1##2 + { + \exp_after:wN \c_nan_fp \exp:w \exp_end_continue_f:w ##1 + \str_if_eq:nnTF {##2} { \protect } + { + \cs_if_eq:NNTF ##2 #1 { \use_i:nn } { \use:n } + { \__msg_kernel_expandable_error:nnn { kernel } { fp-robust-cmd } } + } + { \__msg_kernel_expandable_error:nnn { kernel } { bad-variable } {##2} } + } + } + } +\exp_args:Nc \@@_tmp:w { @unexpandable@protect } %</package> % \end{macrocode} % \end{macro} @@ -947,7 +949,7 @@ % % \begin{macro}[aux, EXP]{\@@_parse_one_other:NN} % For this function, |#2|~is a character token which is not a digit. -% If it is a letter, \cs{@@_parse_letters:N} beyond this one and give +% If it is an \textsc{ascii} letter, \cs{@@_parse_letters:N} beyond this one and give % the result to \cs{@@_parse_word:Nw}. Otherwise, the character is % assumed to be a prefix operator, and we build % |\__fp_parse_prefix_|\meta{operator}|:Nw|. @@ -1143,9 +1145,9 @@ % \end{macro} % % \begin{macro}[aux, EXP]{\@@_parse_zero:} -% After reading a significand of~$0$, we need to remove any exponent, -% then put a sign of~|1| for \cs{@@_sanitize:wN}, small hack to denote -% an exact zero (rather than an underflow). +% After reading a significand of~$0$, find any exponent, then put a +% sign of~|1| for \cs{@@_sanitize:wN}, which will remove everything +% and leave an exact zero. % \begin{macrocode} \cs_new:Npn \@@_parse_zero: { @@ -1771,9 +1773,11 @@ % Here, |#1| is a precedence, |#2| is some extra data used by some % functions, |#3| is \emph{e.g.}, \cs{@@_sin_o:w}, and expands once % after the calculation, |#4| is the operand, and |#5| is a -% |\__fp_parse_infix_...:N| function. We feed the data~|#2|, and the +% \cs[no-index]{@@_parse_infix_\ldots{}:N} function. We feed the data~|#2|, and the % argument~|#4|, to the function~|#3|, which expands % \cs{exp:w} thus the \texttt{infix} function~|#5|. +% +% This is redefined in \pkg{l3fp-extras}. % \begin{macrocode} \cs_new:Npn \@@_parse_apply_unary:NNNwN #1#2#3#4@#5 { @@ -1843,37 +1847,37 @@ % and leaves in the input stream the array it found as an operand, % fetching the following infix operator. % \begin{macrocode} -\group_begin: - \char_set_catcode_letter:N ( - \char_set_catcode_letter:N ) - \cs_new:Npn \@@_parse_prefix_(:Nw #1 - { - \exp_after:wN \@@_parse_lparen_after:NwN - \exp_after:wN #1 - \exp:w - \if_int_compare:w #1 = \c_@@_prec_funcii_int - \@@_parse_operand:Nw \c_@@_prec_comma_int - \else: - \@@_parse_operand:Nw \c_@@_prec_paren_int - \fi: - \@@_parse_expand:w - } - \cs_new:Npn \@@_parse_lparen_after:NwN #1#2 @ #3 - { - \token_if_eq_meaning:NNTF #3 \@@_parse_infix_):N - { - \@@_exp_after_array_f:w #2 \s_@@_stop - \exp_after:wN \@@_parse_infix:NN - \exp_after:wN #1 - \exp:w \@@_parse_expand:w - } - { - \__msg_kernel_expandable_error:nnn - { kernel } { fp-missing } { ) } - #2 @ \use_none:n #3 - } - } -\group_end: +\cs_new:cpn { @@_parse_prefix_(:Nw } #1 + { + \exp_after:wN \@@_parse_lparen_after:NwN + \exp_after:wN #1 + \exp:w + \if_int_compare:w #1 = \c_@@_prec_funcii_int + \@@_parse_operand:Nw \c_@@_prec_comma_int + \else: + \@@_parse_operand:Nw \c_@@_prec_paren_int + \fi: + \@@_parse_expand:w + } +\cs_new:Npx \@@_parse_lparen_after:NwN #1#2 @ #3 + { + \exp_not:N \token_if_eq_meaning:NNTF #3 + \exp_not:c { @@_parse_infix_):N } + { + \exp_not:N \@@_exp_after_array_f:w #2 \s_@@_stop + \exp_not:N \exp_after:wN + \exp_not:N \@@_parse_infix:NN + \exp_not:N \exp_after:wN #1 + \exp_not:N \exp:w + \exp_not:N \@@_parse_expand:w + } + { + \exp_not:N \__msg_kernel_expandable_error:nnn + { kernel } { fp-missing } { ) } + #2 @ + \exp_not:N \use_none:n #3 + } + } % \end{macrocode} % \end{macro} % @@ -1976,20 +1980,15 @@ % % ^^A begin[todo] % -% ^^A todo: test <15 digits>1500000000.1 -% ^^A todo: test <15 digits>1517263572.000 -% -% ^^A todo: word 'e' == 'invalid syntax', word 'E' == "use 'e' instead" -% % \begin{macro}[aux, EXP] -% {\@@_parse_unary_function:nNN, \@@_parse_function:NNN} +% {\@@_parse_unary_function:NNN, \@@_parse_function:NNN} % \begin{macrocode} -\cs_new:Npn \@@_parse_unary_function:nNN #1#2#3 +\cs_new:Npn \@@_parse_unary_function:NNN #1#2#3 { \exp_after:wN \@@_parse_apply_unary:NNNwN \exp_after:wN #3 \exp_after:wN #2 - \cs:w @@_#1_o:w \exp_after:wN \cs_end: + \exp_after:wN #1 \exp:w \@@_parse_operand:Nw \c_@@_prec_func_int \@@_parse_expand:w } @@ -2005,141 +2004,6 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP] -% { -% \@@_parse_word_acot:N , \@@_parse_word_acotd:N, -% \@@_parse_word_atan:N , \@@_parse_word_atand:N, -% \@@_parse_word_max:N , \@@_parse_word_min:N , -% \@@_parse_word_rand:N , \@@_parse_word_randint:N, -% } -% Those functions are also unary (not binary), but may receive a -% variable number of arguments. -% For |randint| we don't use the first argument~|?|. -% \begin{macrocode} -\cs_new:Npn \@@_parse_word_acot:N - { \@@_parse_function:NNN \@@_acot_o:Nw \use_i:nn } -\cs_new:Npn \@@_parse_word_acotd:N - { \@@_parse_function:NNN \@@_acot_o:Nw \use_ii:nn } -\cs_new:Npn \@@_parse_word_atan:N - { \@@_parse_function:NNN \@@_atan_o:Nw \use_i:nn } -\cs_new:Npn \@@_parse_word_atand:N - { \@@_parse_function:NNN \@@_atan_o:Nw \use_ii:nn } -\cs_new:Npn \@@_parse_word_max:N - { \@@_parse_function:NNN \@@_minmax_o:Nw 2 } -\cs_new:Npn \@@_parse_word_min:N - { \@@_parse_function:NNN \@@_minmax_o:Nw 0 } -\cs_new:Npn \@@_parse_word_rand:N - { \@@_parse_function:NNN \@@_rand_o:Nw ? } -\cs_new:Npn \@@_parse_word_randint:N - { \@@_parse_function:NNN \@@_randint_o:Nw ? } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux, EXP] -% { -% \@@_parse_word_abs:N , -% \@@_parse_word_exp:N , -% \@@_parse_word_ln:N , -% \@@_parse_word_sign:N , -% \@@_parse_word_sqrt:N , -% } -% Unary functions. -% \begin{macrocode} -\cs_new:Npn \@@_parse_word_abs:N - { \@@_parse_unary_function:nNN { set_sign } 0 } -\cs_new:Npn \@@_parse_word_exp:N - { \@@_parse_unary_function:nNN {exp} ? } -\cs_new:Npn \@@_parse_word_ln:N - { \@@_parse_unary_function:nNN {ln} ? } -\cs_new:Npn \@@_parse_word_sign:N - { \@@_parse_unary_function:nNN {sign} ? } -\cs_new:Npn \@@_parse_word_sqrt:N - { \@@_parse_unary_function:nNN {sqrt} ? } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux, EXP] -% { -% \@@_parse_word_acos:N , -% \@@_parse_word_acosd:N , -% \@@_parse_word_acsc:N , -% \@@_parse_word_acscd:N , -% \@@_parse_word_asec:N , -% \@@_parse_word_asecd:N , -% \@@_parse_word_asin:N , -% \@@_parse_word_asind:N , -% \@@_parse_word_cos:N , -% \@@_parse_word_cosd:N , -% \@@_parse_word_cot:N , -% \@@_parse_word_cotd:N , -% \@@_parse_word_csc:N , -% \@@_parse_word_cscd:N , -% \@@_parse_word_sec:N , -% \@@_parse_word_secd:N , -% \@@_parse_word_sin:N , -% \@@_parse_word_sind:N , -% \@@_parse_word_tan:N , -% \@@_parse_word_tand:N , -% } -% Unary functions. -% \begin{macrocode} -\tl_map_inline:nn - { - {acos} {acsc} {asec} {asin} - {cos} {cot} {csc} {sec} {sin} {tan} - } - { - \cs_new:cpn { @@_parse_word_#1:N } - { \@@_parse_unary_function:nNN {#1} \use_i:nn } - \cs_new:cpn { @@_parse_word_#1d:N } - { \@@_parse_unary_function:nNN {#1} \use_ii:nn } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux, EXP] -% { -% \@@_parse_word_trunc:N, -% \@@_parse_word_floor:N, -% \@@_parse_word_ceil:N -% } -% \begin{macrocode} -\cs_new:Npn \@@_parse_word_trunc:N - { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_zero:NNN } -\cs_new:Npn \@@_parse_word_floor:N - { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_ninf:NNN } -\cs_new:Npn \@@_parse_word_ceil:N - { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_pinf:NNN } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux, EXP]{\@@_parse_word_round:N, \@@_parse_round:Nw} -% \begin{macro}[aux, deprecated = 2017-12-31]{round+, round0, round-} -% This looks for |+|, |-|, |0| after |round|. That syntax is deprecated. -% \begin{macrocode} -\cs_new:Npn \@@_parse_word_round:N #1#2 - { - \if_meaning:w + #2 - \@@_parse_round:Nw \@@_round_to_pinf:NNN - \else: - \if_meaning:w 0 #2 - \@@_parse_round:Nw \@@_round_to_zero:NNN - \else: - \if_meaning:w - #2 - \@@_parse_round:Nw \@@_round_to_ninf:NNN - \fi: - \fi: - \fi: - \@@_parse_function:NNN - \@@_round_o:Nw \@@_round_to_nearest:NNN #1 - #2 - } -\cs_new:Npn \@@_parse_round:Nw - #1 #2 \@@_round_to_nearest:NNN #3#4 { #2 #1 #3 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \subsection{Main functions} % % \begin{macro}[int, EXP]{\@@_parse:n} @@ -2185,11 +2049,9 @@ % % \begin{macro}[aux, EXP]{\@@_parse_operand:Nw} % \begin{macro}[aux, EXP]{\@@_parse_continue:NwN} -% The \cs{@@_parse_operand} -% This is just a shorthand which sets up both \cs{@@_parse_continue} -% and \cs{@@_parse_one} with the same precedence. Note the -% trailing \cs{exp:w}. This function should be -% used with much care. +% This is just a shorthand which sets up both \cs{@@_parse_continue:NwN} +% and \cs{@@_parse_one:Nw} with the same precedence. Note the +% trailing \cs{exp:w}. % \begin{macrocode} \cs_new:Npn \@@_parse_operand:Nw #1 { @@ -2210,6 +2072,8 @@ % Receives \meta{precedence} \meta{operand_1} |@| \meta{operation} % \meta{operand_2} |@| \meta{infix command}. Builds the appropriate % call to the \meta{operation}~|#3|. +% +% This is redefined in \pkg{l3fp-extras}. % \begin{macrocode} \cs_new:Npn \@@_parse_apply_binary:NwNwN #1 #2@ #3 #4@ #5 { @@ -2230,8 +2094,6 @@ \@@_exp_after_f:nw { \@@_parse_infix:NN #1 } #2; } -\group_begin: - \char_set_catcode_letter:N \* \cs_new:Npn \@@_parse_infix:NN #1 #2 { \if_catcode:w \scan_stop: \exp_not:N #2 @@ -2262,21 +2124,23 @@ #1 #2 } - \cs_new:Npn \@@_parse_infix_check:NNN #1#2#3 - { - \if_meaning:w \scan_stop: #1 - \__msg_kernel_expandable_error:nnn - { kernel } { fp-missing } { * } - \exp_after:wN \@@_parse_infix_*:N - \exp_after:wN #2 - \exp_after:wN #3 - \else: - \exp_after:wN #1 - \exp_after:wN #2 - \exp:w \exp_after:wN \@@_parse_expand:w - \fi: - } -\group_end: +\cs_new:Npx \@@_parse_infix_check:NNN #1#2#3 + { + \exp_not:N \if_meaning:w \scan_stop: #1 + \exp_not:N \__msg_kernel_expandable_error:nnn + { kernel } { fp-missing } { * } + \exp_not:N \exp_after:wN + \exp_not:c { @@_parse_infix_*:N } + \exp_not:N \exp_after:wN #2 + \exp_not:N \exp_after:wN #3 + \exp_not:N \else: + \exp_not:N \exp_after:wN #1 + \exp_not:N \exp_after:wN #2 + \exp_not:N \exp:w + \exp_not:N \exp_after:wN + \exp_not:N \@@_parse_expand:w + \exp_not:N \fi: + } % \end{macrocode} % \end{macro} % @@ -2306,22 +2170,23 @@ % an extra closing parenthesis if the previous operator was the % beginning of the expression. % \begin{macrocode} -\group_begin: - \char_set_catcode_letter:N \) - \cs_new:Npn \@@_parse_infix_):N #1 - { - \if_int_compare:w #1 < \c_@@_prec_paren_int - \__msg_kernel_expandable_error:nnn { kernel } { fp-extra } { ) } - \exp_after:wN \@@_parse_infix:NN - \exp_after:wN #1 - \exp:w \exp_after:wN \@@_parse_expand:w - \else: - \exp_after:wN @ - \exp_after:wN \use_none:n - \exp_after:wN \@@_parse_infix_):N - \fi: - } -\group_end: +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn #1 ##1 + { + \if_int_compare:w ##1 < \c_@@_prec_paren_int + \__msg_kernel_expandable_error:nnn { kernel } { fp-extra } { ) } + \exp_after:wN \@@_parse_infix:NN + \exp_after:wN ##1 + \exp:w \exp_after:wN \@@_parse_expand:w + \else: + \exp_after:wN @ + \exp_after:wN \use_none:n + \exp_after:wN #1 + \fi: + } + } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_):N } % \end{macrocode} % \end{macro} % @@ -2331,44 +2196,49 @@ % \cs{@@_,_o:ww} is a complicated way of replacing any number of % floating point arguments by \texttt{nan}. % \begin{macrocode} -\group_begin: - \char_set_catcode_letter:N \, - \cs_new:Npn \@@_parse_infix_,:N #1 - { - \if_int_compare:w #1 > \c_@@_prec_comma_int - \exp_after:wN @ - \exp_after:wN \use_none:n - \exp_after:wN \@@_parse_infix_,:N - \else: - \if_int_compare:w #1 < \c_@@_prec_comma_int - \@@_parse_infix_comma_error:w +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn #1 ##1 + { + \if_int_compare:w ##1 > \c_@@_prec_comma_int + \exp_after:wN @ + \exp_after:wN \use_none:n + \exp_after:wN #1 + \else: + \if_int_compare:w ##1 < \c_@@_prec_comma_int + \@@_parse_infix_comma_error:w + \fi: + \exp_after:wN \@@_parse_infix_comma:w + \exp:w \@@_parse_operand:Nw \c_@@_prec_comma_int + \exp_after:wN \@@_parse_expand:w \fi: - \exp_after:wN \@@_parse_infix_comma:w - \exp:w \@@_parse_operand:Nw \c_@@_prec_comma_int - \exp_after:wN \@@_parse_expand:w - \fi: - } - \cs_new:Npn \@@_parse_infix_comma:w #1 @ - { #1 @ \use_none:n } - \cs_new:Npn \@@_parse_infix_comma_error:w #1 \exp:w - { - \fi: - \__msg_kernel_expandable_error:nn { kernel } { fp-extra-comma } - \exp_after:wN @ - \exp_after:wN \@@_parse_apply_binary:NwNwN - \exp_after:wN , - \exp:w - } - \cs_new:Npn \@@_,_o:ww #1 - { - \if_meaning:w \s_@@ #1 - \exp_after:wN \@@_use_i_until_s:nw - \exp_after:wN \@@_,_o:ww - \fi: - \exp_after:wN \c_nan_fp - #1 - } -\group_end: + } + } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_,:N } +\cs_new:Npn \@@_parse_infix_comma:w #1 @ + { #1 @ \use_none:n } +\cs_new:Npn \@@_parse_infix_comma_error:w #1 \exp:w + { + \fi: + \__msg_kernel_expandable_error:nn { kernel } { fp-extra-comma } + \exp_after:wN @ + \exp_after:wN \@@_parse_apply_binary:NwNwN + \exp_after:wN , + \exp:w + } +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:Npn #1 ##1 + { + \if_meaning:w \s_@@ ##1 + \exp_after:wN \@@_use_i_until_s:nw + \exp_after:wN #1 + \fi: + \exp_after:wN \c_nan_fp + ##1 + } + } +\exp_args:Nc \@@_tmp:w { @@_,_o:ww } % \end{macrocode} % \end{macro} % \end{macro} @@ -2382,53 +2252,46 @@ % \@@_parse_infix_/:N, \@@_parse_infix_mul:N, % \@@_parse_infix_and:N, \@@_parse_infix_or:N, % } -% \begin{macro}[aux, EXP]+\@@_parse_infix_^:N+ As described in the -% \enquote{work plan}, each infix operator has an associated -% |\..._infix_...| function, a computing function, and precedence, given as -% arguments to \cs{@@_tmp:w}. Using the general mechanism for -% arithmetic operations. The power operation must be associative in -% the opposite order from all others. For this, we use two distinct -% precedences. -% -% The odd requirement to set \cs{+} here is to cover the case where -% \pkg{expl3} is loaded by plain \TeX{}: \cs{+} is an \cs{outer} macro there, -% and so the following code would otherwise give an error in that case. -% \begin{macrocode} -\group_begin: -%<*package> - \cs_set:Npn \+ { } -%</package> - \char_set_catcode_other:N \& - \char_set_catcode_letter:N \^ - \char_set_catcode_letter:N \/ - \char_set_catcode_letter:N \- - \char_set_catcode_letter:N \+ - \cs_set_protected:Npn \@@_tmp:w #1#2#3#4 - { - \cs_new:Npn #1 ##1 - { - \if_int_compare:w ##1 < #3 - \exp_after:wN @ - \exp_after:wN \@@_parse_apply_binary:NwNwN - \exp_after:wN #2 - \exp:w - \@@_parse_operand:Nw #4 - \exp_after:wN \@@_parse_expand:w - \else: - \exp_after:wN @ - \exp_after:wN \use_none:n - \exp_after:wN #1 - \fi: - } - } - \@@_tmp:w \@@_parse_infix_^:N ^ \c_@@_prec_hatii_int \c_@@_prec_hat_int - \@@_tmp:w \@@_parse_infix_/:N / \c_@@_prec_times_int \c_@@_prec_times_int - \@@_tmp:w \@@_parse_infix_mul:N * \c_@@_prec_times_int \c_@@_prec_times_int - \@@_tmp:w \@@_parse_infix_-:N - \c_@@_prec_plus_int \c_@@_prec_plus_int - \@@_tmp:w \@@_parse_infix_+:N + \c_@@_prec_plus_int \c_@@_prec_plus_int - \@@_tmp:w \@@_parse_infix_and:N & \c_@@_prec_and_int \c_@@_prec_and_int - \@@_tmp:w \@@_parse_infix_or:N | \c_@@_prec_or_int \c_@@_prec_or_int -\group_end: +% \begin{macro}[aux, EXP]+\@@_parse_infix_^:N+ +% As described in the \enquote{work plan}, each infix operator has an +% associated |\..._infix_...| function, a computing function, and +% precedence, given as arguments to \cs{@@_tmp:w}. Using the general +% mechanism for arithmetic operations. The power operation must be +% associative in the opposite order from all others. For this, we use +% two distinct precedences. +% \begin{macrocode} +\cs_set_protected:Npn \@@_tmp:w #1#2#3#4 + { + \cs_new:Npn #1 ##1 + { + \if_int_compare:w ##1 < #3 + \exp_after:wN @ + \exp_after:wN \@@_parse_apply_binary:NwNwN + \exp_after:wN #2 + \exp:w + \@@_parse_operand:Nw #4 + \exp_after:wN \@@_parse_expand:w + \else: + \exp_after:wN @ + \exp_after:wN \use_none:n + \exp_after:wN #1 + \fi: + } + } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_^:N } ^ + \c_@@_prec_hatii_int \c_@@_prec_hat_int +\exp_args:Nc \@@_tmp:w { @@_parse_infix_/:N } / + \c_@@_prec_times_int \c_@@_prec_times_int +\exp_args:Nc \@@_tmp:w { @@_parse_infix_mul:N } * + \c_@@_prec_times_int \c_@@_prec_times_int +\exp_args:Nc \@@_tmp:w { @@_parse_infix_-:N } - + \c_@@_prec_plus_int \c_@@_prec_plus_int +\exp_args:Nc \@@_tmp:w { @@_parse_infix_+:N } + + \c_@@_prec_plus_int \c_@@_prec_plus_int +\exp_args:Nc \@@_tmp:w { @@_parse_infix_and:N } & + \c_@@_prec_and_int \c_@@_prec_and_int +\exp_args:Nc \@@_tmp:w { @@_parse_infix_or:N } | + \c_@@_prec_or_int \c_@@_prec_or_int % \end{macrocode} % \end{macro} % \end{macro} @@ -2473,7 +2336,7 @@ { \if_catcode:w ^ \tl_to_str:n { #3 #5 } ^ \else: - \@@_error:nffn { invalid-ii } + \@@_error:nffn { fp-invalid-ii } { \@@_array_to_clist:n { #2; #3 } } { \@@_array_to_clist:n { #4; #5 } } { } @@ -2487,54 +2350,44 @@ % % \begin{macro}[aux, EXP]{\@@_parse_infix_*:N} % \begin{macrocode} -\group_begin: - \char_set_catcode_letter:N ^ - \cs_new:cpn { @@_parse_infix_*:N } #1#2 - { - \if:w * \exp_not:N #2 - \exp_after:wN \@@_parse_infix_^:N - \exp_after:wN #1 - \else: - \exp_after:wN \@@_parse_infix_mul:N - \exp_after:wN #1 - \exp_after:wN #2 - \fi: - } -\group_end: +\cs_set_protected:Npn \@@_tmp:w #1 + { + \cs_new:cpn { @@_parse_infix_*:N } ##1##2 + { + \if:w * \exp_not:N ##2 + \exp_after:wN #1 + \exp_after:wN ##1 + \else: + \exp_after:wN \@@_parse_infix_mul:N + \exp_after:wN ##1 + \exp_after:wN ##2 + \fi: + } + } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_^:N } % \end{macrocode} % \end{macro} % % \begin{macro}[aux, EXP]+\@@_parse_infix_|:Nw+ % \begin{macro}[aux, EXP]+\@@_parse_infix_&:Nw+ % \begin{macrocode} -\group_begin: - \char_set_catcode_letter:N \| - \char_set_catcode_letter:N \& - \cs_new:Npn \@@_parse_infix_|:N #1#2 - { - \if:w | \exp_not:N #2 - \exp_after:wN \@@_parse_infix_|:N - \exp_after:wN #1 - \exp:w \exp_after:wN \@@_parse_expand:w - \else: - \exp_after:wN \@@_parse_infix_or:N - \exp_after:wN #1 - \exp_after:wN #2 - \fi: - } - \cs_new:Npn \@@_parse_infix_&:N #1#2 - { - \if:w & \exp_not:N #2 - \exp_after:wN \@@_parse_infix_&:N - \exp_after:wN #1 - \exp:w \exp_after:wN \@@_parse_expand:w - \else: - \exp_after:wN \@@_parse_infix_and:N - \exp_after:wN #1 - \exp_after:wN #2 - \fi: - } -\group_end: +\cs_set_protected:Npn \@@_tmp:w #1#2#3 + { + \cs_new:Npn #1 ##1##2 + { + \if:w #2 \exp_not:N ##2 + \exp_after:wN #1 + \exp_after:wN ##1 + \exp:w \exp_after:wN \@@_parse_expand:w + \else: + \exp_after:wN #3 + \exp_after:wN ##1 + \exp_after:wN ##2 + \fi: + } + } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_|:N } | \@@_parse_infix_or:N +\exp_args:Nc \@@_tmp:w { @@_parse_infix_&:N } & \@@_parse_infix_and:N % \end{macrocode} % \end{macro} % \end{macro} @@ -2543,39 +2396,32 @@ % % \begin{macro}[aux, EXP]{\@@_parse_infix_?:N, \@@_parse_infix_::N} % \begin{macrocode} -\group_begin: - \char_set_catcode_letter:N \? - \cs_new:Npn \@@_parse_infix_?:N #1 - { - \if_int_compare:w #1 < \c_@@_prec_quest_int - \exp_after:wN @ - \exp_after:wN \@@_ternary:NwwN - \exp:w - \@@_parse_operand:Nw \c_@@_prec_quest_int - \exp_after:wN \@@_parse_expand:w - \else: - \exp_after:wN @ - \exp_after:wN \use_none:n - \exp_after:wN \@@_parse_infix_?:N - \fi: - } - \cs_new:Npn \@@_parse_infix_::N #1 - { - \if_int_compare:w #1 < \c_@@_prec_quest_int - \__msg_kernel_expandable_error:nnnn - { kernel } { fp-missing } { ? } { ~for~?: } - \exp_after:wN @ - \exp_after:wN \@@_ternary_auxii:NwwN - \exp:w - \@@_parse_operand:Nw \c_@@_prec_colon_int - \exp_after:wN \@@_parse_expand:w - \else: - \exp_after:wN @ - \exp_after:wN \use_none:n - \exp_after:wN \@@_parse_infix_::N - \fi: - } -\group_end: +\cs_set_protected:Npn \@@_tmp:w #1#2#3#4 + { + \cs_new:Npn #1 ##1 + { + \if_int_compare:w ##1 < \c_@@_prec_quest_int + #4 + \exp_after:wN @ + \exp_after:wN #2 + \exp:w + \@@_parse_operand:Nw #3 + \exp_after:wN \@@_parse_expand:w + \else: + \exp_after:wN @ + \exp_after:wN \use_none:n + \exp_after:wN #1 + \fi: + } + } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_?:N } + \@@_ternary:NwwN \c_@@_prec_quest_int { } +\exp_args:Nc \@@_tmp:w { @@_parse_infix_::N } + \@@_ternary_auxii:NwwN \c_@@_prec_colon_int + { + \__msg_kernel_expandable_error:nnnn + { kernel } { fp-missing } { ? } { ~for~?: } + } % \end{macrocode} % \end{macro} % @@ -2631,11 +2477,7 @@ \cs_new:Npn \@@_parse_compare_auxi:NNNNNNN #1#2#3#4#5#6#7 { \if_case:w - \if_catcode:w \scan_stop: \exp_not:N #7 - 4 \exp_stop_f: - \else: - \__int_eval:w `#7 - `< \__int_eval_end: - \fi: + \__int_eval:w \exp_after:wN ` \token_to_str:N #7 - `< \__int_eval_end: \@@_parse_compare_auxii:NNNNN #2#2#4#5#6 \or: \@@_parse_compare_auxii:NNNNN #2#3#2#5#6 \or: \@@_parse_compare_auxii:NNNNN #2#3#4#2#6 @@ -2823,6 +2665,8 @@ % \subsection{Messages} % % \begin{macrocode} +\__msg_kernel_new:nnn { kernel } { fp-deprecated } + { '#1'~deprecated;~use~'#2' } \__msg_kernel_new:nnn { kernel } { unknown-fp-word } { Unknown~fp~word~#1. } \__msg_kernel_new:nnn { kernel } { fp-missing } |