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 | 271 |
1 files changed, 197 insertions, 74 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index 3923238e387..7f8d4c4a194 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx @@ -36,7 +36,7 @@ % %<*driver> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3fp-parse.dtx 4604 2013-11-19 03:03:47Z bruno $ +\GetIdInfo$Id: l3fp-parse.dtx 4622 2013-12-14 13:05:45Z bruno $ {L3 Floating-point expression parsing} \documentclass[full]{l3doc} \begin{document} @@ -1721,7 +1721,7 @@ \exp_after:wN \@@_parse_apply_unary:NNNwN \exp_after:wN ##1 \exp_after:wN #4 - \cs:w @@_#3_o:w \exp_after:wN \cs_end: + \exp_after:wN #3 \tex_romannumeral:D \if_int_compare:w #2 < ##1 \@@_parse_operand:Nw ##1 @@ -1731,8 +1731,8 @@ \@@_parse_expand:w } } -\@@_tmp:w - \c_twelve { set_sign } 2 -\@@_tmp:w ! \c_twelve { not } ? +\@@_tmp:w - \c_twelve \@@_set_sign_o:w 2 +\@@_tmp:w ! \c_twelve \@@_not_o:w ? % \end{macrocode} % \end{macro} % @@ -1939,6 +1939,7 @@ % \@@_parse_word_abs:N , % \@@_parse_word_exp:N , % \@@_parse_word_ln:N , +% \@@_parse_word_sqrt:N , % } % Unary functions. % \begin{macrocode} @@ -1948,6 +1949,8 @@ { \@@_parse_unary_function:nNN {exp} ? } \cs_new_nopar:Npn \@@_parse_word_ln:N { \@@_parse_unary_function:nNN {ln} ? } +\cs_new_nopar:Npn \@@_parse_word_sqrt:N + { \@@_parse_unary_function:nNN {sqrt} ? } % \end{macrocode} % \end{macro} % @@ -1990,8 +1993,23 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[aux, EXP]{\@@_parse_word_round:N} -% This function expects one or two arguments. +% \begin{macro}[aux, EXP] +% { +% \@@_parse_word_trunc:N, +% \@@_parse_word_floor:N, +% \@@_parse_word_ceil:N +% } +% \begin{macrocode} +\cs_new_nopar:Npn \@@_parse_word_trunc:N + { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_zero:NNN } +\cs_new_nopar:Npn \@@_parse_word_floor:N + { \@@_parse_function:NNN \@@_round_o:Nw \@@_round_to_ninf:NNN } +\cs_new_nopar: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{macrocode} \cs_new:Npn \@@_parse_word_round:N #1#2 { @@ -2006,27 +2024,12 @@ \fi: \fi: \fi: - \exp_after:wN \@@_parse_apply_round:NNwN - \exp_after:wN #1 - \exp_after:wN \@@_round_to_nearest:NNN - \tex_romannumeral:D - \@@_parse_operand:Nw \c_sixteen \@@_parse_expand:w #2 + \@@_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 \@@_parse_expand:w #4 - { #2 #1 #3 \@@_parse_expand:w } -\cs_new:Npn \@@_parse_apply_round:NNwN #1#2#3@#4 - { - \if_case:w \__int_eval:w \@@_array_count:n {#3} - \c_one \__int_eval_end: - \@@_round:Nwn #2 #3 {0} \tex_romannumeral:D - \or: \@@_round:Nww #2 #3 \tex_romannumeral:D - \else: - \__msg_kernel_expandable_error:nnnnn - { kernel } { fp-num-args } { round() } { 1 } { 2 } - \exp_after:wN \c_nan_fp \tex_romannumeral:D - \fi: - -`0 #4 #1 - } + #1 #2 \@@_round_to_nearest:NNN #3#4 { #2 #1 #3 } % \end{macrocode} % \end{macro} % @@ -2428,74 +2431,73 @@ % } % \begin{macro}[aux, EXP] % { -% \@@_parse_infix_excl_aux:NN, -% \@@_parse_infix_excl_error:, -% \@@_infix_compare:N, -% \@@_parse_compare:NNNNNNw, -% \@@_parse_compare_expand:NNNNNw, -% \@@_parse_compare_end:NNNN, +% \@@_parse_excl_error:, +% \@@_parse_compare:NNNNNNN, +% \@@_parse_compare_auxi:NNNNNNN, +% \@@_parse_compare_auxii:NNNNN, +% \@@_parse_compare_end:NNNNw, % \@@_compare:wNNNNw, % } % \begin{macrocode} \cs_new:cpn { @@_parse_infix_<:N } #1 { - \@@_infix_compare:N #1 \c_one_fp - \c_zero_fp \c_zero_fp \c_zero_fp \c_zero_fp < + \@@_parse_compare:NNNNNNN #1 \c_one + \c_zero \c_zero \c_zero \c_zero < } \cs_new:cpn { @@_parse_infix_=:N } #1 { - \@@_infix_compare:N #1 \c_one_fp - \c_zero_fp \c_zero_fp \c_zero_fp \c_zero_fp = + \@@_parse_compare:NNNNNNN #1 \c_one + \c_zero \c_zero \c_zero \c_zero = } \cs_new:cpn { @@_parse_infix_>:N } #1 { - \@@_infix_compare:N #1 \c_one_fp - \c_zero_fp \c_zero_fp \c_zero_fp \c_zero_fp > + \@@_parse_compare:NNNNNNN #1 \c_one + \c_zero \c_zero \c_zero \c_zero > } \cs_new:cpn { @@_parse_infix_!:N } #1 { - \exp_after:wN \@@_parse_infix_excl_aux:NN - \exp_after:wN #1 \tex_romannumeral:D \@@_parse_expand:w - } -\cs_new:Npn \@@_parse_infix_excl_aux:NN #1#2 - { - \@@_infix_compare:N #1 \c_zero_fp - \c_one_fp \c_one_fp \c_one_fp \c_one_fp #2 + \exp_after:wN \@@_parse_compare:NNNNNNN + \exp_after:wN #1 + \exp_after:wN \c_zero + \exp_after:wN \c_one + \exp_after:wN \c_one + \exp_after:wN \c_one + \exp_after:wN \c_one } -\cs_new:Npn \@@_parse_infix_excl_error: +\cs_new:Npn \@@_parse_excl_error: { \__msg_kernel_expandable_error:nnnn { kernel } { fp-missing } { = } { ~after~!. } } -\cs_new:Npn \@@_infix_compare:N #1 +\cs_new:Npn \@@_parse_compare:NNNNNNN #1 { \if_int_compare:w #1 < \c_seven - \exp_after:wN \@@_parse_compare:NNNNNNw - \exp_after:wN \@@_parse_infix_excl_error: + \exp_after:wN \@@_parse_compare_auxi:NNNNNNN + \exp_after:wN \@@_parse_excl_error: \else: \exp_after:wN @ \exp_after:wN \use_none:n - \exp_after:wN \@@_infix_compare:N + \exp_after:wN \@@_parse_compare:NNNNNNN \fi: } -\cs_new:Npn \@@_parse_compare:NNNNNNw #1#2#3#4#5#6#7 +\cs_new:Npn \@@_parse_compare_auxi:NNNNNNN #1#2#3#4#5#6#7 { \if_case:w - \if_catcode:w \scan_stop: #7 + \if_catcode:w \scan_stop: \exp_not:N #7 \c_minus_one \else: \__int_eval:w `#7 - `< \__int_eval_end: \fi: - \@@_parse_compare_expand:NNNNNw #2#2#4#5#6 - \or: \@@_parse_compare_expand:NNNNNw #2#3#2#5#6 - \or: \@@_parse_compare_expand:NNNNNw #2#3#4#2#6 - \or: \@@_parse_compare_expand:NNNNNw #2#3#4#5#2 - \else: #1 \@@_parse_compare_end:NNNN #3#4#5#6#7 + \@@_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 + \or: \@@_parse_compare_auxii:NNNNN #2#3#4#5#2 + \else: #1 \@@_parse_compare_end:NNNNw #3#4#5#6#7 \fi: } -\cs_new:Npn \@@_parse_compare_expand:NNNNNw #1#2#3#4#5 +\cs_new:Npn \@@_parse_compare_auxii:NNNNN #1#2#3#4#5 { - \exp_after:wN \@@_parse_compare:NNNNNNw + \exp_after:wN \@@_parse_compare_auxi:NNNNNNN \exp_after:wN \prg_do_nothing: \exp_after:wN #1 \exp_after:wN #2 @@ -2504,11 +2506,12 @@ \exp_after:wN #5 \tex_romannumeral:D \exp_after:wN \@@_parse_expand:w } -\cs_new:Npn \@@_parse_compare_end:NNNN #1#2#3#4#5 \fi: +\cs_new:Npn \@@_parse_compare_end:NNNNw #1#2#3#4#5 \fi: { \fi: \exp_after:wN @ - \exp_after:wN \@@_parse_apply_compare:NwNNNNwN + \exp_after:wN \@@_parse_apply_compare:NwNNNNNwN + \exp_after:wN \c_one_fp \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 @@ -2516,26 +2519,146 @@ \tex_romannumeral:D \@@_parse_operand:Nw \c_seven \@@_parse_expand:w #5 } -\cs_new:Npn \@@_parse_apply_compare:NwNNNNwN #1 #2@ #3#4#5#6 #7@ #8 +\cs_new:Npn \@@_parse_apply_compare:NwNNNNNwN + #1 #2@ #3 #4#5#6#7 #8@ #9 { - \exp_after:wN \@@_parse_continue:NwN - \exp_after:wN #1 - \tex_romannumeral:D -`0 - \exp_after:wN \exp_after:wN - \exp_after:wN \exp_after:wN - \exp_after:wN \exp_after:wN - \if_case:w \@@_compare_back:ww #7 #2 \exp_stop_f: - #4 - \or: #5 - \or: #6 - \else: #3 - \fi: - \tex_romannumeral:D -`0 #8 #1 + \if_int_odd:w + \if_meaning:w \c_zero_fp #3 + \c_zero + \else: + \if_case:w \@@_compare_back:ww #8 #2 \exp_stop_f: + #5 \or: #6 \or: #7 \else: #4 + \fi: + \fi: + \exp_after:wN \@@_parse_apply_compare_aux:NNwN + \exp_after:wN \c_one_fp + \else: + \exp_after:wN \@@_parse_apply_compare_aux:NNwN + \exp_after:wN \c_zero_fp + \fi: + #1 #8 #9 + } +\cs_new:Npn \@@_parse_apply_compare_aux:NNwN #1 #2 #3; #4 + { + \if_meaning:w \@@_parse_compare:NNNNNNN #4 + \exp_after:wN \@@_parse_continue_compare:NNwNN + \exp_after:wN #1 + \exp_after:wN #2 + \tex_romannumeral:D -`0 + \@@_exp_after_o:w #3; + \tex_romannumeral:D -`0 + \else: + \exp_after:wN \@@_parse_continue:NwN + \exp_after:wN #2 + \tex_romannumeral:D -`0 + \exp_after:wN #1 + \tex_romannumeral:D -`0 + \fi: + #4 #2 + } +\cs_new:Npn \@@_parse_continue_compare:NNwNN #1#2 #3@ #4#5 + { #4 #2 #3@ #1 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Candidate: defining new \pkg{l3fp} functions} +% +% \begin{macro}[EXP]{\fp_function:Nw} +% This relies on the definition of the null character as a prefix +% operator with very specific semantics. +% \begin{macrocode} +\group_begin: + \char_set_catcode_other:N \^^@ + \cs_new:Npn \fp_function:Nw #1 { ^^@ ; { \exp_after:wN #1 } } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fp_new_function:Npn} +% \begin{macro}[aux]{\@@_function_args:Nwn} +% This relies on the definition of the null character as a prefix +% operator with very specific semantics. +% \begin{macrocode} +\group_begin: + \char_set_catcode_other:N \^^@ + \cs_new_protected:Npn \fp_new_function:Npn #1#2# + { + \cs_new:Npx #1 + { + ^^@ ; + { + \exp_not:N \exp_after:wN + \exp_not:N \@@_function_args:Nwn + \exp_not:N \exp_after:wN + \exp_not:c { @@_user_ \cs_to_str:N #1 } + \exp_not:N \__int_value:w + \int_eval:n { \tl_count:n {#2} / \c_two } + \exp_not:N \exp_after:wN ; + } + } + \cs_new:cpn { @@_user_ \cs_to_str:N #1 } #2 + } +\group_end: +\cs_new:Npn \@@_function_args:Nwn #1#2; #3 + { + \int_compare:nNnTF { \tl_count:n {#3} } = {#2} + { #1 #3 } + { + \__msg_kernel_expandable_error:nnnnn + { kernel } { fp-num-args } { #1() } {#2} {#2} + \c_nan_fp + } } % \end{macrocode} % \end{macro} % \end{macro} % +% \begingroup\catcode`^^@=12\relax % ^^A hack +% \begin{macro}[EXP, aux]{\@@_parse_prefix_^^@:Nw} +% \begin{macrocode} +\group_begin: + \char_set_catcode_other:N \^^@ + \cs_new:cpn { @@_parse_prefix_ ^^@ :Nw } #1 ; #2 + { + \exp_after:wN \@@_function_apply:NnwN + \exp_after:wN #1 + \exp_after:wN { #2 \exp_after:wN } + \tex_romannumeral:D + \@@_parse_operand:Nw \c_sixteen \@@_parse_expand:w + } +\group_end: +% \end{macrocode} +% \end{macro} +% \endgroup +% +% \begin{macro}[aux, EXP] +% { +% \@@_function_apply:NnwN, +% \@@_function_store:wwNwnn, +% \@@_function_store_end:wnnn +% } +% \begin{macrocode} +\cs_new:Npn \@@_function_apply:NnwN #1#2#3@#4 + { + \exp_after:wN \@@_exp_after_array_f:w + \tex_romannumeral:D -`0 + \@@_function_store:wwNwnn #3 + \s_@@_mark \@@_function_store:wwNwnn ; + \s_@@_mark \@@_function_store_end:wnnn + \s_@@_stop { } { } {#2} + \s_@@_stop + #4 #1 + } +\cs_new:Npn \@@_function_store:wwNwnn + #1; #2 \s_@@_mark #3#4 \s_@@_stop #5#6 + { #3 #2 \s_@@_mark #3#4 \s_@@_stop { #5 #6 } { { #1; } } } +\cs_new:Npn \@@_function_store_end:wnnn + #1 \s_@@_stop #2#3#4 + { \@@_parse:n { #4 {#2} } } +% \end{macrocode} +% \end{macro} +% % ^^A end[todo] % % \subsection{Messages} |