summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3int.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx238
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 } }