summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3seq.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-11 23:53:06 +0000
committerKarl Berry <karl@freefriends.org>2006-01-11 23:53:06 +0000
commit1f4499ce04e16a3dae7c287b445576361cc20769 (patch)
treead95653c87d8135183eddbd885d1645f9dc5b547 /Master/texmf-dist/source/latex/expl3/l3seq.dtx
parent4206a1600d2e36ae7c46f99a3c58ae98112ee1ad (diff)
trunk/Master/texmf-dist/source/latex/expl3
git-svn-id: svn://tug.org/texlive/trunk@270 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3seq.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3seq.dtx622
1 files changed, 622 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3seq.dtx b/Master/texmf-dist/source/latex/expl3/l3seq.dtx
new file mode 100644
index 00000000000..f3da69642ef
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3seq.dtx
@@ -0,0 +1,622 @@
+% \iffalse
+%% File: l3seq.dtx Copyright (C) 1990-1998 LaTeX3 project
+%
+%<*dtx>
+ \ProvidesFile{l3seq.dtx}
+%</dtx>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{l3seq}
+%<driver> \ProvidesFile{l3seq.drv}
+% \fi
+% \ProvidesFile{l3seq.dtx}
+ [1998/04/20 v1.0d L3 Experimental Token List Pointers]
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3seq.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \GetFileInfo{l3seq.dtx}
+% \title{The \textsf{l3seq} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Sequences}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+%
+%
+% \section{Sequence}
+%
+% \LaTeX3 implements a data type called `sequences'. These are special
+% token lists that can be accessed via special function on the `left'.
+% Appending tokens is possible at both ends. Appended token lists can be
+% accessed only as a union. The token lists that form the individual
+% items of a sequence might contain any tokens except two internal
+% functions that are used to structure sequences (see section internal
+% functions below). It is also possible to map functions on such
+% sequences so that they are executed for every item on the sequence.
+%
+% All functions that return items from a sequence in some <tlp> assume
+% that the <tlp> is local. See remarks below if you need a global
+% returned value.
+%
+% The defined functions are not orthogonal in the sense that every
+% possible variation possible is actually available. If you need a new
+% variant use the expansion functions described in the package
+% \texttt{l3expan} to build it.
+%
+% Adding items to the left of a sequence can currently be done with
+% either something like "\seq_put_left:Nn" or with a ``stack'' function
+% like "\seq_push:Nn" which has the same effect. Maybe one should
+% therefore remove the ``left'' functions totally.
+%
+% \subsection{Functions}
+%
+% \begin{function}{%
+% \seq_new:N |
+% \seq_new:O |
+% \seq_new:c |
+% }
+% \begin{syntax}
+% "\seq_new:N" <sequence>
+% \end{syntax}
+% Defines <sequence> to be a variable of type sequences.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_clear:N |
+% \seq_clear:c |
+% \seq_gclear:N |
+% \seq_gclear:c |
+% }
+% \begin{syntax}
+% "\seq_clear:N" <sequence>
+% \end{syntax}
+% These functions locally or globally clear <sequence>.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_put_left:Nn |
+% \seq_put_left:No |
+% \seq_put_left:Nx |
+% \seq_put_left:cn |
+% \seq_put_right:Nn |
+% \seq_put_right:No |
+% \seq_put_right:Nx |
+% }
+% \begin{syntax}
+% "\seq_put_left:Nn" <sequence> <token list>
+% \end{syntax}
+% Locally appends <token list> as a single item to the left
+% or right of <sequence>. <token list> might get expanded before
+% appending.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_gput_left:Nn |
+% \seq_gput_right:Nn |
+% \seq_gput_right:No |
+% \seq_gput_right:cn |
+% \seq_gput_right:co |
+% \seq_gput_right:cc |
+% }
+% \begin{syntax}
+% "\seq_gput_left:Nn" <sequence> <token list>
+% \end{syntax}
+% Globally appends <token list> as a single item to the left
+% or right of <sequence>.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_get:NN |
+% \seq_get:cN |
+% }
+% \begin{syntax}
+% "\seq_get:NN" <sequence> <tlp>
+% \end{syntax}
+% Functions that locally assign the left-most item of <sequence> to the
+% token list pointer <tlp>. Item is not removed from <sequence>! If you
+% need a global return value you need to code something like this:
+% \begin{quote}
+% "\seq_get:NN" <sequence> "\l_tmpa_tlp" \\
+% "\tlp_gset_eq:NN" <global tlp> "\l_tmpa_tlp"
+% \end{quote}
+% But if this kind of construction is used often enough a separate
+% function should be provided.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_gconcat:NNN |
+% \seq_gconcat:ccc |
+% }
+% \begin{syntax}
+% "\seq_gconcat:NNN" <seq1> <seq2> <seq3>
+% \end{syntax}
+% Function that conatenates <seq2> and <seq3> and globally assigns the
+% result to <seq1>.
+% \end{function}
+%
+% \begin{function}{\seq_map:NN}
+% \begin{syntax}
+% "\seq_map:NN" <sequences> <function>
+% \end{syntax}
+% This function applies <function> (which must be a function with one
+% argument) to every item of <sequence>. <function> is not executed
+% within a sub-group so that side effects can be achieved locally. The
+% operation is not expandable which means that it can't be used within
+% write operations etc.
+%
+% In the current implementation the next functions are more efficient and
+% should be preferred.
+% \end{function}
+%
+% \begin{function}{\seq_map_inline:Nn |
+% \seq_map_inline:cn
+% }
+% \begin{syntax}
+% "\seq_map_inline:Nn" <sequence> "{" <inline function> "}"
+% \end{syntax}
+% Applies <inline function> (which should be the direct coding for a
+% function with one argument (i.e.\ use "##1" as the place holder for
+% this argument)) to every item of <sequence>. <inline function> is not
+% executed within a sub-group so that side effects can be achieved locally.
+% The operation is not expandable which means that it can't be used
+% within write operations etc.
+% \end{function}
+%
+% \subsection{Predicates and conditionals}
+%
+% \begin{function}{\seq_empty_p:N}
+% \begin{syntax}
+% "\seq_empty_p:N" <sequence>
+% \end{syntax}
+% This predicate returns `true' if <sequence> is `empty' i.e., doesn't
+% contain any tokens.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_empty:NTF |
+% \seq_empty:cTF |
+% \seq_empty:NF |
+% \seq_empty:cF |
+% }
+% \begin{syntax}
+% "\seq_empty:NTF" <sequence> "{" <true code> "}{" <false code> "}"
+% \end{syntax}
+% Set of conditionals that test whether or not a particular <sequence>
+% is empty and if so executes either <true code> or <false code>.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_if_in:NnTF |
+% \seq_if_in:cnTF |
+% \seq_if_in:coTF |
+% }
+% \begin{syntax}
+% "\seq_if_in:NnTF" <sequ> "{" <item> "}{" <true code> "}{" <false code> "}"
+% \end{syntax}
+% Function that tests if <item> is in <sequ>. Depending on the result
+% either <true code> or <false code> is executed.
+% \end{function}
+%
+% \subsection{Internal functions}
+%
+% \begin{function}{\seq_empty_err:N}
+% \begin{syntax}
+% "\seq_empty_err:N" <sequence>
+% \end{syntax}
+% Signals an \LaTeX3 error if <sequence> is empty.
+% \end{function}
+%
+% \begin{function}{\seq_pop_aux:nnNN}
+% \begin{syntax}
+% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tlp>
+% \end{syntax}
+% Function that assigns the left-most item of <sequence> to <tlp> using
+% <assign1> and assigns the tail to <sequence> using <assign2>. This
+% function could be used to implement a global return function.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_get_aux:w |
+% \seq_pop_aux:w |
+% \seq_put_aux:Nnn |
+% \seq_put_aux:w |
+% }
+% Functions used to implement put and get operations. They are not for
+% meant for direct use.
+% \end{function}
+%
+% \begin{function}{%
+% \seq_elt:w |
+% \seq_elt_end: }
+% Functions (usually used as constants) that separates items within a
+% sequence. They might get special meaning during mapping operations and
+% are not supposed to show up as tokens within an item appended to a
+% sequence.
+% \end{function}
+%
+%
+% \section {Implementation}
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<package&!check>\RequirePackage{l3toks}
+%<package&!check>\RequirePackage{l3quark}
+%<package&check>\RequirePackage{l3chk}
+%<package>\RequirePackage{l3expan}
+%<*package>
+% \end{macrocode}
+%
+% A sequence is a control sequence whose top-level expansion is of the
+% form `|\seq_elt:w| \m{text$\sb1$} |\seq_elt_end:| \ldots{}
+% |\seq_elt:w| \zv{text$\sb{n}$} \ldots'. We use explicit delimiters
+% instead of braces around \m{text} to allow efficient searching for
+% an item in the sequence.
+%
+% \begin{macro}{\seq_elt:w}
+% \begin{macro}{\seq_elt_end:}
+% We allocate the delimiters and make them noops as default.
+% \begin{macrocode}
+\let_new:NN \seq_elt:w \use_noop:
+\let_new:NN \seq_elt_end: \use_noop:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\seq_new:N}
+% \begin{macro}{\seq_new:O}
+% \begin{macro}{\seq_new:c}
+% Sequences are implemented using token lists.
+% \begin{macrocode}
+\def_new:Npn \seq_new:N #1{\tlp_new:Nn #1{}}
+\def_new:Npn \seq_new:c {\exp_args:Nc \seq_new:N}
+\def_new:Npn \seq_new:O {\exp_args:No \seq_new:N}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_clear:N}
+% \begin{macro}{\seq_clear:c}
+% \begin{macro}{\seq_gclear:N}
+% \begin{macro}{\seq_gclear:c}
+% Clearing a sequence is the same as clearing a token list.
+% \begin{macrocode}
+\let_new:NN \seq_clear:N \tlp_clear:N
+\let_new:NN \seq_clear:c \tlp_clear:c
+\let_new:NN \seq_gclear:N \tlp_gclear:N
+\let_new:NN \seq_gclear:c \tlp_gclear:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_clear_new:N}
+% \begin{macro}{\seq_clear_new:c}
+% \begin{macro}{\seq_gclear_new:N}
+% \begin{macro}{\seq_gclear_new:c}
+% Clearing a sequence is the same as clearing a token list.
+% \begin{macrocode}
+\let_new:NN \seq_clear_new:N \tlp_clear_new:N
+\let_new:NN \seq_clear_new:c \tlp_clear_new:c
+\let_new:NN \seq_gclear_new:N \tlp_gclear_new:N
+\let_new:NN \seq_gclear_new:c \tlp_gclear_new:c
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_empty_p:N}
+% A predicate which evaluates to |\c_true| iff the sequence is empty.
+% \begin{macrocode}
+\let_new:NN \seq_empty_p:N \tlp_empty_p:N
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_empty:NTF}
+% \begin{macro}{\seq_empty:cTF}
+% \begin{macro}{\seq_empty:NF}
+% \begin{macro}{\seq_empty:cF}
+% |\seq_empty:NTF|\m{seq}\m{true~case}\m{false~case} will check
+% whether the \m{seq} is empty and then select one of the other
+% arguments. |seq_empty:cTF| turns its first argument into a
+% control sequence to get the name of the sequence.
+% \begin{macrocode}
+\def_new:Npn \seq_empty:NTF #1{
+ \if_meaning:NN#1\c_empty_tlp
+ \exp_after:NN\use_choice_i:nn
+ \else: \exp_after:NN\use_choice_ii:nn \fi:}
+\def_new:Npn \seq_empty:cTF {\exp_args:Nc\seq_empty:NTF}
+% \end{macrocode}
+% A variant of this, is only to do something if the sequence is
+% {\em not} empty.
+% \begin{macrocode}
+\def_new:Npn \seq_empty:NF #1{
+ \if_meaning:NN#1\c_empty_tlp \exp_after:NN\use_none:n
+ \else: \exp_after:NN\use:n \fi:}
+\def_new:Npn \seq_empty:cF {\exp_args:Nc\seq_empty:NF}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\seq_empty_err:N}
+% Signals an error if the sequence is empty.
+% \begin{macrocode}
+\def_new:Npn \seq_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp
+% \end{macrocode}
+% As I said before, I don't think we need to provide checks for this
+% kind of error, since it is a severe internal macro package error
+% that can not be produced by the user directly. Can it? So the
+% next line of code should be probably removed.
+% \begin{macrocode}
+ \tlp_clear:N \l_testa_tlp % catch prefixes
+ \err_latex_bug:n{Empty~sequence~`\token_to_string:N#1'}\fi:}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_get:NN}
+% \begin{macro}{\seq_get:cN}
+% |\seq_get:NN |\zz{sequence}\zz{cmd} defines \zz{cmd} to be the
+% left_most element of \zz{sequence}.
+% \begin{macrocode}
+\def_new:Npn \seq_get:NN #1{
+ \seq_empty_err:N #1
+ \exp_after:NN\seq_get_aux:w #1\q_stop}
+\def_new:Npn \seq_get_aux:w \seq_elt:w #1\seq_elt_end:
+ #2\q_stop #3{\tlp_set:Nn #3{#1}}
+\def_new:Npn \seq_get:cN {\exp_args:Nc \seq_get:NN}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_pop_aux:nnNN}
+% |\seq_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{sequence}
+% \zz{cmd} assigns the left_most element of \zz{sequence} to
+% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of
+% \zz{sequence} to \zz{sequence} using \zz{def$\sb1$}.
+% \begin{macrocode}
+\def_new:Npn \seq_pop_aux:nnNN #1#2#3{
+ \seq_empty_err:N #3
+ \exp_after:NN\seq_pop_aux:w #3\q_stop #1#2#3}
+\def_new:Npn \seq_pop_aux:w \seq_elt:w #1\seq_elt_end:
+ #2\q_stop #3#4#5#6{#3#5{#2}#4#6{#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_put_aux:Nnn}
+% |\seq_put_aux:Nnn| \zz{sequence} \zv{left} \zv{right} adds the
+% elements specified by \zv{left} to the left of \zz{sequence}, and
+% those specified by \zv{right} to the right.
+% \begin{macrocode}
+\def_new:Npn \seq_put_aux:Nnn #1{
+ \exp_after:NN\seq_put_aux:w #1\q_stop #1}
+\def_new:Npn \seq_put_aux:w #1\q_stop #2#3#4{\tlp_set:Nn #2{#3#1#4}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_put_left:Nn}
+% \begin{macro}{\seq_put_left:No}
+% \begin{macro}{\seq_put_left:Nx}
+% \begin{macro}{\seq_put_left:cn}
+% \begin{macro}{\seq_put_right:Nn}
+% \begin{macro}{\seq_put_right:No}
+% \begin{macro}{\seq_put_right:Nx}
+% Here are the usual operations for adding to the left and right.
+% \begin{macrocode}
+\def_new:Npn \seq_put_left:Nn #1#2{
+% \end{macrocode}
+% We can't put in a |\use_noop:| instead of |{}| since this argument is
+% passed literally (and we would end up with many |\use_noop:|s inside
+% the sequences.
+% \begin{macrocode}
+ \seq_put_aux:Nnn #1{\seq_elt:w #2\seq_elt_end:}{}}
+\def_new:Npn \seq_put_left:cn {\exp_args:Nc\seq_put_left:Nn}
+\def_new:Npn \seq_put_left:No {\exp_args:NNo\seq_put_left:Nn}
+\def_new:Npn \seq_put_left:Nx {\exp_args:Nnx\seq_put_left:Nn}
+\def_new:Npn \seq_put_right:Nn #1#2{
+ \seq_put_aux:Nnn #1{}{\seq_elt:w #2\seq_elt_end:}}
+\def_new:Npn \seq_put_right:No {\exp_args:Nno\seq_put_right:Nn}
+\def_new:Npn \seq_put_right:Nx {\exp_args:Nnx\seq_put_right:Nn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_gput_left:Nn}
+% \begin{macro}{\seq_gput_right:Nn}
+% \begin{macro}{\seq_gput_right:No}
+% \begin{macro}{\seq_gput_right:cn}
+% \begin{macro}{\seq_gput_right:co}
+% \begin{macro}{\seq_gput_right:cc}
+% An here the global variants.
+% \begin{macrocode}
+\def_new:Npn \seq_gput_left:Nn {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<_check> \pref_global:D
+ \seq_put_left:Nn}
+\def_new:Npn \seq_gput_right:Nn {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<_check> \pref_global:D
+ \seq_put_right:Nn}
+\def_new:Npn \seq_gput_right:No {\exp_args:NNo \seq_gput_right:Nn}
+\def_new:Npn \seq_gput_right:cn {\exp_args:Nc \seq_gput_right:Nn}
+\def_new:Npn \seq_gput_right:co {\exp_args:Nco \seq_gput_right:Nn}
+\def_new:Npn \seq_gput_right:cc {\exp_args:Ncc \seq_gput_right:Nn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_map:NN}
+% |\seq_map:NN| \zz{sequence} \zz{cmd} applies \zz{cmd} to each
+% element of \zz{sequence}, from left to right. Since we don't have
+% braces, this implementation is not very efficient. It might be
+% better to say that \zz{cmd} must be a function with one argument
+% that is delimited by |\seq_elt_end:|.
+% \begin{macrocode}
+\def_new:Npn \seq_map:NN #1#2{
+ \def:Npn \seq_elt:w ##1\seq_elt_end: {#2{##1}}#1}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_inline:Nn}
+% \begin{macro}{\seq_map_inline:cn}
+% When no braces are used, this version of mapping seems more
+% natural.
+% \begin{macrocode}
+\def_new:Npn \seq_map_inline:Nn #1#2{
+ \gdef:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1}
+\def_new:Npn \seq_map_inline:cn{\exp_args:Nc\seq_map_inline:Nn}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_gconcat:NNN}
+% \begin{macro}{\seq_gconcat:ccc}
+% |\seq_gconcat:NNN| \m{seq~1} \m{seq~2} \m{seq~3} will globally
+% assign \m{seq~1} the concatenation of \m{seq~2} and \m{seq~3}.
+% \begin{macrocode}
+\def_new:Npn \seq_gconcat:NNN #1#2#3{
+ \l_tmpa_toks \exp_after:NN{#2}
+ \l_tmpb_toks \exp_after:NN{#3}
+ \gdef:Npx #1{\toks_use:N \l_tmpa_toks \toks_use:N \l_tmpb_toks}}
+\def_new:Npn \seq_gconcat:ccc{\exp_args:Nccc\seq_gconcat:NNN}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_if_in:NnTF}
+% \begin{macro}{\seq_if_in:cnTF}
+% \begin{macro}{\seq_if_in:coTF}
+% |\seq_if_in:NnTF| \m{seq}\m{item} \m{true~case} \m{false~case}
+% will check whether \m{item} is in \m{seq} and then either execute
+% the \m{true~case} or the \m{false~case}. \m{true~case} and
+% \m{false~case} may contain incomplete |\if_char_code:w|
+% statements.
+% \begin{macrocode}
+\def_new:Npn \seq_if_in:NnTF #1#2{
+ \def:Npn\tmp:w
+ ##1\seq_elt:w #2\seq_elt_end: ##2##3\q_stop{
+% \end{macrocode}
+% Note that |##2| contains exactly one token which we can compare
+% with |\q_no_value|.
+% \begin{macrocode}
+ \if_meaning:NN\q_no_value##2
+ \exp_after:NN\use_choice_ii:nn
+ \else:
+ \exp_after:NN\use_choice_i:nn
+ \fi:
+ }
+ \exp_after:NN
+ \tmp:w #1\seq_elt:w
+ #2\seq_elt_end: \q_no_value \q_stop}
+\def_new:Npn \seq_if_in:coTF {\exp_args:Nco \seq_if_in:NnTF}
+\def_new:Npn \seq_if_in:cnTF {\exp_args:Nc \seq_if_in:NnTF}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \subsection{Stack operations}
+%
+% We build stacks from sequences, but here we put the
+% specific functions together.
+%
+%
+% \begin{macro}{\seq_push:Nn}
+% \begin{macro}{\seq_push:No}
+% \begin{macro}{\seq_push:cn}
+% \begin{macro}{\seq_pop:NN}
+% \begin{macro}{\seq_pop:cN}
+% Since sequences can be used as stacks, we ought to have both
+% `push' and `pop'. In most cases they are nothing more then new
+% names for old functions.
+% \begin{macrocode}
+\let_new:NN \seq_push:Nn \seq_put_left:Nn
+\let_new:NN \seq_push:No \seq_put_left:No
+\let_new:NN \seq_push:cn \seq_put_left:cn
+\def_new:Npn \seq_pop:NN {\seq_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn}
+\def_new:Npn \seq_pop:cN {\exp_args:Nc \seq_pop:NN}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\seq_gpush:Nn}
+% \begin{macro}{\seq_gpush:No}
+% \begin{macro}{\seq_gpush:cn}
+% \begin{macro}{\seq_gpop:NN}
+% \begin{macro}{\seq_gpop:cN}
+% I don't agree with Denys that one needs only local stacks,
+% actually I believe that one will probably need the functions
+% here more often. In case of |\seq_gpop:NN| the value is
+% nevertheless returned locally.
+% \begin{macrocode}
+\let_new:NN \seq_gpush:Nn \seq_gput_left:Nn
+\def_new:Npn \seq_gpush:No {\exp_args:NNo \seq_gpush:Nn}
+\def_new:Npn \seq_gpush:cn {\exp_args:Nc \seq_gpush:Nn}
+\def_new:Npn \seq_gpop:NN {\seq_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn}
+\def_new:Npn \seq_gpop:cN {\exp_args:Nc \seq_gpop:NN}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\seq_top:NN}
+% \begin{macro}{\seq_top:cN}
+% Looking at the top element of the stack without removing it is
+% done with this operation.
+% \begin{macrocode}
+\let_new:NN \seq_top:NN \seq_get:NN
+\let_new:NN \seq_top:cN \seq_get:cN
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% Show token usage:
+% \begin{macrocode}
+%</package>
+%<*showmemory>
+%\showMemUsage
+%</showmemory>
+% \end{macrocode}
+%
+%
+%
+