% \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}
%</driver|package>
%\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}
%</driver>
% \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" <type> <g_start_num> <l_start_num>
%    \end{syntax}
%    Sets up the storage needed for the administration of registers of
%    type <type>.\\
%    <type> should be a token list in braces, it can be one of
%    "int", "dimen", "skip", "muskip", "box", "toks", "ior", "iow",
%    "pattern", or "ins".\\
%    <g_start_num> is the number of the first not allocated global
%    register, it will be incremented by 1 when the allocation is done.
%    <l_start_num> 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" <g-l> <type> <alloc_cmd> <cs>
%    \end{syntax}
%    Performs the allocation of a register of type <type> to copntrol
%    sequence <cs>, using the command <alloc_cmd>. 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
%    "\"<type>"_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}
%<package>\ProvidesExplPackage
%<package>  {\filename}{\filedate}{\fileversion}{\filedescription}
%<package>\RequirePackage{l3expan}
%<package>\RequirePackage{l3num}
%<package>\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_<g/l>| 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
%</showmemory>
%</initex|package>
%    \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
%
