[latex3-commits] [git/LaTeX3-latex3-latex3] luaintarray: Lua based intarrays (398cacf4d)

Marcel Fabian Krüger tex at 2krueger.de
Mon Nov 15 15:24:22 CET 2021


Repository : https://github.com/latex3/latex3
On branch  : luaintarray
Link       : https://github.com/latex3/latex3/commit/398cacf4d2e99b1da1031d1c56e10bd2b431f068

>---------------------------------------------------------------

commit 398cacf4d2e99b1da1031d1c56e10bd2b431f068
Author: Marcel Fabian Krüger <tex at 2krueger.de>
Date:   Mon Aug 10 21:40:33 2020 +0200

    Lua based intarrays


>---------------------------------------------------------------

398cacf4d2e99b1da1031d1c56e10bd2b431f068
 l3kernel/l3.ins                                    |   3 +-
 l3kernel/l3bootstrap.dtx                           |   1 +
 l3kernel/l3intarray.dtx                            | 443 ++++++++++++++++++++-
 l3kernel/l3luatex.dtx                              |  79 ++++
 l3kernel/testfiles/m3intarray001.luatex.tlg        |  63 +--
 l3kernel/testfiles/m3intarray001.lvt               |   4 +-
 .../{m3skip001.tlg => m3skip001.luatex.tlg}        |  18 +-
 .../{m3skip005.tlg => m3skip005.luatex.tlg}        |  22 +-
 8 files changed, 541 insertions(+), 92 deletions(-)

diff --git a/l3kernel/l3.ins b/l3kernel/l3.ins
index 34a46aaed..265fde8ac 100644
--- a/l3kernel/l3.ins
+++ b/l3kernel/l3.ins
@@ -78,7 +78,7 @@ and all files in that bundle must be distributed together.
         \from{l3file.dtx}       {package}
         \from{l3skip.dtx}       {package}
         \from{l3keys.dtx}       {package}
-        \from{l3intarray.dtx}   {package}
+        \from{l3intarray.dtx}   {package,tex}
         \from{l3fp.dtx}         {package}
         \from{l3fp-aux.dtx}     {package}
         \from{l3fp-traps.dtx}   {package}
@@ -171,6 +171,7 @@ and all files in that bundle must be distributed together.
   \from{l3names.dtx}{package,lua}
   \from{l3sys.dtx}{package,lua}
   \from{l3token.dtx}{package,lua}
+  \from{l3intarray.dtx}{package,lua}
 }}
 
 \endbatchfile
diff --git a/l3kernel/l3bootstrap.dtx b/l3kernel/l3bootstrap.dtx
index 381473373..795f65ae3 100644
--- a/l3kernel/l3bootstrap.dtx
+++ b/l3kernel/l3bootstrap.dtx
@@ -194,6 +194,7 @@
     \expandafter\ifx\csname newcatcodetable\endcsname\relax
       \input{ltluatex}%
     \fi
+    \ifdefined\newluabytecode\newluabytecode\@expl at luadata@bytecode\fi
     \directlua{require("expl3")}%
 %    \end{macrocode}
 %   As the user might be making a custom format, no assumption is made about
diff --git a/l3kernel/l3intarray.dtx b/l3kernel/l3intarray.dtx
index 3d95e6e04..fd7ecd8bd 100644
--- a/l3kernel/l3intarray.dtx
+++ b/l3kernel/l3intarray.dtx
@@ -173,15 +173,15 @@
 %<@@=intarray>
 %    \end{macrocode}
 %
-% \subsection{Allocating arrays}
+% There are two implementations for this module: One \cs{fontdimen} based one
+% for more traditional \TeX\ engines and a Lua based one for engines with Lua support.
 %
-% \begin{macro}{\@@_entry:w, \@@_count:w}
-%   We use these primitives quite a lot in this module.
+% Both versions do not allow negative array sizes.
 %    \begin{macrocode}
