diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3int.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3int.dtx | 238 |
1 files changed, 114 insertions, 124 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index fa633515f99..fdae7fa1046 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3int.dtx 3460 2012-02-26 12:16:41Z will $ +\GetIdInfo$Id: l3int.dtx 3490 2012-03-04 01:00:53Z bruno $ {L3 Experimental integers} %</driver|package> %<*driver> @@ -208,6 +208,16 @@ % \meta{integer2}. % \end{function} % +% \begin{function}[EXP, pTF, added=2012-03-03] +% {\int_if_exist:N, \int_if_exist:c} +% \begin{syntax} +% \cs{int_if_exist_p:N} \meta{int} +% \cs{int_if_exist:NTF} \meta{int} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests whether the \meta{int} is currently defined. This does not +% check that the \meta{int} really is an integer variable. +% \end{function} +% % \section{Setting and incrementing integers} % % \begin{function}[updated = 2011-10-22] @@ -1056,9 +1066,9 @@ % Create a register if needed, otherwise clear it. % \begin{macrocode} \cs_new_protected:Npn \int_zero_new:N #1 - { \cs_if_exist:NTF #1 { \int_zero:N #1 } { \int_new:N #1 } } + { \int_if_exist:NTF #1 { \int_zero:N #1 } { \int_new:N #1 } } \cs_new_protected:Npn \int_gzero_new:N #1 - { \cs_if_exist:NTF #1 { \int_gzero:N #1 } { \int_new:N #1 } } + { \int_if_exist:NTF #1 { \int_gzero:N #1 } { \int_new:N #1 } } \cs_generate_variant:Nn \int_zero_new:N { c } \cs_generate_variant:Nn \int_gzero_new:N { c } % \end{macrocode} @@ -1082,6 +1092,20 @@ % \end{macro} % \end{macro} % +% \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 +% \end{macrocode} +% \end{macro} +% % \subsection{Setting and incrementing integers} % % \begin{macro}{\int_add:Nn, \int_add:cn} @@ -1167,152 +1191,118 @@ \cs_new_eq:NN \int_use:N \tex_the:D \cs_new:Npn \int_use:c #1 { \int_use:N \cs:w #1 \cs_end: } % \end{macrocode} -% \end{macro} +% \end{macro} % % \subsection{Integer expression conditionals} % -% \begin{macro}[pTF]{\int_compare:n} -% \begin{macro}[aux]{\int_compare_aux:nw} -% \begin{macro}[aux]{\int_compare_aux:Nw} -% \begin{macro}[aux]{int_compare_=:w} -% \begin{macro}[aux]{int_compare_==:w} -% \begin{macro}[aux]{int_compare_!=:w} -% \begin{macro}[aux]{int_compare_<:w} -% \begin{macro}[aux]{int_compare_>:w} -% \begin{macro}[aux]{int_compare_<=:w} -% \begin{macro}[aux]{int_compare_>=:w} -% Comparison tests using a simple syntax where only one set of braces -% is required and additional operators such as |!=| and |>=| are -% supported. First some notes on the idea behind this. We wish to -% support writing code like -% \begin{verbatim} -% \int_compare_p:n { 5 + \l_tmpa_int != 4 - \l_tmpb_int } -% \end{verbatim} -% In other words, we want to somehow add the missing \cs{int_eval:w} -% where required. We can start evaluating from the left using -% \cs{int_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. +% \begin{macro}[aux, EXP]{\kernel_compare_error:, \kernel_compare_error:NNw} +% Those functions are used for comparison tests which use a simple +% syntax where only one set of braces is required and additional +% operators such as |!=| and |>=| are supported. The tests first +% evaluate their left-hand side, with a trailing +% \cs{kernel_compare_error:}. This marker is normally not expanded, +% but if the relation symbol is missing from the test's argument, then +% the marker inserts |=| (and itself) after triggering the relevant +% \TeX{} error. If the first token which appears after evaluating and +% removing the left-hand side is not a known relation symbol, then a +% judiciously placed \cs{kernel_compare_error:Nw} gets expanded, +% cleaning up the end of the test and telling the user what the +% problem was. % \begin{macrocode} -\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF } - { \exp_after:wN \int_compare_aux:nw \int_value:w \int_eval:w #1 \q_stop } -% \end{macrocode} -% Then the next step is to figure out which relation we should use, so -% we have to somehow get rid of the first evaluation so that we can -% see what stopped it. \cs{int_to_roman:w} is handy here since its -% expansion given a non-positive number is \meta{null}. We therefore -% simply check if the first token of the left hand side evaluation is -% a minus. If not, we insert it and issue \cs{int_to_roman:w}, -% thereby ridding us of the left hand side evaluation. We do however -% save it for later. -% \begin{macrocode} -\cs_new:Npn \int_compare_aux:nw #1#2 \q_stop +\cs_new_protected_nopar:Npn \kernel_compare_error: { - \exp_after:wN \int_compare_aux:Nw - \int_to_roman:w - \if:w #1 - - \else: - - - \fi: - #1#2 \q_mark #1#2 \q_stop + \if_num:w \c_zero \c_zero \fi: + = + \kernel_compare_error: } -% \end{macrocode} -% This leaves the first relation symbol in front and assuming the -% right hand side has been input, at least one other token as well. We -% support the following forms: |=|, |<|, |>| and the extended |!=|, -% |==|, |<=| and |>=|. All the extended forms have an extra |=| so we -% check if that is present as well. Then use specific function to -% perform the test. -% \begin{macrocode} -\cs_new:Npn \int_compare_aux:Nw #1#2#3 \q_mark - { \use:c { int_compare_ #1 \if_meaning:w = #2 = \fi: :w } } -% \end{macrocode} -% The actual comparisons are then simple function calls, using the -% relation as delimiter for a delimited argument. -% Equality is easy: -% \begin{macrocode} -\cs_new:cpn { int_compare_=:w } #1 = #2 \q_stop +\cs_new:Npn \kernel_compare_error:Nw + #1#2 \prg_return_true: \else: \prg_return_false: \fi: { - \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \msg_expandable_kernel_error:nnn + { kernel } { unknown-comparison } {#1} + \prg_return_false: } % \end{macrocode} -% So is the one using |==| we just have to use |==| in the -% parameter text. +% \end{macro} +% +% \begin{macro}[pTF, EXP]{\int_compare:n} +% \begin{macro}[aux, EXP]{\int_compare_aux:Nw, \int_compare_aux:NNw} +% \begin{macro}[aux, EXP] +% { +% \int_compare_=:NNw, +% \int_compare_<:NNw, +% \int_compare_>:NNw, +% \int_compare_==:NNw, +% \int_compare_!=:NNw, +% \int_compare_<=:NNw, +% \int_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{int_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{int_eval_end:} will end the +% evaluation of the right-hand side. % \begin{macrocode} -\cs_new:cpn { int_compare_==:w } #1 == #2 \q_stop +\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF } { - \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end: + \exp_after:wN \int_compare_aux:Nw \int_use:N \int_eval:w #1 + \kernel_compare_error: \int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} -% Not equal is just about reversing the truth value. -% \begin{macrocode} -\cs_new:cpn { int_compare_!=:w } #1 != #2 \q_stop - { - \if_int_compare:w #1 = \int_eval:w #2 \int_eval_end: - \prg_return_false: - \else: - \prg_return_true: - \fi: - } -% \end{macrocode} -% Less than and greater than are also straight forward. +% We have just evaluated the left-hand side. To access the relation +% symbol, we remove the number by applying \cs{int_to_roman:w}, after +% making sure that the argument becomes non-positive: its roman +% numeral representation is then empty. The \cs{int_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{kernel_compare_error:Nw} +% raises an error. % \begin{macrocode} -\cs_new:cpn { int_compare_<:w } #1 < #2 \q_stop +\cs_new:Npn \int_compare_aux:Nw #1#2 \kernel_compare_error: { - \if_int_compare:w #1 < \int_eval:w #2 \int_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \exp_after:wN \int_compare_aux:NNw + \int_to_roman:w - 0 #2 ?? \q_mark + #1#2 } -\cs_new:cpn { int_compare_>:w } #1 > #2 \q_stop +\cs_new:Npn \int_compare_aux:NNw #1#2#3 \q_mark { - \if_int_compare:w #1 > \int_eval:w #2 \int_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: + \use:c { int_compare_ #1 \if_meaning:w = #2 = \fi: :NNw } + \kernel_compare_error:Nw #1 } % \end{macrocode} -% The less than or equal operation is just the opposite of the greater -% than operation. \emph{Vice versa} for less than or equal. +% The actual comparisons are then simple function calls, using the +% relation as delimiter for a delimited argument and discarding +% \cs{kernel_compare_error:Nw} \meta{token} responsible for error +% detection. % \begin{macrocode} -\cs_new:cpn { int_compare_<=:w } #1 <= #2 \q_stop - { - \if_int_compare:w #1 > \int_eval:w #2 \int_eval_end: - \prg_return_false: - \else: - \prg_return_true: - \fi: - } -\cs_new:cpn { int_compare_>=:w } #1 >= #2 \q_stop - { - \if_int_compare:w #1 < \int_eval:w #2 \int_eval_end: - \prg_return_false: - \else: - \prg_return_true: - \fi: - } +\cs_new:cpn { int_compare_=:NNw } #1#2#3 = + { \if_int_compare:w #3 = \int_eval:w } +\cs_new:cpn { int_compare_<:NNw } #1#2#3 < + { \if_int_compare:w #3 < \int_eval:w } +\cs_new:cpn { int_compare_>:NNw } #1#2#3 > + { \if_int_compare:w #3 > \int_eval:w } +\cs_new:cpn { int_compare_==:NNw } #1#2#3 == + { \if_int_compare:w #3 = \int_eval:w } +\cs_new:cpn { int_compare_!=:NNw } #1#2#3 != + { \reverse_if:N \if_int_compare:w #3 = \int_eval:w } +\cs_new:cpn { int_compare_<=:NNw } #1#2#3 <= + { \reverse_if:N \if_int_compare:w #3 > \int_eval:w } +\cs_new:cpn { int_compare_>=:NNw } #1#2#3 >= + { \reverse_if:N \if_int_compare:w #3 < \int_eval:w } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}[pTF]{\int_compare:nNn} % \UnitTested @@ -1946,16 +1936,16 @@ { \str_if_eq:nnTF {#2} { Q } { - \cs_if_exist:cF { c_int_from_roman_ #1 _int } + \int_if_exist:cF { c_int_from_roman_ #1 _int } { \int_from_roman_clean_up:w } + \use:c { c_int_from_roman_ #1 _int } #2 } { - \cs_if_exist:cF { c_int_from_roman_ #1 _int } + \int_if_exist:cF { c_int_from_roman_ #1 _int } { \int_from_roman_clean_up:w } - \cs_if_exist:cF { c_int_from_roman_ #2 _int } + \int_if_exist:cF { c_int_from_roman_ #2 _int } { \int_from_roman_clean_up:w } \int_compare:nNnTF { \use:c { c_int_from_roman_ #1 _int } } |