diff options
author | Karl Berry <karl@freefriends.org> | 2012-08-16 22:41:08 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-08-16 22:41:08 +0000 |
commit | ca1c73f9a8de69e467230c4a57ccf8b07cd275a9 (patch) | |
tree | 6272657307f73c14327d6b8bce5d6b7ff97c3f66 /Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx | |
parent | 22c251adda514ed7b453066de05b2f89707d0fe6 (diff) |
finish l3 update
git-svn-id: svn://tug.org/texlive/trunk@27427 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx | 238 |
1 files changed, 142 insertions, 96 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index 2e3a5e262ba..f3e3955c1b1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx @@ -35,7 +35,7 @@ %% % %<*driver> -\RequirePackage{l3names} +\RequirePackage{l3bootstrap} \GetIdInfo$Id: l3fp-traps.dtx 2479 2011-06-19 21:57:25Z bruno $ {L3 Floating-point exception trapping} \documentclass[full]{l3doc} @@ -87,27 +87,27 @@ % % \subsection{Flags} % -% \begin{macro}{\@@_flag_off:n} +% \begin{macro}{\fp_flag_off:n} % Function to turn a flag off. Simply undefine it. % \begin{macrocode} -\cs_new_protected:Npn \@@_flag_off:n #1 +\cs_new_protected:Npn \fp_flag_off:n #1 { \cs_set_eq:cN { l_@@_ #1 _flag_token } \c_undefined:D } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\@@_flag_on:n} +% \begin{macro}[EXP]{\fp_flag_on:n} % Function to turn a flag on expandably: use \TeX{}'s automatic % assignment to \cs{scan_stop:}. % \begin{macrocode} -\cs_new:Npn \@@_flag_on:n #1 +\cs_new:Npn \fp_flag_on:n #1 { \exp_args:Nc \use_none:n { l_@@_ #1 _flag_token } } % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP,pTF]{\@@_if_flag_on:n} +% \begin{macro}[EXP,pTF]{\fp_if_flag_on:n} % Returns true if the flag is on, false otherwise. % \begin{macrocode} -\prg_new_conditional:Npnn \@@_if_flag_on:n #1 { p , T , F , TF } +\prg_new_conditional:Npnn \fp_if_flag_on:n #1 { p , T , F , TF } { \if_cs_exist:w l_@@_ #1 _flag_token \cs_end: \prg_return_true: @@ -150,21 +150,22 @@ % The behaviour when an exception occurs is controlled by the % definitions of the functions % \begin{itemize} -% \item \cs{@@_invalid_operation:Nnw}, -% \item \cs{@@_invalid_operation:Nnww}, -% \item \cs{@@_division_by_zero:Nnw}, -% \item \cs{@@_division_by_zero:Nnww}, +% \item \cs{@@_invalid_operation:nnw}, +% \item \cs{@@_invalid_operation_o:Nww}, +% \item \cs{@@_array_invalid_operation_o:nw}, +% \item \cs{@@_division_by_zero_o:Nnw}, +% \item \cs{@@_division_by_zero_o:NNww}, % \item \cs{@@_overflow:w}, % \item \cs{@@_underflow:w}. % \end{itemize} % Rather than changing them directly, we provide a user interface as -% \cs{@@_trap:nn} \Arg{exception} \Arg{way of trapping}, where the +% \cs{fp_trap:nn} \Arg{exception} \Arg{way of trapping}, where the % \meta{way of trapping} is one of \texttt{error}, \texttt{flag}, or % \texttt{none}. % -% \begin{macro}{\@@_trap:nn} %^^A todo: user command => document +% \begin{macro}{\fp_trap:nn} %^^A todo: user command => document % \begin{macrocode} -\cs_new_protected:Npn \@@_trap:nn #1#2 +\cs_new_protected:Npn \fp_trap:nn #1#2 { \cs_if_exist_use:cF { @@_trap_#1_set_#2: } { @@ -188,6 +189,50 @@ % \@@_trap_invalid_operation_set_none: , % \@@_trap_invalid_operation_set:N , % } +% We provide three types of trapping for invalid operations: either +% produce an error and raise the relevant flag; or only raise the +% flag; or don't even raise the flag. In most cases, the function +% produces as a result its first argument, possibly with +% post-expansion. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_error: + { \@@_trap_invalid_operation_set:N \prg_do_nothing: } +\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_flag: + { \@@_trap_invalid_operation_set:N \use_none:nnnnn } +\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_none: + { \@@_trap_invalid_operation_set:N \use_none:nnnnnnn } +\cs_new_protected:Npn \@@_trap_invalid_operation_set:N #1 + { + \exp_args:Nno \use:n + { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3; } + { + #1 + \@@_error:nffn { invalid } {##2} { \@@_to_tl:w ##3; } { } + \fp_flag_on:n { invalid_operation } + ##1 + } + \exp_args:Nno \use:n + { \cs_set:Npn \@@_invalid_operation_o:Nww ##1##2; ##3; } + { + #1 + \@@_error:nffn { invalid-ii } + { \@@_to_tl:w ##2; } { \@@_to_tl:w ##3; } {##1} + \fp_flag_on:n { invalid_operation } + \exp_after:wN \c_nan_fp + } + \exp_args:Nno \use:n + { \cs_set:Npn \@@_array_invalid_operation_o:nw ##1##2@ } + { + #1 + \@@_error:nffn { invalid } + {##1} { \@@_array_to_clist:w ##2 @ } { } + \fp_flag_on:n { invalid_operation } + \exp_after:wN \c_nan_fp + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[aux] % { % \@@_trap_division_by_zero_set_error: , @@ -195,64 +240,40 @@ % \@@_trap_division_by_zero_set_none: , % \@@_trap_division_by_zero_set:N , % } -% \begin{macro}[aux]{\@@_trap_invalid_operation_set:Nnn} % We provide three types of trapping for invalid operations and % division by zero: either produce an error and raise the relevant % flag; or only raise the flag; or don't even raise the flag. In all % cases, the function must produce a result, namely its first % argument, $\pm\infty$ or \nan{}. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_error: - { \@@_trap_invalid_operation_set:N \prg_do_nothing: } -\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_flag: - { \@@_trap_invalid_operation_set:N \use_none:nn } -\cs_new_protected_nopar:Npn \@@_trap_invalid_operation_set_none: - { \@@_trap_invalid_operation_set:N \use_none:nnnn } -\cs_new_protected:Npn \@@_trap_invalid_operation_set:N #1 - { - \@@_trap_invalid_operation_set:Nnn #1 - { invalid_operation } { Invalid~operation~ } - } \cs_new_protected_nopar:Npn \@@_trap_division_by_zero_set_error: { \@@_trap_division_by_zero_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \@@_trap_division_by_zero_set_flag: - { \@@_trap_division_by_zero_set:N \use_none:nn } + { \@@_trap_division_by_zero_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \@@_trap_division_by_zero_set_none: - { \@@_trap_division_by_zero_set:N \use_none:nnnn } + { \@@_trap_division_by_zero_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_division_by_zero_set:N #1 { - \@@_trap_invalid_operation_set:Nnn #1 - { division_by_zero } { Division~by~zero~in~ } - } -\cs_new_protected:Npn \@@_trap_invalid_operation_set:Nnn #1#2#3 - { \exp_args:Nno \use:n - { \cs_set:cpn { @@_ #2 :Nnw } ##1##2##3; } + { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3; } { #1 - \@@_error:x { { #3 ##2 } ( \@@_to_tl:w ##3; ) } - \@@_flag_on:n {#2} + \@@_error:nffn { zero-div } {##2} { \@@_to_tl:w ##3; } { } + \fp_flag_on:n { division_by_zero } \exp_after:wN ##1 } \exp_args:Nno \use:n - { \cs_set:cpn { @@_ #2 :Nnww } ##1##2##3; ##4; } + { \cs_set:Npn \@@_division_by_zero_o:NNww ##1##2##3; ##4; } { #1 - \@@_error:x - { - {#3} - \tl_if_single:nTF {##2} - { ( \@@_to_tl:w ##3; ) ##2 ( \@@_to_tl:w ##4; ) } - { { ##2 ( } \@@_to_tl:w ##3; { , ~ } \@@_to_tl:w ##4; ) } - } - \@@_flag_on:n {#2} + \@@_error:nffn { zero-div-ii } + { \@@_to_tl:w ##3; } { \@@_to_tl:w ##4; } {##2} + \fp_flag_on:n { division_by_zero } \exp_after:wN ##1 } } % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}[aux] % { @@ -271,7 +292,7 @@ % \begin{macro}[aux]{\@@_trap_overflow_set:NnNn} % Just as for invalid operations and division by zero, the three % different behaviours are obtained by feeding \cs{prg_do_nothing:}, -% \cs{use_none:nn} or \cs{use_none:nnnn} to an auxiliary, with a +% \cs{use_none:nnnnn} or \cs{use_none:nnnnnnn} to an auxiliary, with a % further auxiliary common to overflow and underflow functions. In % most cases, the argument of the \cs{@@_overflow:w} and % \cs{@@_underflow:w} functions will be an (almost) normal number @@ -286,17 +307,17 @@ \cs_new_protected_nopar:Npn \@@_trap_overflow_set_error: { \@@_trap_overflow_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \@@_trap_overflow_set_flag: - { \@@_trap_overflow_set:N \use_none:nn } + { \@@_trap_overflow_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \@@_trap_overflow_set_none: - { \@@_trap_overflow_set:N \use_none:nnnn } + { \@@_trap_overflow_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_overflow_set:N #1 { \@@_trap_overflow_set:NnNn #1 { overflow } \@@_inf_fp:N { inf } } \cs_new_protected_nopar:Npn \@@_trap_underflow_set_error: { \@@_trap_underflow_set:N \prg_do_nothing: } \cs_new_protected_nopar:Npn \@@_trap_underflow_set_flag: - { \@@_trap_underflow_set:N \use_none:nn } + { \@@_trap_underflow_set:N \use_none:nnnnn } \cs_new_protected_nopar:Npn \@@_trap_underflow_set_none: - { \@@_trap_underflow_set:N \use_none:nnnn } + { \@@_trap_underflow_set:N \use_none:nnnnnnn } \cs_new_protected:Npn \@@_trap_underflow_set:N #1 { \@@_trap_overflow_set:NnNn #1 { underflow } \@@_zero_fp:N { 0 } } \cs_new_protected:Npn \@@_trap_overflow_set:NnNn #1#2#3#4 @@ -305,16 +326,12 @@ { \cs_set:cpn { @@_ #2 :w } \s_@@ \@@_chk:w ##1##2##3; } { #1 - \@@_error:x - { - \token_if_eq_meaning:NNTF 1 ##1 - { - \@@_to_tl:w \s_@@ \@@_chk:w ##1##2##3; ~ #2 ed ~ to ~ - \token_if_eq_meaning:NNF 0 ##2 { - } #4 . - } - { An~#2~occurred. } - } - \@@_flag_on:n {#2} + \@@_error:nffn + { flow \if_meaning:w 1 ##1 -to \fi: } + { \@@_to_tl:w \s_@@ \@@_chk:w ##1##2##3; } + { \token_if_eq_meaning:NNF 0 ##2 { - } #4 } + {#2} + \fp_flag_on:n {#2} #3 ##2 } } @@ -323,10 +340,11 @@ % \end{macro} % \end{macro} % -% \begin{macro}[int] +% \begin{macro}[int, EXP] % { -% \@@_invalid_operation:Nnw, \@@_invalid_operation:Nnww, -% \@@_division_by_zero:Nnw, \@@_division_by_zero:Nnww, +% \@@_invalid_operation:nnw, \@@_invalid_operation_o:Nww, +% \@@_array_invalid_operation_o:nw, +% \@@_division_by_zero_o:Nnw, \@@_division_by_zero_o:NNww, % \@@_overflow:w , \@@_underflow:w % } % Initialize the two control sequences (to log properly their @@ -334,55 +352,71 @@ % division by zero, overflow, and underflow to act silently on their % flag. % \begin{macrocode} -\cs_new_protected_nopar:Npn \@@_invalid_operation:Nnw { } -\cs_new_protected_nopar:Npn \@@_invalid_operation:Nnww { } -\cs_new_protected_nopar:Npn \@@_division_by_zero:Nnw { } -\cs_new_protected_nopar:Npn \@@_division_by_zero:Nnww { } -\cs_new_protected_nopar:Npn \@@_overflow:w { } -\cs_new_protected_nopar:Npn \@@_underflow:w { } -\@@_trap:nn { invalid_operation } { error } -\@@_trap:nn { division_by_zero } { flag } -\@@_trap:nn { overflow } { flag } -\@@_trap:nn { underflow } { flag } +\cs_new:Npn \@@_invalid_operation:nnw #1#2#3; { } +\cs_new:Npn \@@_invalid_operation_o:Nww #1#2; #3; { } +\cs_new:Npn \@@_array_invalid_operation_o:nw #1 #2 @ { } +\cs_new:Npn \@@_division_by_zero_o:Nnw #1#2#3; { } +\cs_new:Npn \@@_division_by_zero_o:NNww #1#2#3; #4; { } +\cs_new:Npn \@@_overflow:w { } +\cs_new:Npn \@@_underflow:w { } +\fp_trap:nn { invalid_operation } { error } +\fp_trap:nn { division_by_zero } { flag } +\fp_trap:nn { overflow } { flag } +\fp_trap:nn { underflow } { flag } % \end{macrocode} % \end{macro} % -%^^A todo: first arg of @@_invalid_operation:Nnw(w) should be an 'invalid' nan. +% \begin{macro}[int, EXP] +% {\@@_invalid_operation_o:nw} +% Convenient short-hands for returning \cs{c_nan_fp} for a unary or +% binary operation, and expanding after. +% \begin{macrocode} +\cs_new_nopar:Npn \@@_invalid_operation_o:nw + { \@@_invalid_operation:nnw { \exp_after:wN \c_nan_fp } } +% \end{macrocode} +% \end{macro} % % \subsection{Errors} % %^^A begin[todo] -% \begin{macro}[int, EXP]{\@@_error:n, \@@_error:x} -% The argument is fully expanded in a way similar to \texttt{x}-type -% expansion, but braced groups are simply copied, \cs{exp_not:n} does -% not work, spaces are ignored unless braced. The result of that -% weird (but useful) expansion is fed to \cs{__msg_expandable_error:n}. +% \begin{macro}[int, EXP]{\@@_error:nnnn, \@@_error:nffn} +% \begin{macrocode} +\cs_new:Npn \@@_error:nnnn #1 + { \__msg_kernel_expandable_error:nnnnn { kernel } { fp - #1 } } +\cs_generate_variant:Nn \@@_error:nnnn { nff } +% \end{macrocode} +% \end{macro} +% ^^A end[todo] +% +% ^^A todo: move \@@_array_to_clist:w elsewhere. +% \begin{macro}[int, EXP]{\@@_array_to_clist:w} +% \begin{macro}[aux, EXP]{\@@_array_to_clist_i:wwww, \@@_array_to_clist_ii:ww} +% Converts an array of floating point numbers to a comma-list. Does +% not work for empty arrays. % \begin{macrocode} -\cs_new_eq:NN \@@_error:n \__msg_expandable_error:n -\cs_new:Npn \@@_error:x #1 +\cs_new:Npn \@@_array_to_clist:w #1 @ { - \exp_args:Nf \__msg_expandable_error:n - { - \@@_error_loop:nwnN { \exp_stop_f: } #1 \prg_do_nothing: - \s_@@_mark { } \@@_error_loop:nwnN \s_@@_mark { } \@@_error_end:nw - } + \@@_array_to_clist_i:wwww ; + #1 + \@@_array_to_clist_ii:ww \s_@@ ; @ } -\cs_new:Npn \@@_error_end:nw #1#2 \@@_error_end:nw { #1 } -\cs_new:Npn \@@_error_loop:nwnN #1#2 \s_@@_mark #3 #4 +\cs_new:Npn \@@_array_to_clist_i:wwww #1; #2 \s_@@ #3; #4 @ { - \exp_after:wN #4 \tex_romannumeral:D -`0 #2 - \s_@@_mark { #3 #1 } #4 + \exp_after:wN \@@_array_to_clist_i:wwww + \tex_romannumeral:D -`0 \@@_to_tl:w \s_@@ #3 ; ; + #4 , ~ #1 @ } +\cs_new:Npn \@@_array_to_clist_ii:ww #1 ; , ~ , ~ #2 @ {#2} % \end{macrocode} % \end{macro} -% ^^A end[todo] +% \end{macro} % % \subsection{Messages} % % Some messages. % \begin{macrocode} -\msg_new:nnnn { kernel } { unknown-fpu-exception } +\__msg_kernel_new:nnnn { kernel } { unknown-fpu-exception } { The~FPU~exception~'#1'~is~not~known:~that~trap~will~never~be~triggered. } { The~only~exceptions~to~which~traps~can~be~attached~are \\ @@ -394,7 +428,7 @@ * ~ underflow } } -\msg_new:nnnn { kernel } { unknown-fpu-trap-type } +\__msg_kernel_new:nnnn { kernel } { unknown-fpu-trap-type } { The~FPU~trap~type~'#2'~is~not~known. } { The~trap~type~must~be~one~of \\ @@ -405,6 +439,18 @@ * ~ none } } +\__msg_kernel_new:nnn { kernel } { fp-flow } + { An ~ #3 ~ occurred. } +\__msg_kernel_new:nnn { kernel } { fp-flow-to } + { #1 ~ #3 ed ~ to ~ #2 . } +\__msg_kernel_new:nnn { kernel } { fp-zero-div } + { Division~by~zero~in~ #1 (#2) } +\__msg_kernel_new:nnn { kernel } { fp-zero-div-ii } + { Division~by~zero~in~ (#1) #3 (#2) } +\__msg_kernel_new:nnn { kernel } { fp-invalid } + { Invalid~operation~ #1 (#2) } +\__msg_kernel_new:nnn { kernel } { fp-invalid-ii } + { Invalid~operation~ (#1) #3 (#2) } % \end{macrocode} % % \begin{macrocode} @@ -415,4 +461,4 @@ % % \PrintChanges % -% \PrintIndex
\ No newline at end of file +% \PrintIndex |