-\cs_new_eq:NN \@@_entry:w \tex_fontdimen:D
-\cs_new_eq:NN \@@_count:w \tex_hyphenchar:D
+%<*tex>
+\msg_new:nnn { kernel } { negative-array-size }
+  { Size~of~array~may~not~be~negative:~#1 }
 %    \end{macrocode}
-% \end{macro}
 %
 % \begin{variable}{\l_@@_loop_int}
 %   A loop index.
@@ -190,6 +190,419 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \subsection{Lua implementation}
+% First, let's look at the Lua variant:
+%
+% We select the Lua version if the Lua helpers were defined. This can be detected by
+% the presence of \cs{@@_gset_count:Nw}.
+%
+%    \begin{macrocode}
+\cs_if_exist:NTF \@@_gset_count:Nw
+{
+%    \end{macrocode}
+%
+% \subsubsection{Allocating arrays}
+%
+% \begin{variable}{\g_@@_table_int, \l_@@_bad_index_int}
+%   Used to differentiate intarrays in Lua and to record an invalid index.
+%    \begin{macrocode}
+\int_new:N \g_@@_table_int
+\int_new:N \l_@@_bad_index_int
+%</tex>
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@:w}
+%   Used as marker for intarrays in Lua. Followed by an unbraced number
+%   identifying the array and a single space. This format is used to make it
+%   easy to scan from Lua.
+%    \begin{macrocode}
+%<*lua>
+luacmd('@@:w', function()
+  scan_int()
+  tex.error'LaTeX Error: Isolated intarray ignored'
+end, 'protected', 'global')
+%</lua>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_new:Nn, \intarray_new:cn}
+% \begin{macro}{\@@_new:N}
+%   Declare |#1| as a tokenlist with the scanmark and a unique number.
+%   Pass the array's size to the Lua helper.
+%   Every \texttt{intarray} must be global; it's enough to run this
+%   check in \cs{intarray_new:Nn}.
+%    \begin{macrocode}
+%<*tex>
+\cs_new_protected:Npn \@@_new:N #1
+  {
+    \__kernel_chk_if_free_cs:N #1
+    \int_gincr:N \g_@@_table_int
+    \cs_gset_nopar:Npx #1 { \@@:w \int_use:N \g_@@_table_int \c_space_tl }
+  }
+\cs_new_protected:Npn \intarray_new:Nn #1#2
+  {
+    \@@_new:N #1
+    \@@_gset_count:Nw #1 \int_eval:n {#2} \scan_stop:
+    \int_compare:nNnT { \intarray_count:N #1 } < 0
+      {
+        \msg_error:nnx { kernel } { negative-array-size }
+          { \intarray_count:N #1 }
+      }
+  }
+\cs_generate_variant:Nn \intarray_new:Nn { c }
+%</tex>
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Before we get to the first command implmented in Lua, we first need some
+% definitions. Since \texttt{token.create} only works correctly if \TeX{}
+% has seen the tokens before, we first run a short \TeX{} sequence to ensure
+% that all relevant control sequences are known.
+%    \begin{macrocode}
+%<*lua>
+
+local scan_token = token.scan_token
+local put_next = token.put_next
+local intarray_marker = token_create_safe'@@:w'
+local use_none = token_create_safe'use_none:n'
+local use_i = token_create_safe'use:n'
+local expand_after_scan_stop = {token_create_safe'exp_after:wN',
+                                token_create_safe'scan_stop:'}
+local comma = token_create(string.byte',')
+%    \end{macrocode}
+%
+% \begin{macro}{@@_table}
+%   Internal helper to scan an intarray token, extract the associated
+%   Lua table and return an error if the input is invalid.
+%
+%    \begin{macrocode}
+local @@_table do
+  local tables = get_luadata and get_luadata'@@' or {[0] = {}}
+  function @@_table()
+    local t = scan_token()
+    if t ~= intarray_marker then
+      put_next(t)
+      tex.error'LaTeX Error: intarray expected'
+      return tables[0]
+    end
+    local i = scan_int()
+    local current_table = tables[i]
+    if current_table then return current_table end
+    current_table = {}
+    tables[i] = current_table
+    return current_table
+  end
+%    \end{macrocode}
+% Since in \LaTeX{} this is loaded in the format, we want to preserve any intarrays
+% which are created while format building for the actual run.
+%
+% To do this, we use the \texttt{register_luadata} mechanism from \pkg{l3luatex}:
+% Directly before the format get dumped, the following function gets invoked and serializes
+% all existing tables into a string. This string gets compiled and dumped into the format and
+% is made available at the beginning of regular runs as \texttt{get_luadata'@@'}.
+%    \begin{macrocode}
+  if register_luadata then
+    register_luadata('@@', function()
+      local t = "{[0]={},"
+      for i=1, #tables do
+        t = string.format("%s{%s},", t, table.concat(tables[i], ','))
+      end
+      return t .. "}"
+    end)
+  end
+end
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\intarray_count:N, \intarray_count:c}
+% \begin{macro}[EXP]{\@@_gset_count:Nw}
+%   Set and get the size of an array. ``Setting the size'' means in this context that
+%   we add zeros until we reach the desired size.
+%    \begin{macrocode}
+
+local sprint = tex.sprint
+
+luacmd('@@_gset_count:Nw', function()
+  local t = @@_table()
+  local n = scan_int()
+  for i=#t+1, n do t[i] = 0 end
+end, 'protected', 'global')
+
+luacmd('intarray_count:N', function()
+  sprint(-2, #@@_table())
+end, 'global')
+%</lua>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*tex>
+\cs_generate_variant:Nn \intarray_count:N { c }
+%</tex>
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsubsection{Array items}
+%
+% \begin{macro}{\@@_gset:wF, \@@_gset:w}
+%   The setter provided by Lua. The argument order somewhat emulates the |\fontdimen|:
+%   First the array index, followed by the intarray and then the new value.
+%   This has been chosen over a more conventional order to provide a delimiter for the numbers.
+%    \begin{macrocode}
+%<*lua>
+luacmd('@@_gset:wF', function()
+  local i = scan_int()
+  local t = @@_table()
+  if t[i] then
+    t[i] = scan_int()
+    put_next(use_none)
+  else
+    tex.count.l_@@_bad_index_int = i
+    scan_int()
+    put_next(use_i)
+  end
+end, 'protected', 'global')
+
+luacmd('@@_gset:w', function()
+  local i = scan_int()
+  local t = @@_table()
+  t[i] = scan_int()
+end, 'protected', 'global')
+%</lua>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_gset:Nnn, \intarray_gset:cnn, \__kernel_intarray_gset:Nnn}
+%   The \cs{__kernel_intarray_gset:Nnn} function does not use
+%   \cs{int_eval:n}, namely its arguments must be suitable for
+%   \cs{int_value:w}.  The user version checks the position and value
+%   are within bounds.
+%    \begin{macrocode}
+%<*tex>
+\cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3
+{ \@@_gset:w #2 #1 #3 \scan_stop: }
+\cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
+  {
+    \@@_gset:wF \int_eval:n {#2} #1 \int_eval:n{#3}
+      {
+        \msg_error:nnxxx { kernel } { out-of-bounds }
+          { \token_to_str:N #1 } { \int_use:N \l_@@_bad_index_int } { \intarray_count:N #1 }
+      }
+  }
+\cs_generate_variant:Nn \intarray_gset:Nnn { c }
+%</tex>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\intarray_gzero:N, \intarray_gzero:c}
+%   Set the appropriate array entry to zero.  No bound checking
+%   needed.
+%    \begin{macrocode}
+%<*lua>
+luacmd('intarray_gzero:N', function()
+  local t = @@_table()
+  for i=1, #t do
+    t[i] = 0
+  end
+end, 'global', 'protected')
+%</lua>
+%<*tex>
+\cs_generate_variant:Nn \intarray_gzero:N { c }
+%</tex>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\intarray_item:Nn, \intarray_item:cn, \__kernel_intarray_item:Nn}
+% \begin{macro}{\@@_item:wF,\@@_item:w}
+%   Get the appropriate entry and perform bound checks.  The
+%   \cs{__kernel_intarray_item:Nn} function omits bound checks and omits
+%   \cs{int_eval:n}, namely its argument must be a \TeX{} integer
+%   suitable for \cs{int_value:w}.
+%    \begin{macrocode}
+%<*lua>
+luacmd('@@_item:wF', function()
+  local i = scan_int()
+  local t = @@_table()
+  local item = t[i]
+  if item then
+    put_next(use_none)
+  else
+    tex.l_@@_bad_index_int = i
+    put_next(use_i)
+  end
+  put_next(expand_after_scan_stop)
+  scan_token()
+  if item then
+    sprint(-2, item)
+  end
+end, 'global')
+
+luacmd('@@_item:w', function()
+  local i = scan_int()
+  local t = @@_table()
+  sprint(-2, t[i])
+end, 'global')
+%</lua>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*tex>
+\cs_new:Npn \__kernel_intarray_item:Nn #1#2
+  { \@@_item:w #2 #1 }
+\cs_new:Npn \intarray_item:Nn #1#2
+  {
+    \@@_item:wF \int_eval:n {#2} #1
+      {
+        \msg_expandable_error:nnfff { kernel } { out-of-bounds }
+          { \token_to_str:N #1 } { \int_use:N \l_@@_bad_index_int } { \intarray_count:N #1 }
+        0
+      }
+  }
+\cs_generate_variant:Nn \intarray_item:Nn { c }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\intarray_rand_item:N, \intarray_rand_item:c}
+%   Importantly, \cs{intarray_item:Nn} only evaluates its argument once.
+%    \begin{macrocode}
+\cs_new:Npn \intarray_rand_item:N #1
+  { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } }
+\cs_generate_variant:Nn \intarray_rand_item:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Working with contents of integer arrays}
+%
+% \begin{macro}{\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn}
+%   We use the \cs{__kernel_intarray_gset:Nnn} which does not do bounds checking
+%   and instead automatically resizes the array.
+%   This is not implemented in Lua to ensure that the clist parsing is consistent
+%   with the clist module.
+%    \begin{macrocode}
+\cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2
+  {
+    \@@_new:N #1
+    \int_zero:N \l_@@_loop_int
+    \clist_map_inline:nn {#2}
+      {
+        \int_incr:N \l_@@_loop_int
+        \__kernel_intarray_gset:Nnn #1 \l_@@_loop_int { \int_eval:n {##1} } }
+  }
+\cs_generate_variant:Nn \intarray_const_from_clist:Nn { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\intarray_to_clist:N, \intarray_to_clist:c}
+% \begin{macro}[rEXP]{\@@_to_clist:Nn, \@@_to_clist:w}
+%   The \cs{@@_to_clist:Nn} auxiliary allows to choose the delimiter and
+%   is also used in \cs{intarray_show:N}. Here we just pass the information
+%   to Lua and let \texttt{table.concat} do the actual work.
+%   We discard the category codes of the passed delimiter but this is not
+%   an issue since the delimiter is always just a comma or a comma and a space.
+%   In both cases \texttt{sprint(2, ...)} provides the right catcodes.
+%    \begin{macrocode}
+\cs_new:Npn \intarray_to_clist:N #1 { \@@_to_clist:Nn #1 { , } }
+\cs_generate_variant:Nn \intarray_to_clist:N { c }
+%</tex>
+%<*lua>
+local concat = table.concat
+luacmd('@@_to_clist:Nn', function()
+  local t = @@_table()
+  local sep = token.scan_string()
+  sprint(-2, concat(t, sep))
+end, 'global')
+%</lua>
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[rEXP]{\__kernel_intarray_range_to_clist:Nnn, \@@_range_to_clist:w}
+%   Loop through part of the array.
+%    \begin{macrocode}
+%<*tex>
+\cs_new:Npn \__kernel_intarray_range_to_clist:Nnn #1#2#3
+  {
+    \@@_range_to_clist:w #1
+    \int_eval:n {#2} ~ \int_eval:n {#3} ~
+  }
+%</tex>
+%<*lua>
+luacmd('@@_range_to_clist:w', function()
+  local t = @@_table()
+  local from = scan_int()
+  local to = scan_int()
+  sprint(-2, concat(t, ',', from, to))
+end, 'global')
+%</lua>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_intarray_gset_range_from_clist:Nnn, \@@_gset_range:nNw}
+%   Loop through part of the array. We allow additional commas at the end.
+%    \begin{macrocode}
+%<*tex>
+\cs_new_protected:Npn \__kernel_intarray_gset_range_from_clist:Nnn #1#2#3
+  {
+    \@@_gset_range:w \int_eval:w #2 #1 #3 , , \scan_stop:
+  }
+%</tex>
+%<*lua>
+luacmd('@@_gset_range:w', function()
+  local from = scan_int()
+  local t = @@_table()
+  while true do
+    local tok = scan_token()
+    if tok == comma then
+      repeat
+        tok = scan_token()
+      until tok ~= comma
+      break
+    else
+      put_next(tok)
+    end
+    t[from] = scan_int()
+    scan_token()
+    from = from + 1
+  end
+  end, 'global', 'protected')
+%</lua>
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_gset_overflow_test:nw}
+%   In order to allow some code sharing later we provide the
+%   \cs{@@_gset_overflow_test:nw} name here. It doesn't actually test anything
+%   since the Lua implementation accepts all integers which could be tested with
+%   \cs{tex_ifabsnum:D}.
+%    \begin{macrocode}
+%<*tex>
+\cs_new_protected:Npn \@@_gset_overflow_test:nw #1
+  {
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Font dimension based implementation}
+%
+% Go to the false branch of the conditional above.
+%    \begin{macrocode}
+}
+{
+%    \end{macrocode}
+%
+% \subsubsection{Allocating arrays}
+%
+% \begin{macro}{\@@_entry:w, \@@_count:w}
+%   We use these primitives quite a lot in this module.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_entry:w \tex_fontdimen:D
+\cs_new_eq:NN \@@_count:w \tex_hyphenchar:D
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{variable}{\c_@@_sp_dim}
 %   Used to convert integers to dimensions fast.
 %    \begin{macrocode}
@@ -204,11 +617,6 @@
 %    \end{macrocode}
 % \end{variable}
 %
-%    \begin{macrocode}
-\msg_new:nnn { kernel } { negative-array-size }
-  { Size~of~array~may~not~be~negative:~#1 }
-%    \end{macrocode}
-%
 % \begin{macro}{\intarray_new:Nn, \intarray_new:cn}
 % \begin{macro}{\@@_new:N}
 %   Declare |#1| to be a font (arbitrarily |cmr10| at a never-used
@@ -255,7 +663,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Array items}
+% \subsubsection{Array items}
 %
 % \begin{macro}[EXP]{\@@_signed_max_dim:n}
 %   Used when an item to be stored is larger than \cs{c_max_dim} in
@@ -400,7 +808,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Working with contents of integer arrays}
+% \subsubsection{Working with contents of integer arrays}
 %
 % \begin{macro}{\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn}
 % \begin{macro}{\@@_const_from_clist:nN}
@@ -506,6 +914,12 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%    \begin{macrocode}
+}
+%    \end{macrocode}
+%
+% \subsection{Common parts}
+%
 % \begin{macro}{\intarray_show:N, \intarray_show:c, \intarray_log:N, \intarray_log:c}
 %   Convert the list to a comma list (with spaces after each comma)
 %    \begin{macrocode}
@@ -527,7 +941,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Random arrays}
+% \subsubsection{Random arrays}
 %
 % \begin{macro}{\intarray_gset_rand:Nn, \intarray_gset_rand:cn}
 % \begin{macro}{\intarray_gset_rand:Nnn, \intarray_gset_rand:cnn}
