summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx149
1 files changed, 96 insertions, 53 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
index 6acdf09e1af..db486f01c0d 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx
@@ -41,7 +41,7 @@
% }^^A
% }
%
-% \date{Released 2018/03/05}
+% \date{Released 2018-04-30}
%
% \maketitle
%
@@ -63,6 +63,20 @@
%
% ^^A todo: make sanitize and pack more homogeneous between modules.
%
+% \subsection{Access to primitives}
+%
+% \begin{macro}{\@@_int_eval:w, \@@_int_eval_end:, \@@_int_to_roman:w}
+% Largely for performance reasons, we need to directly access primitives
+% rather than use \cs{int_eval:n}. This happens \emph{a lot}, so we
+% use private names. The same is true for \tn{romannumeral}, although it
+% is used much less widely.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_int_eval:w \etex_numexpr:D
+\cs_new_eq:NN \@@_int_eval_end: \scan_stop:
+\cs_new_eq:NN \@@_int_to_roman:w \tex_romannumeral:D
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Internal representation}
%
% Internally, a floating point number \meta{X} is a
@@ -223,7 +237,7 @@
% However, when typeset, \cs{s_@@} does nothing, and \cs{@@_chk:w} is
% expanded. We define \cs{@@_chk:w} to produce an error.
% \begin{macrocode}
-\__scan_new:N \s_@@
+\scan_new:N \s_@@
\cs_new_protected:Npn \@@_chk:w #1 ;
{ \@@_misused:n { \s_@@ \@@_chk:w #1 ; } }
% \end{macrocode}
@@ -232,8 +246,8 @@
% \begin{macro}{\s_@@_mark, \s_@@_stop}
% Aliases of \cs{tex_relax:D}, used to terminate expressions.
% \begin{macrocode}
-\__scan_new:N \s_@@_mark
-\__scan_new:N \s_@@_stop
+\scan_new:N \s_@@_mark
+\scan_new:N \s_@@_stop
% \end{macrocode}
% \end{macro}
%
@@ -245,11 +259,11 @@
% A couple of scan marks used to indicate where special floating point
% numbers come from.
% \begin{macrocode}
-\__scan_new:N \s_@@_invalid
-\__scan_new:N \s_@@_underflow
-\__scan_new:N \s_@@_overflow
-\__scan_new:N \s_@@_division
-\__scan_new:N \s_@@_exact
+\scan_new:N \s_@@_invalid
+\scan_new:N \s_@@_underflow
+\scan_new:N \s_@@_overflow
+\scan_new:N \s_@@_division
+\scan_new:N \s_@@_exact
% \end{macrocode}
% \end{macro}
%
@@ -344,12 +358,12 @@
% \end{macro}
%
% \begin{macro}[EXP]{\@@_neg_sign:N}
-% When appearing in an integer expression or after \cs{__int_value:w},
+% When appearing in an integer expression or after \cs{int_value:w},
% this expands to the sign opposite to |#1|, namely $0$ (positive) is
% turned to $2$ (negative), $1$ (\texttt{nan}) to $1$, and $2$ to $0$.
% \begin{macrocode}
\cs_new:Npn \@@_neg_sign:N #1
- { \__int_eval:w 2 - #1 \__int_eval_end: }
+ { \@@_int_eval:w 2 - #1 \@@_int_eval_end: }
% \end{macrocode}
% \end{macro}
%
@@ -454,11 +468,11 @@
{
\exp_after:wN \@@_exp_after_normal:Nwwwww
\exp_after:wN #2
- \__int_value:w #3 \exp_after:wN ;
- \__int_value:w 1 #4 \exp_after:wN ;
- \__int_value:w 1 #5 \exp_after:wN ;
- \__int_value:w 1 #6 \exp_after:wN ;
- \__int_value:w 1 #7 \exp_after:wN ; #1
+ \int_value:w #3 \exp_after:wN ;
+ \int_value:w 1 #4 \exp_after:wN ;
+ \int_value:w 1 #5 \exp_after:wN ;
+ \int_value:w 1 #6 \exp_after:wN ;
+ \int_value:w 1 #7 \exp_after:wN ; #1
}
\cs_new:Npn \@@_exp_after_normal:Nwwwww
#1 #2; 1 #3 ; 1 #4 ; 1 #5 ; 1 #6 ;
@@ -477,7 +491,7 @@
% an error, just like usual floating point numbers.
% Tuples may have zero or one element.
% \begin{macrocode}
-\__scan_new:N \s_@@_tuple
+\scan_new:N \s_@@_tuple
\cs_new_protected:Npn \@@_tuple_chk:w #1 ;
{ \@@_misused:n { \s_@@_tuple \@@_tuple_chk:w #1 ; } }
\tl_const:Nn \c_@@_empty_tuple_fp
@@ -497,10 +511,10 @@
{ \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w {#1} ; }
\cs_new:Npn \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w #1 ;
{
- \__int_value:w \__int_eval:w 0
- \@@_tuple_count_loop:Nw #1 { ? \__prg_break: } ;
- \__prg_break_point:
- \__int_eval_end:
+ \int_value:w \@@_int_eval:w 0
+ \@@_tuple_count_loop:Nw #1 { ? \prg_break: } ;
+ \prg_break_point:
+ \@@_int_eval_end:
}
\cs_new:Npn \@@_tuple_count_loop:Nw #1#2;
{ \use_none:n #1 + 1 \@@_tuple_count_loop:Nw }
@@ -510,7 +524,7 @@
%
% \begin{macro}[EXP]{\@@_if_type_fp:NTwFw}
% Used as \cs{@@_if_type_fp:NTwFw} \meta{marker} \Arg{true code}
-% \cs{s__fp} \Arg{false code} \cs{q_stop}, this test whether the
+% \cs{s_@@} \Arg{false code} \cs{q_stop}, this test whether the
% \meta{marker} is \cs{s_@@} or not and runs the appropriate
% \meta{code}. The very unusual syntax is for optimization purposes
% as that function is used for all floating point operations.
@@ -524,14 +538,14 @@
% \begin{macrocode}
\cs_new:Npn \@@_array_if_all_fp:nTF #1
{
- \@@_array_if_all_fp_loop:w #1 { \s_@@ \__prg_break: } ;
- \__prg_break_point: \use_i:nn
+ \@@_array_if_all_fp_loop:w #1 { \s_@@ \prg_break: } ;
+ \prg_break_point: \use_i:nn
}
\cs_new:Npn \@@_array_if_all_fp_loop:w #1#2 ;
{
\@@_if_type_fp:NTwFw
#1 \@@_array_if_all_fp_loop:w
- \s_@@ { \__prg_break:n \use_iii:nnn }
+ \s_@@ { \prg_break:n \use_iii:nnn }
\q_stop
}
% \end{macrocode}
@@ -557,12 +571,9 @@
\exp_not:N \token_to_str:N #1 \exp_not:N \q_mark
\tl_to_str:n { s_@@ _? } \exp_not:N \q_mark \exp_not:N \q_stop
}
-\use:x
- {
- \cs_new:Npn \exp_not:N \@@_type_from_scan:w
- ##1 \tl_to_str:n { s_@@ } ##2 \exp_not:N \q_mark ##3 \exp_not:N \q_stop
- {##2}
- }
+\exp_last_unbraced:NNNNo
+ \cs_new:Npn \@@_type_from_scan:w #1
+ { \tl_to_str:n { s_@@ } } #2 \q_mark #3 \q_stop {#2}
% \end{macrocode}
% \end{macro}
%
@@ -645,7 +656,8 @@
% \begin{macrocode}
\cs_new:Npn \@@_exp_after_tuple_o:w
{ \@@_exp_after_tuple_f:nw { \exp_after:wN \exp_stop_f: } }
-\cs_new:Npn \@@_exp_after_tuple_f:nw #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+\cs_new:Npn \@@_exp_after_tuple_f:nw
+ #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
{
\exp_after:wN \s_@@_tuple
\exp_after:wN \@@_tuple_chk:w
@@ -670,7 +682,7 @@
% \begin{verbatim}
% \cs_new:Npn \pack:NNNNNw #1 #2#3#4#5 #6; { {#2#3#4#5} {#6} }
% \exp_after:wN \pack:NNNNNw
-% \__int_value:w \__int_eval:w 1 0000 0000 + #1 ;
+% \__fp_int_value:w \__fp_int_eval:w 1 0000 0000 + #1 ;
% \end{verbatim}
% The idea is that adding $10^8$ to the number ensures that it has
% exactly $9$ digits, and can then easily find which digits correspond
@@ -685,19 +697,19 @@
% 6677\,8899$. With simplified names, we would do
% \begin{verbatim}
% \exp_after:wN \post_processing:w
-% \__int_value:w \__int_eval:w - 5 0000
+% \__fp_int_value:w \__fp_int_eval:w - 5 0000
% \exp_after:wN \pack:NNNNNw
-% \__int_value:w \__int_eval:w 4 9995 0000
+% \__fp_int_value:w \__fp_int_eval:w 4 9995 0000
% + 12345 * 6677
% \exp_after:wN \pack:NNNNNw
-% \__int_value:w \__int_eval:w 5 0000 0000
+% \__fp_int_value:w \__fp_int_eval:w 5 0000 0000
% + 12345 * 8899 ;
% \end{verbatim}
-% The \cs{exp_after:wN} triggers |\__int_value:w \__int_eval:w|, which
+% The \cs{exp_after:wN} triggers \cs{int_value:w} \cs{@@_int_eval:w}, which
% starts a first computation, whose initial value is $- 5\,0000$ (the
% \enquote{leading shift}). In that computation appears an
% \cs{exp_after:wN}, which triggers the nested computation
-% |\__int_value:w \__int_eval:w| with starting value $4\,9995\,0000$ (the
+% \cs{int_value:w} \cs{@@_int_eval:w} with starting value $4\,9995\,0000$ (the
% \enquote{middle shift}). That, in turn, expands \cs{exp_after:wN}
% which triggers the third computation. The third computation's value
% is $5\,0000\,0000 + 12345 \times 8899$, which has $9$ digits. Adding
@@ -858,7 +870,7 @@
\if_meaning:w 2 #1
+ 1
\fi:
- \__int_eval_end:
+ \@@_int_eval_end:
#2#3#4; {#5} ;
}
\cs_new:Npn \@@_basics_pack_weird_high:NNNNNNNNw
@@ -911,10 +923,10 @@
{
\cs:w
@@_decimate_
- \if_int_compare:w \__int_eval:w #1 > \c_@@_prec_int
+ \if_int_compare:w \@@_int_eval:w #1 > \c_@@_prec_int
tiny
\else:
- \__int_to_roman:w \__int_eval:w #1
+ \@@_int_to_roman:w \@@_int_eval:w #1
\fi:
:Nnnnn
\cs_end:
@@ -970,7 +982,7 @@
\cs_new:cpn { @@_decimate_ #1 :Nnnnn } ##1 ##2##3##4##5
{
\exp_after:wN ##1
- \__int_value:w
+ \int_value:w
\exp_after:wN \@@_round_digit:Nw #2 ;
\@@_decimate_pack:nnnnnnnnnnw #3 ;
}
@@ -996,7 +1008,7 @@
%
% \begin{macro}[EXP]{\@@_decimate_pack:nnnnnnnnnnw}
% The computation of the \meta{rounding} digit leaves an unfinished
-% \cs{__int_value:w}, which expands the following functions. This
+% \cs{int_value:w}, which expands the following functions. This
% allows us to repack nicely the digits we keep. Those digits come
% as an alternation of unbraced and braced blocks of $4$ digits,
% such that the first $5$ groups of token consist in $4$ single digits,
@@ -1025,12 +1037,12 @@
% treated using a few standard functions which we define now. A typical
% use context for those functions would be
% \begin{syntax}
-% |\if_case:w| \meta{integer} |\exp_stop_f:|
-% | \@@_case_return_o:Nw| \meta{fp var}
-% |\or: \@@_case_use:nw| \Arg{some computation}
-% |\or: \@@_case_return_same_o:w|
-% |\or: \@@_case_return:nw| \Arg{something}
-% |\fi:|
+% \cs{if_case:w} \meta{integer} \cs{exp_stop_f:}
+% | |\cs{@@_case_return_o:Nw} \meta{fp var}
+% \cs{or:} \cs{@@_case_use:nw} \Arg{some computation}
+% \cs{or:} \cs{@@_case_return_same_o:w}
+% \cs{or:} \cs{@@_case_return:nw} \Arg{something}
+% \cs{fi:}
% \meta{junk}
% \meta{floating point}
% \end{syntax}
@@ -1160,7 +1172,7 @@
\or:
\@@_case_return:nw
{
- \exp_after:wN \@@_small_int_true:wTF \__int_value:w
+ \exp_after:wN \@@_small_int_true:wTF \int_value:w
\if_meaning:w 2 #2 - \fi: 1 0000 0000 ;
}
\else: \@@_case_return:nw \use_ii:nn
@@ -1178,7 +1190,7 @@
{
\if_meaning:w 0 #1
\exp_after:wN \@@_small_int_true:wTF
- \__int_value:w \if_meaning:w 2 #5 - \fi:
+ \int_value:w \if_meaning:w 2 #5 - \fi:
\if_int_compare:w #2 > 0 \exp_stop_f:
1 0000 0000
\else:
@@ -1224,6 +1236,33 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Fast string comparison}
+%
+% \begin{macro}{\@@_str_if_eq_x:nn}
+% A private version of the low-level string comparison function. As
+% the nature of the arguments is restricted and as speed is of the essence,
+% this version does not seek to deal with |#| tokens.
+% No \pkg{l3sys} or \pkg{l3luatex} just yet so we have to define in terms of
+% primitives.
+% \begin{macrocode}
+\cs_new:Npn \@@_str_if_eq_x:nn #1#2 { \pdftex_strcmp:D {#1} {#2} }
+\sys_if_engine_luatex:T
+ {
+ \cs_set:Npn \@@_str_if_eq_x:nn #1#2
+ {
+ \luatex_directlua:D
+ {
+ l3kernel.strcmp
+ (
+ " \luatex_luaescapestring:D {#1}",
+ " \luatex_luaescapestring:D {#2}"
+ )
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Name of a function from its \pkg{l3fp-parse} name}
%
% \begin{macro}[EXP]{\@@_func_to_name:N, \@@_func_to_name_aux:w}
@@ -1231,10 +1270,14 @@
% This is used in error messages hence does not need to be fast.
% \begin{macrocode}
\cs_new:Npn \@@_func_to_name:N #1
- { \exp_last_unbraced:Nf \@@_func_to_name_aux:w { \cs_to_str:N #1 } X }
+ {
+ \exp_last_unbraced:Nf
+ \@@_func_to_name_aux:w { \cs_to_str:N #1 } X
+ }
\cs_set_protected:Npn \@@_tmp:w #1 #2
{ \cs_new:Npn \@@_func_to_name_aux:w ##1 #1 ##2 #2 ##3 X {##2} }
-\exp_args:Nff \@@_tmp:w { \tl_to_str:n { @@_ } } { \tl_to_str:n { _o: } }
+\exp_args:Nff \@@_tmp:w { \tl_to_str:n { @@_ } }
+ { \tl_to_str:n { _o: } }
% \end{macrocode}
% \end{macro}
%