diff options
author | Karl Berry <karl@freefriends.org> | 2013-03-12 22:38:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2013-03-12 22:38:22 +0000 |
commit | 574c4946ce553944c797750da25ba8844775996f (patch) | |
tree | 9ea4729ca09c49a4564d99d9134a5417eb7b2af3 /Master/texmf-dist/source/latex/l3kernel/l3int.dtx | |
parent | 5c30ca128a813719715e012a0d72c1ccaba2d811 (diff) |
latex3 (12mar13)
git-svn-id: svn://tug.org/texlive/trunk@29361 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3int.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3int.dtx | 219 |
1 files changed, 150 insertions, 69 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index e67616a2f7d..dcea709ebbc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3int.dtx Copyright (C) 1990-2012 The LaTeX3 Project +%% File: l3int.dtx Copyright (C) 1990-2013 The LaTeX3 Project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3bootstrap} -\GetIdInfo$Id: l3int.dtx 4237 2012-09-26 10:18:58Z bruno $ +\GetIdInfo$Id: l3int.dtx 4444 2013-01-13 20:27:20Z bruno $ {L3 Integers} %</driver|package> %<*driver> @@ -300,16 +300,36 @@ % \end{center} % \end{function} % -% \begin{function}[EXP,pTF]{\int_compare:n} +% \begin{function}[updated = 2013-01-13, EXP, pTF]{\int_compare:n} % \begin{syntax} -% \cs{int_compare_p:n} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \\ +% \cs{int_compare_p:n} \\ +% ~~\{ \\ +% ~~~~\meta{intexpr_1} \meta{relation_1} \\ +% ~~~~\ldots{} \\ +% ~~~~\meta{intexpr_N} \meta{relation_N} \\ +% ~~~~\meta{intexpr_{N+1}} \\ +% ~~\} \\ % \cs{int_compare:nTF} -% ~~\{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} +% ~~\{ \\ +% ~~~~\meta{intexpr_1} \meta{relation_1} \\ +% ~~~~\ldots{} \\ +% ~~~~\meta{intexpr_N} \meta{relation_N} \\ +% ~~~~\meta{intexpr_{N+1}} \\ +% ~~\} \\ % ~~\Arg{true code} \Arg{false code} % \end{syntax} -% This function first evaluates each of the \meta{integer expressions} -% as described for \cs{int_eval:n}. The two results are then -% compared using the \meta{relation}: +% This function evaluates the \meta{integer expressions} as described +% for \cs{int_eval:n} and compares consecutive result using the +% corresponding \meta{relation}, namely it compares \meta{intexpr_1} +% and \meta{intexpr_2} using the \meta{relation_1}, then +% \meta{intexpr_2} and \meta{intexpr_3} using the \meta{relation_2}, +% until finally comparing \meta{intexpr_N} and \meta{intexpr_{N+1}} +% using the \meta{relation_N}. The test yields \texttt{true} if all +% comparisons are \texttt{true}. Each \meta{integer expression} is +% evaluated only once, and the evaluation is lazy, in the sense that +% if one comparison is \texttt{false}, then no other \meta{integer +% expression} is evaluated and no other comparison is performed. +% The \meta{relations} can be any of the following: % \begin{center} % \begin{tabular}{ll} % Equal & |=| or |==| \\ @@ -413,35 +433,35 @@ % \texttt{false}. % \end{function} % -% \begin{function}[rEXP]{\int_do_until:nn} +% \begin{function}[updated = 2013-01-13, rEXP]{\int_do_until:nn} % \begin{syntax} -% \cs{int_do_until:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_do_until:nn} \Arg{integer relation} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and -% then evaluates the relationship between the two -% \meta{integer expressions} as described for \cs{int_compare:nTF}. +% then evaluates the \meta{integer relation} +% as described for \cs{int_compare:nTF}. % If the test is \texttt{false} then the \meta{code} will be inserted % into the input stream again and a loop will occur until the % \meta{relation} is \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\int_do_while:nn} +% \begin{function}[updated = 2013-01-13, rEXP]{\int_do_while:nn} % \begin{syntax} -% \cs{int_do_while:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_do_while:nn} \Arg{integer relation} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and -% then evaluates the relationship between the two -% \meta{integer expressions} as described for \cs{int_compare:nTF}. +% then evaluates the \meta{integer relation} +% as described for \cs{int_compare:nTF}. % If the test is \texttt{true} then the \meta{code} will be inserted % into the input stream again and a loop will occur until the % \meta{relation} is \texttt{false}. % \end{function} % -% \begin{function}[rEXP]{\int_until_do:nn} +% \begin{function}[updated = 2013-01-13, rEXP]{\int_until_do:nn} % \begin{syntax} -% \cs{int_until_do:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_until_do:nn} \Arg{integer_relation} \Arg{code} % \end{syntax} -% Evaluates the relationship between the two \meta{integer expressions} +% Evaluates the \meta{integer relation} % as described for \cs{int_compare:nTF}, and then places the % \meta{code} in the input stream if the \meta{relation} is % \texttt{false}. After the \meta{code} has been processed by \TeX{} the @@ -449,11 +469,11 @@ % \texttt{true}. % \end{function} % -% \begin{function}[rEXP]{\int_while_do:nn} +% \begin{function}[updated = 2013-01-13, rEXP]{\int_while_do:nn} % \begin{syntax} -% \cs{int_while_do:nn} \{ \meta{intexpr_1} \meta{relation} \meta{intexpr_2} \} \Arg{code} +% \cs{int_while_do:nn} \Arg{integer relation} \Arg{code} % \end{syntax} -% Evaluates the relationship between the two \meta{integer expressions} +% Evaluates the \meta{integer relation} % as described for \cs{int_compare:nTF}, and then places the % \meta{code} in the input stream if the \meta{relation} is % \texttt{true}. After the \meta{code} has been processed by \TeX{} the @@ -591,7 +611,7 @@ % % \begin{function}[updated = 2011-09-17, EXP]{\int_to_hexadecimal:n} % \begin{syntax} -% \cs{int_to_binary:n} \Arg{integer expression} +% \cs{int_to_hexadecimal:n} \Arg{integer expression} % \end{syntax} % Calculates the value of the \meta{integer expression} and places % the hexadecimal (base~$16$) representation of the result in the @@ -1167,14 +1187,8 @@ % \begin{macro}[pTF]{\int_if_exist:N, \int_if_exist:c} % Copies of the \texttt{cs} functions defined in \pkg{l3basics}. % \begin{macrocode} -\cs_new_eq:NN \int_if_exist:NTF \cs_if_exist:NTF -\cs_new_eq:NN \int_if_exist:NT \cs_if_exist:NT -\cs_new_eq:NN \int_if_exist:NF \cs_if_exist:NF -\cs_new_eq:NN \int_if_exist_p:N \cs_if_exist_p:N -\cs_new_eq:NN \int_if_exist:cTF \cs_if_exist:cTF -\cs_new_eq:NN \int_if_exist:cT \cs_if_exist:cT -\cs_new_eq:NN \int_if_exist:cF \cs_if_exist:cF -\cs_new_eq:NN \int_if_exist_p:c \cs_if_exist_p:c +\prg_new_eq_conditional:NNn \int_if_exist:N \cs_if_exist:N { TF , T , F , p } +\prg_new_eq_conditional:NNn \int_if_exist:c \cs_if_exist:c { TF , T , F , p } % \end{macrocode} % \end{macro} % @@ -1288,8 +1302,10 @@ \__prg_compare_error: } \cs_new:Npn \__prg_compare_error:Nw - #1#2 \prg_return_true: \else: \prg_return_false: \fi: + #1#2 \q_stop { + { } + \c_zero \fi: \__msg_kernel_expandable_error:nnn { kernel } { unknown-comparison } {#1} \prg_return_false: @@ -1298,9 +1314,11 @@ % \end{macro} % % \begin{macro}[pTF, EXP]{\int_compare:n} -% \begin{macro}[aux, EXP]{\@@_compare_aux:Nw, \@@_compare_aux:NNw} +% \begin{macro}[aux, EXP] +% {\@@_compare:w, \@@_compare:Nw, \@@_compare:NNw, \@@_compare:nnN} % \begin{macro}[aux, EXP] % { +% \@@_compare_end_=:NNw, % \@@_compare_=:NNw, % \@@_compare_<:NNw, % \@@_compare_>:NNw, @@ -1310,67 +1328,122 @@ % \@@_compare_>=:NNw % } % Comparison tests using a simple syntax where only one set of braces -% is required and additional operators such as |!=| and |>=| are -% supported. We can start evaluating from the left using -% \cs{@@_eval:w}, and we know that since the relation symbols |<|, -% |>|, |=| and |!| are not allowed in such expressions, they will -% terminate the expression. Therefore, we first let \TeX{} evaluate -% this left hand side of the (in)equality. We also insert at that -% stage the end of the test: \cs{@@_eval_end:} will end the -% evaluation of the right-hand side. +% is required, additional operators such as |!=| and |>=| are +% supported, and multiple comparisons can be performed at once, for +% instance |0 < 5 <= 1|. The idea is to loop through the argument, +% finding one operand at a time, and comparing it to the previous one. +% The looping auxiliary \cs{@@_compare:Nw} reads one \meta{operand} +% and one \meta{comparison} symbol, and leaves roughly +% \begin{quote} +% \meta{operand} \cs{prg_return_false:} \cs{fi:} \\ +% \cs{reverse_if:N} \cs{if_int_compare:w} \meta{operand} \meta{comparison} \\ +% \cs{@@_compare:Nw} +% \end{quote} +% in the input stream. Each call to this auxiliary provides the +% second operand of the last call's \cs{if_int_compare:w}. If one of +% the \meta{comparisons} is \texttt{false}, the \texttt{true} branch +% of the \TeX{} conditional is taken (because of \cs{reverse_if:N}), +% immediately returning \texttt{false} as the result of the test. +% There is no \TeX{} conditional waiting the first operand, so we add +% an \cs{if_false:} and expand by hand with \cs{@@_value:w}, thus +% skipping \cs{prg_return_false:} on the first iteration. +% +% Before starting the loop, the first step is to make sure that there +% is at least one relation symbol. We first let \TeX{} evaluate this +% left hand side of the (in)equality using \cs{@@_eval:w}. Since the +% relation symbols |<|, |>|, |=| and |!| are not allowed in integer +% expressions, they will terminate it. If the argument contains no +% relation symbol, \cs{__prg_compare_error:} is expanded, +% inserting~|=| and itself after an error. In all cases, +% \cs{@@_compare:w} receives as its argument an integer, a relation +% symbol, and some more tokens. We then setup the loop, which will be +% ended by the two odd-looking items |e| and |{=nd_}|, with a trailing +% \cs{q_stop} used to grab the entire argument when necessary. % \begin{macrocode} \prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF } { - \exp_after:wN \@@_compare_aux:Nw \int_use:N \@@_eval:w #1 - \__prg_compare_error: \@@_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \exp_after:wN \@@_compare:w + \int_use:N \@@_eval:w #1 \__prg_compare_error: + } +\cs_new:Npn \@@_compare:w #1 \__prg_compare_error: + { + \exp_after:wN \if_false: \@@_value:w + \@@_compare:Nw #1 e { = nd_ } \q_stop } % \end{macrocode} -% We have just evaluated the left-hand side. To access the relation -% symbol, we remove the number by applying \cs{@@_to_roman:w}, after -% making sure that the argument becomes non-positive: its roman -% numeral representation is then empty. The \cs{@@_compare_aux:NNw} -% auxiliary then probes the first two tokens to determine the relation -% symbol, building a control sequence from it. All the extended forms -% have an extra |=| hence the test for that as a second token. If the -% relation symbol is unknown, then the control sequence is turned by -% \TeX{} into \cs{scan_stop:}, and \cs{__prg_compare_error:Nw} -% raises an error. +% The goal here is to find an \meta{operand} and a \meta{comparison}. +% The \meta{operand} is already evaluated, but we cannot yet grab it +% as an argument. To access the following relation symbol, we remove +% the number by applying \cs{@@_to_roman:w}, after making sure that +% the argument becomes non-positive: its roman numeral representation +% is then empty. Then probe the first two tokens with +% \cs{@@_compare:NNw} to determine the relation symbol, building a +% control sequence from it. All the extended forms have an extra |=| +% hence the test for that as a second token. If the relation symbol +% is unknown, then the control sequence is turned by \TeX{} into +% \cs{scan_stop:}, ignored thanks to \tn{unexpanded}, and +% \cs{__prg_compare_error:Nw} raises an error. % \begin{macrocode} -\cs_new:Npn \@@_compare_aux:Nw #1#2 \__prg_compare_error: +\cs_new:Npn \@@_compare:Nw #1#2 \q_stop { - \exp_after:wN \@@_compare_aux:NNw - \@@_to_roman:w - 0 #2 ?? \q_mark - #1#2 + \exp_after:wN \@@_compare:NNw + \@@_to_roman:w - 0 #2 \q_mark + #1#2 \q_stop } -\cs_new:Npn \@@_compare_aux:NNw #1#2#3 \q_mark +\cs_new:Npn \@@_compare:NNw #1#2#3 \q_mark { + \etex_unexpanded:D \use:c { @@_compare_ #1 \if_meaning:w = #2 = \fi: :NNw } \__prg_compare_error:Nw #1 } % \end{macrocode} +% When the last \meta{operand} is seen, \cs{@@_compare:NNw} receives +% |e| and |=nd_| as arguments, hence calling +% \cs{@@_compare_end_=:NNw} to end the loop: return the result of the +% last comparison (involving the operand that we just found). When a +% normal relation is found, the appropriate auxiliary calls +% \cs{@@_compare:nnN} where |#1| is \cs{if_int_compare:w} or +% \cs{reverse_if:N} \cs{if_int_compare:w}, |#2| is the \meta{operand}, +% and |#3| is one of |<|, |=|, or~|>|. As announced earlier, we leave +% the \meta{operand} for the previous conditional. If this +% conditional is true the result of the test is known, so we remove +% all tokens and return \texttt{false}. Otherwise, we apply the +% conditional |#1| to the \meta{operand} |#2| and the comparison |#3|, +% and call \cs{@@_compare:Nw} to look for additional operands, after +% evaluating the following expression. +% \begin{macrocode} +\cs_new:cpn { @@_compare_end_=:NNw } #1#2#3 e #4 \q_stop + { + {#3} \exp_stop_f: + \prg_return_false: \else: \prg_return_true: \fi: + } +\cs_new:Npn \@@_compare:nnN #1#2#3 + { + {#2} \exp_stop_f: + \prg_return_false: \exp_after:wN \use_none_delimit_by_q_stop:w + \fi: + #1 #2 #3 \exp_after:wN \@@_compare:Nw \@@_value:w \@@_eval:w + } +% \end{macrocode} % The actual comparisons are then simple function calls, using the % relation as delimiter for a delimited argument and discarding % \cs{__prg_compare_error:Nw} \meta{token} responsible for error % detection. % \begin{macrocode} \cs_new:cpn { @@_compare_=:NNw } #1#2#3 = - { \if_int_compare:w #3 = \@@_eval:w } + { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} = } \cs_new:cpn { @@_compare_<:NNw } #1#2#3 < - { \if_int_compare:w #3 < \@@_eval:w } + { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} < } \cs_new:cpn { @@_compare_>:NNw } #1#2#3 > - { \if_int_compare:w #3 > \@@_eval:w } + { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} > } \cs_new:cpn { @@_compare_==:NNw } #1#2#3 == - { \if_int_compare:w #3 = \@@_eval:w } + { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} = } \cs_new:cpn { @@_compare_!=:NNw } #1#2#3 != - { \reverse_if:N \if_int_compare:w #3 = \@@_eval:w } + { \@@_compare:nnN { \if_int_compare:w } {#3} = } \cs_new:cpn { @@_compare_<=:NNw } #1#2#3 <= - { \reverse_if:N \if_int_compare:w #3 > \@@_eval:w } + { \@@_compare:nnN { \if_int_compare:w } {#3} > } \cs_new:cpn { @@_compare_>=:NNw } #1#2#3 >= - { \reverse_if:N \if_int_compare:w #3 < \@@_eval:w } + { \@@_compare:nnN { \if_int_compare:w } {#3} < } % \end{macrocode} % \end{macro} % \end{macro} @@ -2335,29 +2408,37 @@ % \begin{macro}{\if_num:w} % Deprecated 2012-05-30 for removal after 2012-11-30. % \begin{macrocode} +%<*deprecated> \cs_new_eq:NN \if_num:w \if_int_compare:w +%</deprecated> % \end{macrocode} % \end{macro} % % \begin{variable}{\l_tmpc_int} % Deprecated 2012-07-04 for removal after 2012-12-31. % \begin{macrocode} +%<*deprecated> \int_new:N \l_tmpc_int +%</deprecated> % \end{macrocode} % \end{variable} % % \begin{macro}{\int_eval:w, \int_eval_end:} % Deprecated 2012-07-13 for removal after 2012-12-31. % \begin{macrocode} +%<*deprecated> \cs_new_eq:NN \int_eval:w \@@_eval:w \cs_new_eq:NN \int_eval_end: \@@_eval_end: +%</deprecated> % \end{macrocode} % \end{macro} % % \begin{macro}{\int_value:w} % Deprecated 2012-07-14 for removal after 2012-12-31. % \begin{macrocode} +%<*deprecated> \cs_new_eq:NN \int_value:w \@@_value:w +%</deprecated> % \end{macrocode} % \end{macro} % |