@@ -624,6 +1038,7 @@
 % \end{macro}
 %
 %    \begin{macrocode}
+%</tex>
 %</package>
 %    \end{macrocode}
 %
diff --git a/l3kernel/l3luatex.dtx b/l3kernel/l3luatex.dtx
index 4a3e32f9d..99805d6e7 100644
--- a/l3kernel/l3luatex.dtx
+++ b/l3kernel/l3luatex.dtx
@@ -703,6 +703,85 @@ end
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Preserving iniTeX Lua data for runs}
+%
+%    \begin{macrocode}
+%<@@=lua>
+%    \end{macrocode}
+%
+% The Lua state is not dumped when a forat is written, therefore any Lua
+% variables filled doing format building need to be restored in order to
+% be accessible during normal runs.
+%
+% We provide some kernel-internal helpers for this. They will only be available if
+% \texttt{luatexbase} is available. This is not a big restriction though, because
+% Con\TeX{}t (which does not use \texttt{luatexbase}) does not load \pkg{expl3}
+% in the format.
+%
+%    \begin{macrocode}
+local register_luadata, get_luadata
+
+if luatexbase then
+  local register = token_create'@expl at luadata@bytecode'.index
+  if status.ini_version then
+%    \end{macrocode}
+%
+% \begin{macro}{register_luadata}
+% \texttt{register_luadata} is only available during format generation.
+% It accept a string which uniquely identifies the data object and has to be
+% provided to retrieve it later. Additionally it accepts a function which is
+% called in the \texttt{pre_dump} callback and which has to return a string that
+% evaluates to a valid Lua object to be preserved.
+%    \begin{macrocode}
+    local luadata, luadata_order = {}, {}
+
+    function register_luadata(name, func)
+      if luadata[name] then
+        error(format("LaTeX error: data name %q already in use", name))
+      end
+      luadata[name] = func
+      luadata_order[#luadata_order + 1] = func and name
+    end
+%    \end{macrocode}
+% \end{macro}
+% 
+% The actual work is done in \texttt{pre_dump}. The \texttt{luadata_order} is used
+% to ensure that the order is consistent over multiple runs.
+%    \begin{macrocode}
+    luatexbase.add_to_callback("pre_dump", function()
+      if next(luadata) then
+        local str = "return {"
+        for i=1, #luadata_order do
+          local name = luadata_order[i]
+          str = format('%s[%q]=%s,', str, name, luadata[name]())
+        end
+        lua.bytecode[register] = assert(load(str .. "}"))
+      end
+    end, "ltx.luadata")
+  else
+%    \end{macrocode}
+%
+% \begin{macro}{get_luadata}
+% \texttt{get_luadata} is only available if data should be restored.
+% It accept the identifier which was used when the data object was registered and
+% returns the associated object. Every object can only be retrieved once.
+%    \begin{macrocode}
+    local luadata = lua.bytecode[register]
+    if luadata then
+      lua.bytecode[register] = nil
+      luadata = luadata()
+    end
+    function get_luadata(name)
+      if not luadata then return end
+      local data = luadata[name]
+      luadata[name] = nil
+      return data
+    end
+  end
+end
+%    \end{macrocode}
+% \end{macro}
+%
 %    \begin{macrocode}
 %</lua>
 %    \end{macrocode}
diff --git a/l3kernel/testfiles/m3intarray001.luatex.tlg b/l3kernel/testfiles/m3intarray001.luatex.tlg
index c05361920..3fd3c31ac 100644
--- a/l3kernel/testfiles/m3intarray001.luatex.tlg
+++ b/l3kernel/testfiles/m3intarray001.luatex.tlg
@@ -22,7 +22,7 @@ This is a coding error.
 LaTeX has been asked to create a new control sequence '\g_testa_intarray' but
 this name has already been used elsewhere.
 The current meaning is:
-  select font cmr10 at 0.00014pt
+  macro:->\__intarray:w 9 
 Defining \g_testa_intarray on line ...
 ! LaTeX3 Error: Access to an entry beyond an array's bounds.
 For immediate help type H <return>.
@@ -30,13 +30,6 @@ For immediate help type H <return>.
 l. ...  }
 An attempt was made to access or store data at position 0 of the array
 '\g_testa_intarray', but this array has entries at positions from 1 to 12.
