% \iffalse
%% File: l3intexpr.dtx Copyright (C) 2009 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/svnroot/experimental/trunk/
%%
%% 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: l3intexpr.dtx 1086 2009-03-20 19:29:35Z morten $
       {L3 Integer Expressions}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
%
% \title{The \textsf{l3intexpr} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Integer expressions}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
% \begin{documentation}
% 
% Calculation and comparison of integer values can be carried out
% using literal numbers, \texttt{int} registers, constants and
% integers stored in token list variables. The standard operators
% \texttt{+}, \texttt{-}, \texttt{/} and \texttt{*} and 
% parentheses can be used within such expressions to carry 
% arithmetic operations. This module carries out these functions
% on \emph{integer expressions} (`\texttt{int expr}').
%
%\section{Calculating and comparing integers}
%
% \begin{function}{\intexpr_eval:n / (EXP)}
% \begin{syntax}
%    "\intexpr_eval:n" \Arg{int~expr}
% \end{syntax}
%   Evaluates an <integer expression>, expanding to a properly
%   terminated <number> that can be used in any situation that
%   demands one, or which can be typeset. For example,
%\begin{verbatim}
%  \intexpr_eval:n{ 5 + 4*3 - (3+4*5) }
%\end{verbatim}   
% evaluates to \(-6\).  Two expansions are necessary to convert the
% <expression> into the <number> it represents. Full expansion to
% the <number> can be carried out using an \texttt{f} expansion
% in an expandable context or a \texttt{x} expansion in other 
% cases.
% \end{function}
%
%\begin{function}{
%  \intexpr_compare_p:n / (EXP) |
%  \intexpr_compare:n / (TF) (EXP)
%}
% \begin{syntax}
%    "\intexpr_compare_p:n" \Arg{<int~expr1> <rel> <int~expr2>}
%    "\intexpr_compare:nTF" \Arg{<int~expr1> <rel> <int~expr2>}
%    ~~~~<true code> <false code>
% \end{syntax}
% Evaluates <integer expression 1> and <integer expression 2> as
% described for \cs{intexpr_eval:n}, and then carries out a 
% comparison of the resulting integers using C-like operators:
% \begin{center}
%   \begin{tabular}{ll@{\hspace{2cm}}ll}
%     Less than & "<" & Less than or equal & "<=" \\
%     Greater than & "<" & Greater than or equal  &  ">=" \\
%     Equal &  "==" or "=" & Not equal & "!="
%   \end{tabular}
% \end{center}
% Based on the result of the comparison either the <true code>
% or <false code> is executed. Both integer expressions are evaluated 
% fully in the process. Note the syntax, which allows natural input in 
% the style of
% \begin{quote}
%    |\intexpr_compare_p:n {5+3 != \l_tmpb_int}|
% \end{quote}
% \texttt{=} is available as comparator (in addition to those
% familiar to C users) as standard \TeX\ practice is to compare
% values using a single \texttt{=}.
% \end{function}
% 
%
%\begin{function}{
%  \intexpr_compare_p:nNn / (EXP) |
%  \intexpr_compare:nNn / (TF)(EXP)
%}
% \begin{syntax}
%    "\intexpr_compare_p:nNn" \Arg{int~expr1} <rel> \Arg{int~expr2}
% \end{syntax}
% Evaluates <integer expression 1> and <integer expression 2> as
% described for \cs{intexpr_eval:n}, then compares the two
% results using one of the relations \texttt{=}, "<" or
% ">". These functions are faster than the \texttt{n}
% variants described above but do not support an extended set
% of relational operators. 
%\end{function}
%
%
%\begin{function}{
%  \intexpr_max:nn / (EXP)|
%  \intexpr_min:nn / (EXP)
%}
% \begin{syntax}
%   "\intexpr_max:nn" \Arg{int~expr1} \Arg{int~expr2}
% \end{syntax}
% Evaluates <integer expression 1> and <integer expression 2> as
% described for \cs{intexpr_eval:n}, expanding to the larger or
% smaller of the two resulting <numbers> (for \texttt{max} and 
% \texttt{min}, respectively).
% \end{function}
%
%\begin{function}{\intexpr_abs:n / (EXP)}
% \begin{syntax}
%   "\intexpr_abs:n" \Arg{int~expr}
% \end{syntax}
% Evaluates <integer expression> as described for \cs{intexpr_eval:n} 
% and expands to the absolute value of the resulting <number>.
% \end{function}
%
%\begin{function}{
%  \intexpr_if_odd:n / (EXP)(TF) |
%  \intexpr_if_odd_p:n / (EXP) |
%  \intexpr_if_even:n / (EXP)(TF) |
%  \intexpr_if_even_p:n / (EXP) |
%}
% \begin{syntax}
%   "\intexpr_if_odd:nTF" \Arg{int~expr} \Arg{true} \Arg{false}
% \end{syntax}
% Evaluates <integer expression> as described for \cs{intexpr_eval:n} 
% and execute <true code> or <false code> depending on whether
% the resulting <number> is odd or even.
% \end{function}
%
%\begin{function}{
%  \intexpr_div_truncate:nn / (EXP) |
%  \intexpr_div_round:nn / (EXP) |
% \intexpr_mod:nn / (EXP) |
%}
%  \begin{syntax}
%    "\intexpr_div_truncate:nn"   \Arg{int~expr1} \Arg{int~expr2}
%    "\intexpr_mod:nn"   \Arg{int~expr1} \Arg{int~expr2}
%  \end{syntax}
%  Evaluates <integer expression 1> and <integer expression 2> as
%  described for \cs{intexpr_eval:n}, expanding to the appropriate
%  result of division of the resulting <numbers>. The
%  \texttt{truncate} function expands to the integer part of the 
%  division with the decimal simply discarded, whereas
%  \texttt{round} will use the decimal part to round the integer 
%  up if appropriate. The \texttt{mod} function expands to the integer
%  remainder of the division.
%\end{function}
%
% \section{Primitive (internal) functions}
% 
%\begin{function}{
%  \if_num:w            / (EXP) |
%  \if_inexpr_compare:w / (EXP)
%}
%  \begin{syntax}
%    "\if_num:w" <number1> <rel> <number2> <true> "\else:" <false> "\fi:"
%  \end{syntax}
%  Compare two integers using <rel>, which must be one of
%  \texttt{=}, "<" or ">" with category code \(12\).
%  The \cs{else:} branch is optional. 
%  \begin{texnote}
%   These are both names for the \TeX\ primitive \cs{ifnum}.
%  \end{texnote}
%\end{function}
%
%\begin{function}{
%  \if_intexpr_case:w / (EXP) |
%  \if_case:w         / (EXP) |
%  \or:               / (EXP)
%}
%  \begin{syntax}
%    "\if_case:w" <number> <case0> "\or:" <case1> "\or:" "..." "\else:"
%    <default> "\fi:"
%  \end{syntax}
%  Selects a case to execute based on the value of <number>. The first
%  case (<case0>) is executed if <number> is \(0\), the second
%  (<case1>) if the <number> is \(1\), \emph{etc}. The
%  <number> may be a literal, a constant or an integer
%  expression (\emph{e.g}.~using \cs{intexpr_eval:n}).
%  \begin{texnote}
%    These are the \TeX\ primitives \cs{ifcase} (with two
%    different names depending on context)  and \cs{or}.
%  \end{texnote}
%\end{function}
%
%\begin{function}{\intexpr_value:w / (EXP)}
%  \begin{syntax}
%    "\intexpr_value:w" <integer> 
%    "\intexpr_value:w" <tokens>  <optional space>
%  \end{syntax}
%  Expands <tokens> until an <integer> is formed. One space may be
%  gobbled in the process. 
%  \begin{texnote}
%    This is the \TeX\ primitive \tn{number}.
%  \end{texnote}
%\end{function}
%
%\begin{function}{
%  \intexpr_eval:w   / (EXP) |
%  \intexpr_eval_end:
%}
%  \begin{syntax}
%    "\intexpr_eval:w" <int expr> "\intexpr_eval_end:"
%  \end{syntax}
%  Evaluates <integer expression> as described for \cs{intexpr_eval:n}.
%  The evalution stops when an unexpandable token with category code
%  other than \(12\) is read or when \cs{intexpr_eval_end:} is
%  reached. The latter is gobbled by the scanner mechanism:
%  \cs{intexpr_eval_end:} itself is unexpandable but used correctly
%  the entire construct is expandable.
%  \begin{texnote}
%   This is the \eTeX\ primitive \cs{numexpr}.
%  \end{texnote}
%\end{function}
%
%\begin{function}{\if_intexpr_odd:w / (EXP)}
%  \begin{syntax}
%    "\if_intexpr_odd:w" <tokens>  <true> "\else:" <false> "\fi:"
%    "\if_intexpr_odd:w" <number>  <true> "\else:" <false> "\fi:"
%  \end{syntax}
%  Expands <tokens> until a non-numeric tokens is found, and 
%  tests whether the resulting <number> is odd. If so, <true code>
%  is executed. The \cs{else:} branch is optional.
%  \begin{texnote}
%   This is the \TeX\ primitive \cs{ifodd}.
%  \end{texnote}
%\end{function}
%
%\begin{function}{
%  \intexpr_while_do:nn / (EXP) |
%  \intexpr_until_do:nn / (EXP) |
%  \intexpr_do_while:nn / (EXP) |
%  \intexpr_do_until:nn / (EXP) 
%}
% \begin{syntax}
%   "\intexpr_while_do:nn" \Arg{<int~expr1> <rel> <int~expr2>} \Arg{code}
% \end{syntax}
% In the case of the \texttt{while_do} version, the integer
% comparison is evaluated as described for \cs{intexpr_compare_p:n}, 
% and if \texttt{true} execute the <code>. The test and code then 
% alternate until the result is <false>. The \texttt{do_while}
% alternative first executes the <code> and then evaluates the integer
% comparison. In the \texttt{until} cases, the <code> is executed
% if the test is \texttt{false}: the loop is ended when the relation
% is \texttt{true}.
% \end{function}
%
%\begin{function}{
%  \intexpr_while_do:nNnn / (EXP) |
%  \intexpr_until_do:nNnn / (EXP) |
%  \intexpr_do_while:nNnn / (EXP) |
%  \intexpr_do_until:nNnn / (EXP) 
%}
% \begin{syntax}
%   "\intexpr_while_do:nNnn"   <int expr> <rel> <int~expr> \Arg{code}
% \end{syntax}
% These behave in the same manner as the preceding loops but use the
% relation logic described for \cs{intexpr_compare_p:nNn}.
%\end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3intexpr} implementation}
%
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
%</package>
%<*initex|package>
%    \end{macrocode}
%
% \begin{macro}{\if_num:w}
% \begin{macro}{\if_case:w}
%   Here are the remaining primitives for number comparisons and
%   expressions.
%    \begin{macrocode}
\cs_new_eq:NN \if_num:w           \tex_ifnum:D
\cs_new_eq:NN \if_case:w          \tex_ifcase:D
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\intexpr_value:w}
% \begin{macro}{\intexpr_eval:n,\intexpr_eval:w,\intexpr_eval_end:}
% \begin{macro}{\if_intexpr_compare:w}
% \begin{macro}{\if_intexpr_odd:w}
% \begin{macro}{\if_intexpr_case:w}
%   Here are the remaining primitives for number comparisons and
%   expressions.
%    \begin{macrocode}
\cs_set_eq:NN \intexpr_value:w \tex_number:D
\cs_set_eq:NN \intexpr_eval:w \etex_numexpr:D
\cs_set_protected:Npn \intexpr_eval_end: {\tex_relax:D}
\cs_set_eq:NN \if_intexpr_compare:w \tex_ifnum:D
\cs_set_eq:NN \if_intexpr_odd:w \tex_ifodd:D
\cs_set_eq:NN \if_intexpr_case:w \tex_ifcase:D
\cs_set:Npn \intexpr_eval:n #1{
  \intexpr_value:w \intexpr_eval:w #1\intexpr_eval_end:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
%
%
%
% \begin{macro}{\intexpr_compare_p:n}
% \begin{macro}[TF]{\intexpr_compare:n}
% Comparison tests using a simple syntax where only one set of braces
% is required and additional operators such as "!=" and ">=" are
% supported. First some notes on the idea behind this. We wish to
% support writing code like
% \begin{verbatim}
% \intexpr_compare_p:n { 5 + \l_tmpa_int != 4 - \l_tmpb_int }
% \end{verbatim}
% In other words, we want to somehow add the missing "\intexpr_eval:w"
% where required.  We can start evaluating from the left using
% "\intexpr:w", and we know that since the relation symbols "<", ">",
% "=" and "!" are not allowed in such expressions, they will terminate
% the expression. Therefore, we first let \TeX\ evaluate this left
% hand side of the (in)equality.
%    \begin{macrocode}
\prg_set_conditional:Npnn \intexpr_compare:n #1{p,TF,T,F}{
  \exp_after:wN \intexpr_compare_auxi:w \intexpr_value:w
    \intexpr_eval:w #1\q_stop
}
%    \end{macrocode}
% Then the next step is to figure out which relation we should use, so
% we have to somehow get rid of the first evaluation so that we can
% see what stopped it. "\tex_romannumeral:D" is handy here since its
% expansion given a non-positive number is \m{null}. We therefore
% simply check if the first token of the left hand side evaluation is
% a minus. If not, we insert it and issue "\tex_romannumeral:D",
% thereby ridding us of the left hand side evaluation. We do however
% save it for later.
%    \begin{macrocode}
\cs_set:Npn \intexpr_compare_auxi:w #1#2\q_stop{
   \exp_after:wN   \intexpr_compare_auxii:w \tex_romannumeral:D
   \if:w #1- \else: -\fi: #1#2 \q_stop #1#2 \q_nil
}
%    \end{macrocode}
% This leaves the first relation symbol in front and assuming the
% right hand side has been input, at least one other token as well. We
% support the following forms: |=|, |<|, |>| and the extended |!=|,
% |==|, |<=| and |>=|. All the extended forms have an extra |=| so we
% check if that is present as well. Then use specific function to
% perform the test.
%    \begin{macrocode}
\cs_set:Npn \intexpr_compare_auxii:w #1#2#3\q_stop{ 
   \use:c{
     intexpr_compare_ 
     #1  \if_meaning:w =#2 =  \fi:
     :w}  
}
%    \end{macrocode}
% The actual comparisons are then simple function calls, using the
% relation as delimiter for a delimited argument.
% Equality is easy:
%    \begin{macrocode}
\cs_set:cpn {intexpr_compare_=:w} #1=#2\q_nil{
  \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: 
    \prg_return_true: \else: \prg_return_false: \fi:
}
%    \end{macrocode}
% So is the one using |==| -- we just have to use |==| in the
% parameter text.
%    \begin{macrocode}
\cs_set:cpn {intexpr_compare_==:w} #1==#2\q_nil{
  \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: 
  \prg_return_true: \else: \prg_return_false: \fi:
}
%    \end{macrocode}
% Not equal is just about reversing the truth value.
%    \begin{macrocode}
\cs_set:cpn {intexpr_compare_!=:w} #1!=#2\q_nil{
  \if_intexpr_compare:w #1=\intexpr_eval:w #2 \intexpr_eval_end: 
  \prg_return_false: \else: \prg_return_true: \fi:
}
%    \end{macrocode}
% Less than and greater than are also straight forward.
%    \begin{macrocode}
\cs_set:cpn {intexpr_compare_<:w} #1<#2\q_nil{
  \if_intexpr_compare:w #1<\intexpr_eval:w #2 \intexpr_eval_end: 
  \prg_return_true: \else: \prg_return_false: \fi:
}
\cs_set:cpn {intexpr_compare_>:w} #1>#2\q_nil{
  \if_intexpr_compare:w #1>\intexpr_eval:w #2 \intexpr_eval_end:
  \prg_return_true: \else: \prg_return_false: \fi:
}
%    \end{macrocode}
% The less than or equal operation is just the opposite of the greater
% than operation. Vice versa for less than or equal.
%    \begin{macrocode}
\cs_set:cpn {intexpr_compare_<=:w} #1<=#2\q_nil{
  \if_intexpr_compare:w #1>\intexpr_eval:w #2 \intexpr_eval_end: 
  \prg_return_false: \else: \prg_return_true: \fi:
}
\cs_set:cpn {intexpr_compare_>=:w} #1>=#2\q_nil{
  \if_intexpr_compare:w #1<\intexpr_eval:w #2 \intexpr_eval_end:
  \prg_return_false: \else: \prg_return_true: \fi:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\intexpr_compare_p:nNn}
% \begin{macro}[TF]{\intexpr_compare:nNn}
% More efficient but less natural in typing.
%    \begin{macrocode}
\prg_set_conditional:Npnn \intexpr_compare:nNn #1#2#3{p,TF,T,F}{
  \if_intexpr_compare:w \intexpr_eval:w #1 #2 \intexpr_eval:w #3
  \intexpr_eval_end:
  \prg_return_true: \else: \prg_return_false: \fi:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\intexpr_max:nn}
% \begin{macro}{\intexpr_min:nn}
% \begin{macro}{\intexpr_abs:n}
% Functions for $\min$, $\max$, and absolute value.
%    \begin{macrocode}
\cs_set:Npn \intexpr_abs:n #1{
  \intexpr_value:w 
  \if_intexpr_compare:w \intexpr_eval:w #1<\c_zero 
    -
  \fi:
  \intexpr_eval:w #1\intexpr_eval_end:
}
\cs_set:Npn \intexpr_max:nn #1#2{
  \intexpr_value:w \intexpr_eval:w 
    \if_intexpr_compare:w 
      \intexpr_eval:w #1>\intexpr_eval:w #2\intexpr_eval_end: 
      #1
    \else:
      #2
    \fi:
  \intexpr_eval_end:
}
\cs_set:Npn \intexpr_min:nn #1#2{
  \intexpr_value:w \intexpr_eval:w 
    \if_intexpr_compare:w 
      \intexpr_eval:w #1<\intexpr_eval:w #2\intexpr_eval_end: 
      #1
    \else:
      #2
    \fi:
  \intexpr_eval_end:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\intexpr_div_truncate:nn}
% \begin{macro}{\intexpr_div_round:nn}
% \begin{macro}{\intexpr_mod:nn}
% As "\intexpr_eval:w" rounds the result of a division we also
% provide a version that truncates the result.
%    \begin{macrocode}
%    \end{macrocode}
%    Initial version didn't work correctly with e\TeX's implementation.    
%    \begin{macrocode}
%\cs_set:Npn \intexpr_div_truncate_raw:nn #1#2 {
%  \intexpr_eval:n{ (2*#1 - #2) / (2* #2) }
%}
%    \end{macrocode}
%    New version by Heiko:
%    \begin{macrocode}
\cs_set:Npn \intexpr_div_truncate:nn #1#2 {
  \intexpr_value:w \intexpr_eval:w
    \if_intexpr_compare:w \intexpr_eval:w #1 = \c_zero
      0
    \else:
      (#1
      \if_intexpr_compare:w \intexpr_eval:w #1 < \c_zero
        \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero
          -( #2 +
        \else:   
          +( #2 -
        \fi:
      \else:
        \if_intexpr_compare:w \intexpr_eval:w #2 < \c_zero
          +( #2 + 
        \else:   
          -( #2 -
        \fi:
      \fi:  
      1)/2)
    \fi:
    /(#2)
  \intexpr_eval_end:  
}
%    \end{macrocode}
% For the sake of completeness:
%    \begin{macrocode}
\cs_set:Npn \intexpr_div_round:nn #1#2 {\intexpr_eval:n{(#1)/(#2)}}
%    \end{macrocode}
% Finally there's the modulus operation.
%    \begin{macrocode}
\cs_set:Npn \intexpr_mod:nn #1#2 {
  \intexpr_value:w 
    \intexpr_eval:w  
    #1 - \intexpr_div_truncate:nn {#1}{#2} * (#2) 
    \intexpr_eval_end:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\intexpr_if_odd_p:n}
% \begin{macro}[TF]{\intexpr_if_odd:n}
% \begin{macro}{\intexpr_if_even_p:n}
% \begin{macro}[TF]{\intexpr_if_even:n}
% A predicate function.
%    \begin{macrocode}
\prg_set_conditional:Npnn \intexpr_if_odd:n #1 {p,TF,T,F} {
  \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end:
    \prg_return_true: \else: \prg_return_false: \fi:
}
\prg_set_conditional:Npnn \intexpr_if_even:n #1 {p,TF,T,F} {
  \if_intexpr_odd:w \intexpr_eval:w #1\intexpr_eval_end:
    \prg_return_false: \else: \prg_return_true: \fi:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\intexpr_while_do:nn}
% \begin{macro}{\intexpr_until_do:nn}
% \begin{macro}{\intexpr_do_while:nn}
% \begin{macro}{\intexpr_do_until:nn}
%  These are quite easy given the above functions. The "while" versions
%  test first and then execute the body. The "do_while" does it the
%  other way round. 
%    \begin{macrocode}
\cs_set:Npn \intexpr_while_do:nn #1#2{
  \intexpr_compare:nT {#1}{#2 \intexpr_while_do:nn {#1}{#2}}
}
\cs_set:Npn \intexpr_until_do:nn #1#2{
  \intexpr_compare:nF {#1}{#2 \intexpr_until_do:nn {#1}{#2}}
}
\cs_set:Npn \intexpr_do_while:nn #1#2{
  #2 \intexpr_compare:nT {#1}{\intexpr_do_while:nNnn {#1}{#2}}
}
\cs_set:Npn \intexpr_do_until:nn #1#2{
  #2 \intexpr_compare:nF {#1}{\intexpr_do_until:nn {#1}{#2}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\intexpr_while_do:nNnn}
% \begin{macro}{\intexpr_until_do:nNnn}
% \begin{macro}{\intexpr_do_while:nNnn}
% \begin{macro}{\intexpr_do_until:nNnn}
%  As above but not using the more natural syntax. 
%    \begin{macrocode}
\cs_set:Npn \intexpr_while_do:nNnn #1#2#3#4{
  \intexpr_compare:nNnT {#1}#2{#3}{#4 \intexpr_while_do:nNnn {#1}#2{#3}{#4}}
}
\cs_set:Npn \intexpr_until_do:nNnn #1#2#3#4{
  \intexpr_compare:nNnF {#1}#2{#3}{#4 \intexpr_until_do:nNnn {#1}#2{#3}{#4}}
}
\cs_set:Npn \intexpr_do_while:nNnn #1#2#3#4{
  #4 \intexpr_compare:nNnT {#1}#2{#3}{\intexpr_do_while:nNnn {#1}#2{#3}{#4}}
}
\cs_set:Npn \intexpr_do_until:nNnn #1#2#3#4{
  #4 \intexpr_compare:nNnF {#1}#2{#3}{\intexpr_do_until:nNnn {#1}#2{#3}{#4}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% 
%\begin{macro}{\c_max_register_int}
% This is here as this particular integer is needed both in package
% mode and to bootstrap \pkg{l3alloc}
%    \begin{macrocode}
\tex_mathchardef:D \c_max_register_int = 32767 \scan_stop:
%    \end{macrocode}
%  \end{macro}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
% \PrintIndex
%
% \endinput
