[latex3-commits] [latex3/latex2e] gh1189: Use a one-level indirection for optimized commands (84b6817e)
github at latex-project.org
github at latex-project.org
Wed Nov 29 11:46:45 CET 2023
Repository : https://github.com/latex3/latex2e
On branch : gh1189
Link : https://github.com/latex3/latex2e/commit/84b6817e9af83fcd238890a5405b470c00e39cd2
>---------------------------------------------------------------
commit 84b6817e9af83fcd238890a5405b470c00e39cd2
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date: Wed Nov 29 10:44:21 2023 +0000
Use a one-level indirection for optimized commands
This means that they still have "\foo code" and no args at the top level:
that makes them easier to handle with patching, etc.
Args are only grabbed once and we are looking at very simple expansion, so there is no real need
to worry about performance.
The marker \@@_start_optimized: is retained:
we could just check for "\foo code" directly,
but this way there is a clear single-token
marker at the start of the def.
>---------------------------------------------------------------
84b6817e9af83fcd238890a5405b470c00e39cd2
base/ltcmd.dtx | 51 ++++++++++++++++++---------
base/testfiles-ltcmd/github-1009.tlg | 56 +++++++++++++++++-------------
base/testfiles-ltcmd/ltcmd001.tlg | 67 +++++++++++++++++-------------------
base/testfiles-ltcmd/ltcmd002.tlg | 2 +-
4 files changed, 99 insertions(+), 77 deletions(-)
diff --git a/base/ltcmd.dtx b/base/ltcmd.dtx
index a293750f..125122de 100644
--- a/base/ltcmd.dtx
+++ b/base/ltcmd.dtx
@@ -491,17 +491,29 @@
% The optimized version of commands just has to worry about whether to make
% them protected or long. The commands start with an expandable marker so
% that other parts of the kernel know these are set up by \pkg{ltcmd}.
+% We need the two layers of redirection so that the \texttt{code} internal
+% function has the same form as it would for any other document command.
% \begin{macrocode}
\cs_new_protected:Npn \@@_declare_cmd_optimized:Nnn #1#2#3
{
- \exp_args:NNc \cs_generate_from_arg_count:NNnn #1
+ \bool_if:NTF \l_@@_expandable_bool
+ { \cs_set_nopar:Npe }
+ { \cs_set_protected_nopar:Npe }
+ #1
+ {
+ \exp_not:N \@@_start_optimized:
+ \exp_not:c { \l_@@_function_tl \c_space_tl code }
+ }
+ \exp_args:Ncc \cs_generate_from_arg_count:NNnn
+ { \l_@@_function_tl \c_space_tl code }
{
cs_set
\bool_if:NF \l_@@_expandable_bool { _protected }
\bool_if:NF \l_@@_some_long_bool { _nopar }
:Npn
}
- \l_@@_current_arg_int { \@@_start_optimized: #3 }
+ \l_@@_current_arg_int
+ {#3}
}
\cs_new:Npn \@@_start_optimized: { }
% \end{macrocode}
@@ -2247,10 +2259,20 @@
% \end{macrocode}
%
% \begin{macro}{\@@_copy_optimized:nnNN}
-% Trivial copy.
+% Copy the code, simply define the wrapper.
% \begin{macrocode}
\cs_new_protected:Npn \@@_copy_optimized:nnNN #1#2#3#4
- { \cs_set_eq:NN #3 #4 }
+ {
+ \cs_set_eq:cc { #1 ~ code } { #2 ~ code }
+ \token_if_protected_macro:NTF #4
+ { \cs_set_protected_nopar:Npe }
+ { \cs_set_nopar:Npe }
+ #3
+ {
+ \exp_not:N \@@_start_optimized:
+ \exp_not:c { #1 ~ code }
+ }
+ }
% \end{macrocode}
% \end{macro}
%
@@ -2604,6 +2626,12 @@
% reconstruct the argument spec.
% \begin{macrocode}
\cs_new_protected:Npn \@@_show_optimized:N #1
+ {
+ \exp_args:Nc \@@_show_optimized:NN
+ { \cs_to_str:N #1 \c_space_tl code }
+ #1
+ }
+\cs_new_protected:Npn \@@_show_optimized:NN #1#2
{
\cs_set:Npe \@@_show_optimized_aux:N ##1
{
@@ -2616,7 +2644,7 @@
}
\tl_show:e
{
- \token_to_str:N #1 =
+ \token_to_str:N #2 =
\bool_lazy_or:nnF
{ \token_if_protected_macro_p:N #1 }
{ \token_if_protected_long_macro_p:N #1 }
@@ -2630,20 +2658,9 @@
}
\@@_show_optimized_aux:N
->
- \use:e
- {
- \exp_not:N \@@_show_optimized_aux:w
- \cs_replacement_spec:N #1
- }
+ \cs_replacement_spec:N #1
}
}
-\cs_new:Npn \@@_show_optimized_aux:N #1 { }
-\use:e
- {
- \cs_new:Npn \exp_not:N \@@_show_optimized_aux:w
- \token_to_str:N \@@_start_optimized: \c_space_tl
- }
- { }
% \end{macrocode}
%
% We can reuse most of the above to show an environment, except that
diff --git a/base/testfiles-ltcmd/github-1009.tlg b/base/testfiles-ltcmd/github-1009.tlg
index 195cbc6d..24098de3 100644
--- a/base/testfiles-ltcmd/github-1009.tlg
+++ b/base/testfiles-ltcmd/github-1009.tlg
@@ -13,21 +13,25 @@ l. ...}
->.
<recently read> }
l. ...}
-> \foo=\protected macro:
-#1->\__cmd_start_optimized: .
-<argument> \foo
+> \foo=document command:
+ #1:m
+->.
+<recently read> }
l. ...}
-> \baz=\protected macro:
-#1->\__cmd_start_optimized: .
-<argument> \baz
+> \baz=document command:
+ #1:m
+->.
+<recently read> }
l. ...}
-> \foo=\protected\long macro:
-#1->\__cmd_start_optimized: .
-<argument> \foo
+> \foo=document command:
+ #1:+m
+->.
+<recently read> }
l. ...}
-> \baz=\protected\long macro:
-#1->\__cmd_start_optimized: .
-<argument> \baz
+> \baz=document command:
+ #1:+m
+->.
+<recently read> }
l. ...}
> \foo=document command:
#1:>{\foo }m
@@ -53,20 +57,24 @@ l. ...}
->.
<recently read> }
l. ...}
-> \foo=macro:
-#1->\__cmd_start_optimized: .
-<argument> \foo
+> \foo=expandable document command:
+ #1:m
+->.
+<recently read> }
l. ...}
-> \baz=macro:
-#1->\__cmd_start_optimized: .
-<argument> \baz
+> \baz=expandable document command:
+ #1:m
+->.
+<recently read> }
l. ...}
-> \foo=\long macro:
-#1->\__cmd_start_optimized: .
-<argument> \foo
+> \foo=expandable document command:
+ #1:+m
+->.
+<recently read> }
l. ...}
-> \baz=\long macro:
-#1->\__cmd_start_optimized: .
-<argument> \baz
+> \baz=expandable document command:
+ #1:+m
+->.
+<recently read> }
l. ...}
============================================================
diff --git a/base/testfiles-ltcmd/ltcmd001.tlg b/base/testfiles-ltcmd/ltcmd001.tlg
index 5e2b34f7..3d7d3a5d 100644
--- a/base/testfiles-ltcmd/ltcmd001.tlg
+++ b/base/testfiles-ltcmd/ltcmd001.tlg
@@ -17,73 +17,70 @@ For immediate help type H <return>.
l. ...}
You have used \RenewDocumentCommand with a command that was never defined.
LaTeX will ignore this entire definition.
-> \foo=\protected macro:->\__cmd_start_optimized: First definition.
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:->First definition.
<recently read> }
l. ...}
============================================================
============================================================
TEST 2: Commands with simple mandatory arguments
============================================================
-> \foo=\protected macro:#1->\__cmd_start_optimized: (#1).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1->(#1).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2->\__cmd_start_optimized: (#1)(#2).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1#2->(#1)(#2).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3->\__cmd_start_optimized: (#1)(#2)(#3).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1#2#3->(#1)(#2)(#3).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3#4->\__cmd_start_optimized: (#1)(#2)(#3)(#4).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1#2#3#4->(#1)(#2)(#3)(#4).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3#4#5->\__cmd_start_optimized:
-(#1)(#2)(#3)(#4)(#5).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3#4#5#6->\__cmd_start_optimized:
-(#1)(#2)(#3)(#4)(#5)(#6).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3#4#5#6#7->\__cmd_start_optimized:
-(#1)(#2)(#3)(#4)(#5)(#6)(#7).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected macro:#1#2#3#4#5#6#7->(#1)(#2)(#3)(#4)(#5)(#6)(#7).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3#4#5#6#7#8->\__cmd_start_optimized:
-(#1)(#2)(#3)(#4)(#5)(#6)(#7)(#8).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected
+macro:#1#2#3#4#5#6#7#8->(#1)(#2)(#3)(#4)(#5)(#6)(#7)(#8).
<recently read> }
l. ...}
-> \foo=\protected macro:#1#2#3#4#5#6#7#8#9->\__cmd_start_optimized:
-(#1)(#2)(#3)(#4)(#5)(#6)(#7)(#8)(#9).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected
+macro:#1#2#3#4#5#6#7#8#9->(#1)(#2)(#3)(#4)(#5)(#6)(#7)(#8)(#9).
<recently read> }
l. ...}
============================================================
@@ -107,10 +104,10 @@ l. ...}
============================================================
TEST 4: Commands with one long mandatory argument
============================================================
-> \foo=\protected\long macro:#1->\__cmd_start_optimized: (#1).
+> \foo=\protected macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\protected\long macro:#1->(#1).
<recently read> }
l. ...}
> \foo=\protected macro:->\__cmd_start_expandable:nNNNNn {m+m}\foo \foo
@@ -324,22 +321,22 @@ l. ...}
============================================================
TEST 8: Some valid expandable functions
============================================================
-> \foo=macro:#1->\__cmd_start_optimized: (#1).
+> \foo=macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=macro:#1->(#1).
<recently read> }
l. ...}
-> \foo=\long macro:#1->\__cmd_start_optimized: (#1).
+> \foo=macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=\long macro:#1->(#1).
<recently read> }
l. ...}
-> \foo=macro:#1#2#3->\__cmd_start_optimized: (#1)(#2)(#3).
+> \foo=macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=macro:#1#2#3->(#1)(#2)(#3).
<recently read> }
l. ...}
> \foo=macro:->\__cmd_start_expandable:nNNNNn {om}\foo \foo \foo code
@@ -697,10 +694,10 @@ l. ...}
You have used \RenewExpandableDocumentCommand with a command that was never
defined.
LaTeX will ignore this entire definition.
-> \foo=macro:->\__cmd_start_optimized: First definition.
+> \foo=macro:->\__cmd_start_optimized: \foo code .
<recently read> }
l. ...}
-> \foo code=undefined.
+> \foo code=macro:->First definition.
<recently read> }
l. ...}
============================================================
diff --git a/base/testfiles-ltcmd/ltcmd002.tlg b/base/testfiles-ltcmd/ltcmd002.tlg
index 3a5fbeb9..cad76a7b 100644
--- a/base/testfiles-ltcmd/ltcmd002.tlg
+++ b/base/testfiles-ltcmd/ltcmd002.tlg
@@ -48,7 +48,7 @@ TEST 2: Nesting optional arguments
TEST 3: Invalid arguments (types s, o m)
============================================================
Runaway argument?
-! Paragraph ended before \foo was complete.
+! Paragraph ended before \foo code was complete.
<to be read again>
\par
l. ...}
More information about the latex3-commits
mailing list.