-! LaTeX3 Error: Integers larger than 2^{30}-1 cannot be stored in arrays.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-An attempt was made to store -2000000000 at position 1 in the array
-'\g_testa_intarray'. The largest allowed value -1073741823 will be used
-instead.
 ! LaTeX3 Error: Access to an entry beyond an array's bounds.
 For immediate help type H <return>.
  ...                                              
@@ -52,7 +45,7 @@ put `1' after `\a', since control sequence names are
 made up of letters only. The macro here has not been
 followed by the required stuff, so I'm ignoring it.
 0
--1073741823
+-2000000000
 0
 ! Use of \??? doesn't match its definition.
 <argument> \???  
@@ -68,40 +61,12 @@ followed by the required stuff, so I'm ignoring it.
 TEST 3: Unsafe array operations with errors
 ============================================================
 Defining \g_testb_intarray on line ...
-! Font \g_testb_intarray has only 15 fontdimen parameters.
-<recently read> \g_testb_intarray 
-l. ...  }
-To increase the number of font parameters, you must
-use \fontdimen immediately after the \font is loaded.
-! Dimension too large.
-<recently read> \c__intarray_sp_dim 
-l. ...  }
-I can't work with sizes bigger than about 19 feet.
-Continue and I'll use the largest value I can.
-! Dimension too large.
-<recently read> \c__intarray_sp_dim 
-l. ...  }
-I can't work with sizes bigger than about 19 feet.
-Continue and I'll use the largest value I can.
-! Font \g_testb_intarray has only 16 fontdimen parameters.
-<recently read> \g_testb_intarray 
-l. ...  }
-To increase the number of font parameters, you must
-use \fontdimen immediately after the \font is loaded.
-0
--1073741823
+2000000000
+-2000000000
 0
 123456
