%% This is part of the OpTeX project, see http://petr.olsak.net/optex \_codedecl \newdimen {Allocators for registers <2021-02-15>} % loaded in format \_doc ----------------------------- The limits are set first. \_cod ----------------------------- \_chardef\_maicount = 65535 % Max Allocation Index for counts registers in LuaTeX \_let\_maidimen = \_maicount \_let\_maiskip = \_maicount \_let\_maimuskip = \_maicount \_let\_maibox = \_maicount \_let\_maitoks = \_maicount \_chardef\_mairead = 15 \_chardef\_maiwrite = 15 \_chardef\_maifam = 255 \_doc ----------------------------- Each allocation macro needs its own counter. \_cod ----------------------------- \_countdef\_countalloc=10 \_countalloc=255 \_countdef\_dimenalloc=11 \_dimenalloc=255 \_countdef\_skipalloc=12 \_skipalloc=255 \_countdef\_muskipalloc=13 \_muskipalloc=255 \_countdef\_boxalloc=14 \_boxalloc=255 \_countdef\_toksalloc=15 \_toksalloc=255 \_countdef\_readalloc=16 \_readalloc=-1 \_countdef\_writealloc=17 \_writealloc=-1 \_countdef\_famalloc=18 \_famalloc=3 \_doc ----------------------------- The common allocation macro \`\_allocator` `\ {} \` is defined. This idea was used in classical plain \TeX/ by Donald Knuth too but the macro from plain \TeX/ seems to be more complicated:). \_cod ----------------------------- \_def\_allocator #1#2#3{% \_incr{\_cs{_#2alloc}}% \_ifnum\_cs{_#2alloc}>\_cs{_mai#2}% \_errmessage{No room for a new \_ea\_string\_csname #2\_endcsname}% \_else \_global#3#1=\_cs{_#2alloc}% \_wlog{\_string#1=\_ea\_string\_csname #2\_endcsname\_the\_cs{_#2alloc}}% \_fi } \_doc ----------------------------- The allocation macros \`\newcount`, \`\newdimen`, \`\newskip`, \`\newmuskip`, \`\newbox`, \`\newtoks`, \`\newread`, \`\newwrite` and \`\newfam` are defined here. \_cod ----------------------------- \_def\_newcount #1{\_allocator #1{count}\_countdef} \_def\_newdimen #1{\_allocator #1{dimen}\_dimendef} \_def\_newskip #1{\_allocator #1{skip}\_skipdef} \_def\_newmuskip #1{\_allocator #1{muskip}\_muskipdef} \_def\_newbox #1{\_allocator #1{box}\_chardef} \_def\_newtoks #1{\_allocator #1{toks}\_toksdef} \_def\_newread #1{\_allocator #1{read}\_chardef} \_def\_newwrite #1{\_allocator #1{write}\_chardef} \_def\_newfam #1{\_allocator #1{fam}\_chardef} \_public \newcount \newdimen \newskip \newmuskip \newbox \newtoks \newread \newwrite \newfam ; \_doc ----------------------------- The \`\newinsert` macro is defined differently than others. \_cod ----------------------------- \_newcount\_insertalloc \_insertalloc=255 \_chardef\_insertmin = 201 \_def\_newinsert #1{% \_decr\_insertalloc \_ifnum\_insertalloc <\_insertmin \_errmessage {No room for a new \_string\insert}% \_else \_global\_chardef#1=\_insertalloc \_wlog {\_string#1=\_string\_insert\_the\_insertalloc}% \_fi } \_public \newinsert ; \_doc ----------------------------- Other allocation macros \`\newattribute` and \`\newcatcodetable` have their counter allocated by the `\newcount` macro. \_cod ----------------------------- \_newcount \_attributealloc \_attributealloc=0 \_chardef\_maiattribute=\_maicount \_def\_newattribute #1{\_allocator #1{attribute}\_attributedef} \_newcount \_catcodetablealloc \_catcodetablealloc=10 \_chardef\_maicatcodetable=32767 \_def\_newcatcodetable #1{\_allocator #1{catcodetable}\_chardef} \_public \newattribute \newcatcodetable ; \_doc ----------------------------- We declare public and private versions of `\tmpnum` and `\tmpdim` registers separately. They are independent registers. \_cod ----------------------------- \_newcount \tmpnum \_newcount \_tmpnum \_newdimen \tmpdim \_newdimen \_tmpdim \_doc ----------------------------- A few registers are initialized like in plain\TeX/. We absolutely don't support the `@`category dance, so `\z@skip` `\z@`, `\p@` etc. are not defined in \OpTeX/. If you need such control sequences then you can initialize them by `\load[plain-at]`. Only the \`\_zo` and \`\_zoskip` (equivalents to `\z@` and `\z@skip`) are declared here and used in some internal macros of \OpTeX/ for improving speed. \_cod ----------------------------- \_newdimen\_maxdimen \_maxdimen=16383.99999pt % the largest legal \_newdimen\_zo \_zo=0pt \_newskip\_hideskip \_hideskip=-1000pt plus 1fill % negative but can grow \_newskip\_centering \_centering=0pt plus 1000pt minus 1000pt \_newskip\_zoskip \_zoskip=0pt plus0pt minus0pt \_newbox\_voidbox % permanently void box register \_public \maxdimen \hideskip \centering \voidbox ; \_endcode %--------------------------------------------------- Like plain\TeX, the allocators `\newcount`, `\newwrite`, etc. are defined. The registers are allocated from 256 to the `\_mai` which is 65535 in \LuaTeX/. Unlike in Plain\TeX/, the mentioned allocators are not `\outer`. User can use `\dimen0` to `\dimen200` and similarly for `\skip`, `\muskip`, `\box`, and `\toks` directly. User can use `\count20` to `\count200` directly too. This is the same philosophy as in old plain\TeX/, but the range of directly used registers is wider. Inserts are allocated from 254 to 201 using `\newinsert`. You can define your own allocation concept (for example for allocation of arrays) from the top of the registers array. The example shows a definition of the array-like declarator of counters. \nobreak \begtt \newcount \_maicount % redefine maximal allocation index as variable \_maicount = \maicount % first value is top of the array \def\newcountarray #1[#2]{% \newcountarray \foo[100] \global\advance\_maicount by -#2\relax \ifnum \_countalloc > \_maicount \errmessage{No room for a new array of \string\count}% \else \global\chardef#1=\_maicount \fi } \def\usecount #1[#2]{% \usecount \foo[2] \count\numexpr#1+#2\relax } \endtt \_endinput 2021-02-15 \_advance -> \_incr, \_decr 2020-05-12 \newmath -> \newfam bug fixing 2020-01-23 released