% \iffalse %% File: l3alloc.dtx Copyright (C) 1990-2006 LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the %% LaTeX Project Public License (LPPL), either version 1.3c of this %% license or (at your option) any later version. The latest version %% of this license is in the file %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the ``expl3 bundle'' (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/cgi-bin/cvsweb.cgi/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- % %<*driver|package> \RequirePackage{l3names} % %\fi \GetIdInfo$Id: l3alloc.dtx 621 2007-09-01 20:14:19Z morten $ {L3 Experimental register allocation}% %\iffalse %<*driver> %\fi \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse \documentclass{l3doc} \begin{document} \DocInput{\filename.\filenameext} \end{document} % % \fi % % % \title{The \textsf{l3alloc} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ % Allocating registers and the like} % \author{\Team} % \date{\filedate} % \maketitle % % \section{Allocating registers and the like} % % This module provides the basic mechanism for allocating \TeX's % registers. While designing this we have to take into account the % following characteristics: % \begin{itemize} % \item |\box255| is reserved for use in the output routine, so it % should not be allocated otherwise. % \item \TeX\ can load up 256 hyphenation patterns (registers % |\tex_language:D| 0-255), % \item \TeX\ can load no more than 16 math families, % \item \TeX\ supports no more than 16 io-streams for reading % (|\tex_read:D|) and 16 io-streams for writing (|\tex_write:D|), % \item \TeX\ supports no more than 256 inserts, Omega supports more. % \item The other registers (|\tex_count:D|, |\tex_dimen:D|, % |\tex_skip:D|, |\tex_muskip:D|, |\tex_box:D|, and |\tex_toks:D| % range from 0 to 32768, but registers numbered above 255 are % accessed somewhat less efficient. % \item Registers could be allocated both globally and locally; the % use of regsiters could also be globaly or locally. Here we % provide support for globally allocated registers for both % gloabl and local use and for locally allocated registers for % local use only. % \end{itemize} % We also need to allow for some bookkeeping: we need to know which % register was allocated last and which registers can not be % allocated by the standard mechanisms. % % \subsection{Functions} % % \begin{function}{\alloc_setup_type:nnn} % \begin{syntax} % "\alloc_setup_type:nnn" % \end{syntax} % Sets up the storage needed for the administration of registers of % type .\\ % should be a token list in braces, it can be one of % "int", "dimen", "skip", "muskip", "box", "toks", "ior", "iow", % "pattern", or "ins".\\ % is the number of the first not allocated global % register, it will be incremented by 1 when the allocation is done. % is the number of the first not allocated local % register, it will be decremented by 1 when the allocation is done. % \end{function} % % \begin{function}{\alloc_reg:NnNN} % \begin{syntax} % "\alloc_reg:NnNN" % \end{syntax} % Performs the allocation of a register of type to copntrol % sequence , using the command . The "g" or "l" % indicaties whether the allocation should be global or local. % This macro is the basic building block for the definition of the % "\""_new:N" commands % \end{function} % % \StopEventually{} % % \subsection{The Implementation} % % We start by ensuring that the required packages are loaded when % this file is loaded as a package on top of \LaTeXe. % % \begin{macrocode} %\ProvidesExplPackage % {\filename}{\filedate}{\fileversion}{\filedescription} %\RequirePackage{l3expan} %\RequirePackage{l3num} %\RequirePackage{l3seq}\par % \end{macrocode} % % % \begin{macrocode} %<*initex|package> % \end{macrocode} % % \begin{macro}{\alloc_setup_type:nnn} % For each type of register we need to `counters' that hold the % last allocated global or local register. We also need a sequence % to store the `excpetions'. % \begin{macrocode} \def_new:Npn \alloc_setup_type:nnn #1 #2 #3{ \num_new:c {g_ #1 _allocation_num} \num_new:c {l_ #1 _allocation_num} \seq_new:c {g_ #1 _allocation_seq} \num_set:cn {g_ #1 _allocation_num}{#2} \num_set:cn {l_ #1 _allocation_num}{#3} } % \end{macrocode} % \end{macro} % % \begin{macro}{\alloc_next_g:n} % \begin{macro}{\alloc_next_l:n} % These routines find the next free register. For globally allocated % registers we first increment the counter that keeps track of them. % \begin{macrocode} \def_new:Npn \alloc_next_g:n #1 { \num_gincr:c {g_ #1 _allocation_num} % \end{macrocode} % Then we need to check whether we have run out of registers. % \begin{macrocode} \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num} {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ g_#1!}} { % \end{macrocode} % We also need to check wether the value of the counter already % occurs in the list of already allocated registers. % \begin{macrocode} \seq_if_in:cxTF {g_ #1 _allocation_seq} {\num_use:c{g_ #1 _allocation_num}} {\io_put_term:x{\num_use:c{g_ #1 _allocation_num}~Already~ allocated!} % \end{macrocode} % If it does, we find the next value. % \begin{macrocode} \alloc_next_g:n {#1} } {\use_noop:} } % \end{macrocode} % By now the |.._allocation_num| counter will contain the number of % the register we will assign a control seuence for. % \begin{macrocode} } % \end{macrocode} % For the locally allocated registers we have a similar function. % \begin{macrocode} \def_new:Npn \alloc_next_l:n #1 { \num_gdecr:c {l_ #1 _allocation_num} \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num} {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ l_#1!}} { \seq_if_in:cxTF {g_ #1 _allocation_seq} {\num_use:c{l_ #1 _allocation_num}} {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Already~ allocated!} \alloc_next_l:n {#1} } {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Free!}} } } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\alloc_reg:NnNN} % This internal macro performs the actual allocation. It's first % argument is either 'g' for a globally allocated register or `l' % for a locally allocated register. The second argument is the % type of register to allocate, the third argument is the command % to use and the fourth argument is the control sequence that is to % be defined to point to the register. % \begin{macrocode} \def_new:Npn \alloc_reg:NnNN #1 #2 #3 #4{ % \end{macrocode} % It first checks that the control sequence that is to denote the % register does not already exist. % \begin{macrocode} \chk_new_cs:N #4 % \end{macrocode} % Next, it decides whether a prefix is needed for the allocation % command; % \begin{macrocode} \if:w#1g \exp_after:NN \pref_global:D \fi: % \end{macrocode} % And finally the actual allocation takes place. % \begin{macrocode} #3 #4 \num_use:c{#1_ #2 _allocation_num} %%\cs_record_meaning:N#1 % \end{macrocode} % All that's left to do is write a message in the log file. % \begin{macrocode} \io_put_log:x{ \token_to_string:N#4=#2~register~\num_use:c{#1_ #2 _allocation_num}} % \end{macrocode} % Finally, it calls |\alloc_next_| to find the next free register % number. % \begin{macrocode} \cs_use:c{alloc_next_#1:n} {#2} } % \end{macrocode} % \end{macro} % % % \begin{macrocode} %<*showmemory> \showMemUsage % % % \end{macrocode} % % \endinput % % $Log$ % Revision 1.6 2006/03/20 18:26:32 braams % Updated the copyright notice (2006) and demoted all implementation % sections to subsections and so on to clean up the toc for source3.tex % % Revision 1.5 2006/01/15 14:02:58 braams % Added a \SopEventually{} command % % Revision 1.4 2005/12/27 16:02:18 morten % Changed RCS information retrieval % % Revision 1.3 2005/04/06 22:32:38 braams % Removed the functins that belong in other modules; % Fixed the naming conventions % % Revision 1.2 2005/04/05 22:12:44 braams % First, working, version of the regsiter allocation support % % Revision 1.1 2005/03/16 22:50:02 braams % Initial register allocation module %