-0
 1234567
 Defining \g_testc_intarray on line ...
-! LaTeX3 Error: Size of array may not be negative: -1
-Type <return> to continue.
- ...                                              
-l. ...  }
-LaTeX does not know anything more about this error, sorry.
-Try typing <return> to proceed.
-If that doesn't work, type X <return> to quit.
 12345678
 ============================================================
 ============================================================
@@ -114,11 +79,11 @@ TEST 5: Zeroing
 ============================================================
 0,0,24,0,0,0,0,28,0,0
 The integer array \g_testd_intarray contains 10 items:
->  0, 0, 24, 0, 0, 0, 0, 28, 0, 0.
+> 0, 0, 24, 0, 0, 0, 0, 28, 0, 0.
 24
 0,0,0,0,0,0,0,20,0,0
 The integer array \g_testd_intarray contains 10 items:
->  0, 0, 0, 0, 0, 0, 0, 20, 0, 0.
+> 0, 0, 0, 0, 0, 0, 0, 20, 0, 0.
 <recently read> }
 l. ...  }
 0
@@ -127,19 +92,5 @@ l. ...  }
 TEST 6: Const
 ============================================================
 Defining \c_teste_intarray on line ...
-! LaTeX3 Error: Integers larger than 2^{30}-1 cannot be stored in arrays.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-An attempt was made to store -1073741824 at position \l__intarray_loop_int  in
-the array '\c_teste_intarray'. The largest allowed value -1073741823 will be
-used instead.
-! LaTeX3 Error: Integers larger than 2^{30}-1 cannot be stored in arrays.
-For immediate help type H <return>.
- ...                                              
-l. ...  }
-An attempt was made to store 1073741824 at position \l__intarray_loop_int  in
-the array '\c_teste_intarray'. The largest allowed value 1073741823 will be
-used instead.
-7,43,-1073741823,1073741823
+7,43,-1073741824,1073741824
 ============================================================
