summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2014-08-26 17:33:09 +0000
committerKarl Berry <karl@freefriends.org>2014-08-26 17:33:09 +0000
commit6c4cd2ab2f8d1ebe3a051d700c3005d73eefe04c (patch)
tree16833d474c6532347c42dee6b34fa77aed22eca6 /Master/texmf-dist/source/latex/l3kernel/l3int.dtx
parent097e7dc0afa442be238a967b292237470680626e (diff)
l3 (26aug14)
git-svn-id: svn://tug.org/texlive/trunk@35045 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.dtx250
1 files changed, 95 insertions, 155 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
index dd98220454f..78d244e3845 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
@@ -37,7 +37,7 @@
\documentclass[full]{l3doc}
%</driver>
%<*driver|package>
-\GetIdInfo$Id: l3int.dtx 5197 2014-07-11 06:42:47Z joseph $
+\GetIdInfo$Id: l3int.dtx 5372 2014-08-25 02:01:41Z bruno $
{L3 Integers}
%</driver|package>
%<*driver>
@@ -713,14 +713,15 @@
% representation and leaves this in the input stream.
% \end{function}
%
-% \begin{function}[EXP]{\int_from_roman:n}
+% \begin{function}[updated = 2014-08-25, EXP]{\int_from_roman:n}
% \begin{syntax}
% \cs{int_from_roman:n} \Arg{roman numeral}
% \end{syntax}
% Converts the \meta{roman numeral} into the integer (base~$10$)
% representation and leaves this in the input stream. The
% \meta{roman numeral} may be in upper or lower case; if the numeral
-% is not valid then the resulting value will be $-1$.
+% contains letters besides |mdclxvi| or |MDCLXVI| then the resulting
+% value will be $-1$.
% \end{function}
%
% \begin{function}[EXP]{\int_from_base:nn}
@@ -744,7 +745,7 @@
%
% \begin{function}[added = 2011-11-22, updated = 2012-05-27]{\int_show:n}
% \begin{syntax}
-% \cs{int_show:n} \meta{integer expression}
+% \cs{int_show:n} \Arg{integer expression}
% \end{syntax}
% Displays the result of evaluating the \meta{integer expression}
% on the terminal.
@@ -974,10 +975,12 @@
% corrected to the \enquote{real} version here.
% \begin{macrocode}
%<*initex>
-\cs_set:Npn \int_eval:n #1 { \@@_value:w \@@_eval:w #1 \@@_eval_end: }
+\cs_set:Npn \int_eval:n #1
+ { \@@_value:w \@@_eval:w #1 \@@_eval_end: }
%</initex>
%<*package>
-\cs_new:Npn \int_eval:n #1 { \@@_value:w \@@_eval:w #1 \@@_eval_end: }
+\cs_new:Npn \int_eval:n #1
+ { \@@_value:w \@@_eval:w #1 \@@_eval_end: }
%</package>
% \end{macrocode}
% \end{macro}
@@ -1211,8 +1214,10 @@
% \begin{macro}[pTF]{\int_if_exist:N, \int_if_exist:c}
% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
% \begin{macrocode}
-\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 }
+\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}
%
@@ -2099,144 +2104,93 @@
%
% \subsection{Converting from other formats to integers}
%
-% \begin{macro}[int]{\@@_get_sign:n}
-% \begin{macro}[int]{\@@_get_digits:n}
-% \begin{macro}[aux]
-% {\@@_get_sign_and_digits:nNNN, \@@_get_sign_and_digits:oNNN}
-% Finding a number and its sign requires dealing with an arbitrary
-% list of |+| and |-| symbols. This is done by working through token
-% by token until there is something else at the start of the input.
-% The sign of the input is tracked by the first Boolean used by the
-% auxiliary function.
-% \begin{macrocode}
-\cs_new:Npn \@@_get_sign:n #1
- {
- \@@_get_sign_and_digits:nNNN {#1}
- \c_true_bool \c_true_bool \c_false_bool
- }
-\cs_new:Npn \@@_get_digits:n #1
- {
- \@@_get_sign_and_digits:nNNN {#1}
- \c_true_bool \c_false_bool \c_true_bool
- }
-% \end{macrocode}
-% The auxiliary loops through, finding sign tokens and removing them.
-% The sign itself is carried through as a flag.
+% \begin{macro}[aux,rEXP]{\@@_pass_signs:wn, \@@_pass_signs_end:wn}
+% Called as \cs{@@_pass_signs:wn} \meta{signs and digits} \cs{q_stop}
+% \Arg{code}, this function leaves in the input stream any sign it
+% finds, then inserts the \meta{code} before the first non-sign token
+% (and removes \cs{q_stop}). More precisely, it deletes any~|+| and
+% passes any~|-| to the input stream, hence should be called in an
+% integer expression.
% \begin{macrocode}
-\cs_new:Npn \@@_get_sign_and_digits:nNNN #1#2#3#4
+\cs_new:Npn \@@_pass_signs:wn #1
{
- \exp_args:Nf \tl_if_head_eq_charcode:nNTF {#1} -
- {
- \bool_if:NTF #2
- {
- \@@_get_sign_and_digits:oNNN
- { \use_none:n #1 } \c_false_bool #3#4
- }
- {
- \@@_get_sign_and_digits:oNNN
- { \use_none:n #1 } \c_true_bool #3#4
- }
- }
- {
- \exp_args:Nf \tl_if_head_eq_charcode:nNTF {#1} +
- { \@@_get_sign_and_digits:oNNN { \use_none:n #1 } #2#3#4 }
- {
- \bool_if:NT #3 { \bool_if:NF #2 - }
- \bool_if:NT #4 {#1}
- }
- }
+ \if:w + \if:w - \exp_not:N #1 + \fi: \exp_not:N #1
+ \exp_after:wN \@@_pass_signs:wn
+ \else:
+ \exp_after:wN \@@_pass_signs_end:wn
+ \exp_after:wN #1
+ \fi:
}
-\cs_generate_variant:Nn \@@_get_sign_and_digits:nNNN { o }
+\cs_new:Npn \@@_pass_signs_end:wn #1 \q_stop #2 { #2 #1 }
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\int_from_alph:n}
% \UnitTested
-% \begin{macro}[aux]{\@@_from_alph:n}
-% \begin{macro}[aux]{\@@_from_alph:nN}
-% \begin{macro}[aux]{\@@_from_alph:N}
-% The aim here is to iterate through the input, converting one letter at
-% a time to a number. The same approach is also used for base
-% conversion, but this needs a different final auxiliary.
+% \begin{macro}[aux]{\@@_from_alph:nN, \@@_from_alph:N}
+% First take care of signs then loop through the input using the
+% \texttt{recursion} quarks. The \cs{@@_from_alph:nN} auxiliary
+% collects in its first argument the value obtained so far, and the
+% auxiliary \cs{@@_from_alph:N} converts one letter to an expression
+% which evaluates to the correct number.
% \begin{macrocode}
\cs_new:Npn \int_from_alph:n #1
{
\int_eval:n
{
- \@@_get_sign:n {#1}
- \exp_args:Nf \@@_from_alph:n { \@@_get_digits:n {#1} }
+ \@@_pass_signs:wn #1
+ \q_stop { \@@_from_alph:nN { 0 } }
+ \q_recursion_tail \q_recursion_stop
}
}
-\cs_new:Npn \@@_from_alph:n #1
- { \@@_from_alph:nN { 0 } #1 \q_nil }
\cs_new:Npn \@@_from_alph:nN #1#2
{
- \quark_if_nil:NTF #2
- {#1}
- {
- \exp_args:Nf \@@_from_alph:nN
- { \int_eval:n { #1 * 26 + \@@_from_alph:N #2 } }
- }
+ \quark_if_recursion_tail_stop_do:Nn #2 {#1}
+ \exp_args:Nf \@@_from_alph:nN
+ { \int_eval:n { #1 * 26 + \@@_from_alph:N #2 } }
}
\cs_new:Npn \@@_from_alph:N #1
- { \int_eval:n { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } } }
+ { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } }
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\int_from_base:nn}
% \UnitTested
-% \begin{macro}[aux]{\@@_from_base:nn}
-% \begin{macro}[aux]{\@@_from_base:nnN}
-% \begin{macro}[aux]{\@@_from_base:N}
-% Conversion to base ten means stripping off the sign then iterating
-% through the input one token at a time. The total number is then added
-% up as the code loops.
+% \begin{macro}[aux]{\@@_from_base:nnN, \@@_from_base:N}
+% Leave the signs into the integer expression, then loop through
+% characters, collecting the value found so far in the first argument
+% of \cs{@@_from_base:nnN}. To convert a single character,
+% \cs{@@_from_base:N} checks first for digits, then distinguishes
+% lower from upper case letters, turning them into the appropriate
+% number. Note that this auxiliary does not use \cs{int_eval:n},
+% hence is not safe for general use.
% \begin{macrocode}
\cs_new:Npn \int_from_base:nn #1#2
{
\int_eval:n
{
- \@@_get_sign:n {#1}
- \exp_args:Nf \@@_from_base:nn
- { \@@_get_digits:n {#1} } {#2}
+ \@@_pass_signs:wn #1
+ \q_stop { \@@_from_base:nnN { 0 } {#2} }
+ \q_recursion_tail \q_recursion_stop
}
}
-\cs_new:Npn \@@_from_base:nn #1#2
- { \@@_from_base:nnN { 0 } { #2 } #1 \q_nil }
\cs_new:Npn \@@_from_base:nnN #1#2#3
{
- \quark_if_nil:NTF #3
- {#1}
- {
- \exp_args:Nf \@@_from_base:nnN
- { \int_eval:n { #1 * #2 + \@@_from_base:N #3 } }
- {#2}
- }
+ \quark_if_recursion_tail_stop_do:Nn #3 {#1}
+ \exp_args:Nf \@@_from_base:nnN
+ { \int_eval:n { #1 * #2 + \@@_from_base:N #3 } }
+ {#2}
}
-% \end{macrocode}
-% The conversion here will take lower or upper case letters and turn
-% them into the appropriate number, hence the two-part nature of the
-% function.
-% \begin{macrocode}
\cs_new:Npn \@@_from_base:N #1
{
\int_compare:nNnTF { `#1 } < { 58 }
{#1}
- {
- \int_eval:n
- { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } }
- }
+ { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\int_from_bin:n, \int_from_hex:n, \int_from_oct:n}
% \UnitTested
@@ -2285,63 +2239,53 @@
% \UnitTested
% \TestMissing{boundary cases / wrong input?}
% \begin{macro}[aux]{\@@_from_roman:NN}
-% \begin{macro}[aux]{\@@_from_roman_end:w}
-% \begin{macro}[aux]{\@@_from_roman_clean_up:w}
+% \begin{macro}[aux]{\@@_from_roman_error:w}
% The method here is to iterate through the input, finding the
% appropriate value for each letter and building up a sum. This is
-% then evaluated by \TeX{}.
+% then evaluated by \TeX{}. If any unknown letter is found, skip to
+% the closing parenthesis and insert |*0-1| afterwards, to replace the
+% value by $-1$.
% \begin{macrocode}
\cs_new:Npn \int_from_roman:n #1
{
- \tl_if_blank:nF {#1}
+ \int_eval:n
{
- \exp_after:wN \@@_from_roman_end:w
- \@@_value:w \@@_eval:w
- \@@_from_roman:NN #1 Q \q_stop
+ (
+ \c_zero
+ \exp_after:wN \@@_from_roman:NN \tl_to_str:n {#1}
+ \q_recursion_tail \q_recursion_tail \q_recursion_stop
+ )
}
}
\cs_new:Npn \@@_from_roman:NN #1#2
{
- \str_if_eq:nnTF {#1} { Q }
- {#1#2}
+ \quark_if_recursion_tail_stop:N #1
+ \int_if_exist:cF { c_@@_from_roman_ #1 _int }
+ { \@@_from_roman_error:w }
+ \quark_if_recursion_tail_stop_do:Nn #2
+ { + \use:c { c_@@_from_roman_ #1 _int } }
+ \int_if_exist:cF { c_@@_from_roman_ #2 _int }
+ { \@@_from_roman_error:w }
+ \int_compare:nNnTF
+ { \use:c { c_@@_from_roman_ #1 _int } }
+ <
+ { \use:c { c_@@_from_roman_ #2 _int } }
{
- \str_if_eq:nnTF {#2} { Q }
- {
- \int_if_exist:cF { c_@@_from_roman_ #1 _int }
- { \@@_from_roman_clean_up:w }
- +
- \use:c { c_@@_from_roman_ #1 _int }
- #2
- }
- {
- \int_if_exist:cF { c_@@_from_roman_ #1 _int }
- { \@@_from_roman_clean_up:w }
- \int_if_exist:cF { c_@@_from_roman_ #2 _int }
- { \@@_from_roman_clean_up:w }
- \int_compare:nNnTF
- { \use:c { c_@@_from_roman_ #1 _int } }
- <
- { \use:c { c_@@_from_roman_ #2 _int } }
- {
- + \use:c { c_@@_from_roman_ #2 _int }
- - \use:c { c_@@_from_roman_ #1 _int }
- \@@_from_roman:NN
- }
- {
- + \use:c { c_@@_from_roman_ #1 _int }
- \@@_from_roman:NN #2
- }
- }
+ + \use:c { c_@@_from_roman_ #2 _int }
+ - \use:c { c_@@_from_roman_ #1 _int }
+ \@@_from_roman:NN
+ }
+ {
+ + \use:c { c_@@_from_roman_ #1 _int }
+ \@@_from_roman:NN #2
}
}
-\cs_new:Npn \@@_from_roman_end:w #1 Q #2 \q_stop
- { \tl_if_empty:nTF {#2} {#1} {#2} }
-\cs_new:Npn \@@_from_roman_clean_up:w #1 Q { + 0 Q -1 }
+\cs_new:Npn \@@_from_roman_error:w #1 \q_recursion_stop #2
+ { #2 * \c_zero - \c_one }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \subsection{Viewing integer}
%
@@ -2370,22 +2314,15 @@
% This is needed early, and so is in \pkg{l3basics}
% \end{variable}
%
-% \begin{variable}{\c_zero}
-% Again, one in \pkg{l3basics} for obvious reasons.
-% \end{variable}
-%
-% \begin{variable}{\c_six, \c_seven}
-% \begin{variable}{\c_twelve}
-% \begin{variable}{\c_sixteen}
-% Once again, in \pkg{l3basics}.
-% \end{variable}
-% \end{variable}
+% \begin{variable}{\c_zero, \c_sixteen}
+% Again, in \pkg{l3basics}
% \end{variable}
%
% \begin{variable}
% {
-% \c_one, \c_two, \c_three, \c_four, \c_five, \c_eight, \c_nine, \c_ten,
-% \c_eleven, \c_thirteen, \c_fourteen, \c_fifteen,
+% \c_one, \c_two, \c_three, \c_four, \c_five, \c_six, \c_seven, \c_eight,
+% \c_nine, \c_ten, \c_eleven, \c_twelve, \c_thirteen, \c_fourteen,
+% \c_fifteen
% }
% Low-number values not previously defined.
% \begin{macrocode}
@@ -2394,10 +2331,13 @@
\int_const:Nn \c_three { 3 }
\int_const:Nn \c_four { 4 }
\int_const:Nn \c_five { 5 }
+\int_const:Nn \c_six { 6 }
+\int_const:Nn \c_seven { 7 }
\int_const:Nn \c_eight { 8 }
\int_const:Nn \c_nine { 9 }
\int_const:Nn \c_ten { 10 }
\int_const:Nn \c_eleven { 11 }
+\int_const:Nn \c_twelve { 12 }
\int_const:Nn \c_thirteen { 13 }
\int_const:Nn \c_fourteen { 14 }
\int_const:Nn \c_fifteen { 15 }