diff --git a/l3kernel/testfiles/m3intarray001.lvt b/l3kernel/testfiles/m3intarray001.lvt
index 298d9d87a..84e429061 100644
--- a/l3kernel/testfiles/m3intarray001.lvt
+++ b/l3kernel/testfiles/m3intarray001.lvt
@@ -69,7 +69,9 @@
   }
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\int_gadd:Nn \g__intarray_font_int { 100000 } % to make sure nothing is suppressed accidentally by scaling the font.
+\cs_if_exist:NT \g__intarray_font_int {
+  \int_gadd:Nn \g__intarray_font_int { 100000 } % to make sure nothing is suppressed accidentally by scaling the font.
+}
 \TEST { Any~stray~non-zero? }
   {
     \intarray_new:Nn \g_testd_intarray { 10 }
diff --git a/l3kernel/testfiles/m3skip001.tlg b/l3kernel/testfiles/m3skip001.luatex.tlg
similarity index 96%
copy from l3kernel/testfiles/m3skip001.tlg
copy to l3kernel/testfiles/m3skip001.luatex.tlg
index 6b00ba452..3ca538a9f 100644
--- a/l3kernel/testfiles/m3skip001.tlg
+++ b/l3kernel/testfiles/m3skip001.luatex.tlg
@@ -39,7 +39,7 @@ This is a coding error.
 LaTeX has been asked to create a new control sequence '\g_testa_dim' but this
 name has already been used elsewhere.
 The current meaning is:
-  \dimen168
+  \dimen167
 Defining \g_testa_dim on line ...
 \g_testa_dim=\dimen...
 ! LaTeX3 Error: Control sequence \g_testa_muskip already defined.
@@ -109,19 +109,19 @@ TEST 9: (SKIP) Overflow (BUT \maxdimen != maximum skip?!)
 -32767.00003pt plus -32767.00003pt minus -32767.00003pt (overflow by 1pt)
 ! Dimension too large.
 <to be read again> 
-                   p
+p
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
 ! Dimension too large.
 <to be read again> 
-                   m
+m
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
 ! Dimension too large.
 <to be read again> 
-                   \scan_stop: 
+\scan_stop: 
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
@@ -136,19 +136,19 @@ TEST 10: (SKIP) Underflow
 32767.00003pt plus 32767.00003pt minus 32767.00003pt (overflow by 1pt)
 ! Dimension too large.
 <to be read again> 
-                   p
+p
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
 ! Dimension too large.
 <to be read again> 
-                   m
+m
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
 ! Dimension too large.
 <to be read again> 
-                   \scan_stop: 
+\scan_stop: 
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
@@ -163,7 +163,7 @@ TEST 11: (DIM) Overflow (BUT \maxdimen != maximum dim?!)
 -32767.00003pt (overflow by 1pt)
 ! Dimension too large.
 <to be read again> 
-                   \__dim_eval_end: 
+\__dim_eval_end: 
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
@@ -178,7 +178,7 @@ TEST 12: (DIM) Underflow
 32767.00003pt (overflow by 1pt)
 ! Dimension too large.
 <to be read again> 
-                   \__dim_eval_end: 
+\__dim_eval_end: 
 l. ...}
 I can't work with sizes bigger than about 19 feet.
 Continue and I'll use the largest value I can.
diff --git a/l3kernel/testfiles/m3skip005.tlg b/l3kernel/testfiles/m3skip005.luatex.tlg
similarity index 89%
copy from l3kernel/testfiles/m3skip005.tlg
copy to l3kernel/testfiles/m3skip005.luatex.tlg
index eb73a74c4..52c4200e4 100644
--- a/l3kernel/testfiles/m3skip005.tlg
+++ b/l3kernel/testfiles/m3skip005.luatex.tlg
@@ -25,7 +25,7 @@ This is a coding error.
 LaTeX has been asked to create a new control sequence '\c_my_dim' but this
 name has already been used elsewhere.
 The current meaning is:
-  \dimen168
+  \dimen167
 Defining \c_my_dim on line ...
 \c_my_dim=\dimen...
 ! LaTeX3 Error: Control sequence \c_my_skip already defined.
@@ -59,7 +59,7 @@ TEST 3: Errors
 ============================================================
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '1.0pt2pt\scan_stop: ' in \dim_eval:n 
+      ! LaTeX3 Error: '1.0pt2pt\scan_stop: ' in \dim_eval:n 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are
@@ -68,7 +68,7 @@ followed by the required stuff, so I'm ignoring it.
 > 1pt2pt=1.0pt2pt\scan_stop: \__dim_eval_end: .
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '0.0ptpt)\scan_stop: ' in \dim_set:Nn 
+      ! LaTeX3 Error: '0.0ptpt)\scan_stop: ' in \dim_set:Nn 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are
@@ -76,7 +76,7 @@ made up of letters only. The macro here has not been
 followed by the required stuff, so I'm ignoring it.
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '0.769ptpt\scan_stop: ' in \dim_compare:nNnTF 
+      ! LaTeX3 Error: '0.769ptpt\scan_stop: ' in \dim_compare:nNnTF 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are
@@ -84,19 +84,19 @@ made up of letters only. The macro here has not been
 followed by the required stuff, so I'm ignoring it.
 ! Missing = inserted for \ifdim.
 <to be read again> 
-                   p
+p
 l. ...  }
 I was expecting to see `<', `=', or `>'. Didn't.
 ! Missing number, treated as zero.
 <to be read again> 
-                   p
+p
 l. ...  }
 A number should have been here; I inserted `0'.
 (If you can't figure out why I needed to see a number,
 look up `weird error' in the index to The TeXbook.)
 ! Illegal unit of measure (pt inserted).
 <to be read again> 
-                   m
+m
 l. ...  }
 Dimensions can be in units of em, ex, in, pt, pc,
 cm, mm, dd, cc, nd, nc, bp, or sp; but yours is a new one!
@@ -106,7 +106,7 @@ delete the erroneous units; e.g., type `2' to delete
 two letters. (See Chapter 27 of The TeXbook.)
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '1.0ptmu\scan_stop: ' in \skip_eval:n 
+      ! LaTeX3 Error: '1.0ptmu\scan_stop: ' in \skip_eval:n 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are
@@ -115,7 +115,7 @@ followed by the required stuff, so I'm ignoring it.
 > 1mu=1.0ptmu\scan_stop: \scan_stop: .
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '144.54ptches\scan_stop: ' in \skip_add:Nn 
+      ! LaTeX3 Error: '144.54ptches\scan_stop: ' in \skip_add:Nn 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are
@@ -123,7 +123,7 @@ made up of letters only. The macro here has not been
 followed by the required stuff, so I'm ignoring it.
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '1.0mu2\scan_stop: ' in \muskip_eval:n 
+      ! LaTeX3 Error: '1.0mu2\scan_stop: ' in \muskip_eval:n 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are
@@ -132,7 +132,7 @@ followed by the required stuff, so I'm ignoring it.
 > 1mu2=1.0mu2\scan_stop: \scan_stop: .
 ! Use of \??? doesn't match its definition.
 <argument> \???  
-                 ! LaTeX3 Error: '2.0mu)\scan_stop: ' in \muskip_add:Nn 
+      ! LaTeX3 Error: '2.0mu)\scan_stop: ' in \muskip_add:Nn 
 l. ...  }
 If you say, e.g., `\def\a1{...}', then you must always
 put `1' after `\a', since control sequence names are





More information about the latex3-commits mailing list.