lowlevel-registers.tex /size: 16 Kb    last modification: 2024-01-16 09:02
1% language=us runpath=texruns:manuals/lowlevel
2
3\environment lowlevel-style
4
5\startdocument
6  [title=registers,
7   color=darkmagenta]
8
9\startsectionlevel[title=Preamble]
10
11Registers are sets of variables that are accessed by index and a such resemble
12registers in a processing unit. You can store a quantity in a register, retrieve
13it, and also manipulate it.
14
15There is hardly any need to use them in \CONTEXT\ so we keep it simple.
16
17\stopsectionlevel
18
19\startsectionlevel[title={\TEX\ primitives}]
20
21There are several categories:
22
23\startitemize
24\startitem
25    Integers (int): in order to be portable (at the time it surfaced) there are only
26    integers and no floats. The only place where \TEX\ uses floats internally is
27    when glue gets effective which happens in the backend.
28\stopitem
29\startitem
30    Dimensions (dimen): internally these are just integers but when they are entered they
31    are sliced into two parts so that we have a fractional part. The internal
32    representation is called a scaled point.
33\stopitem
34\startitem
35    Glue (skip): these are dimensions with a few additional properties: stretch and
36    shrink. Being a compound entity they are stored differently and thereby a bit
37    less efficient than numbers and dimensions.
38\stopitem
39\startitem
40    Math glue (muskip): this is the same as glue but with a unit that adapts to
41    the current math style properties. It's best to think about them as being
42    relative measures.
43\stopitem
44\startitem
45    Token lists (toks): these contain a list of tokens coming from the input
46    or coming from a place where they already have been converted.
47\stopitem
48\stopitemize
49
50The original \TEX\ engine had 256 entries per set. The first ten of each set are
51normally reserved for scratch purposes: the even ones for local use, and the odd
52ones for global usage. On top of that macro packages can reserve some for its own
53use. It was quite easy to reach the maximum but there were tricks around that.
54This limitation is no longer present in the variants in use today.
55
56Let's set a few dimension registers:
57
58\startbuffer[1]
59\dimen 0 = 10 pt
60\dimen2=10pt
61\dimen4 10pt
62\scratchdimen 10pt
63\stopbuffer
64
65\typebuffer[1][option=TEX]
66
67We can serialize them with:
68
69\startbuffer[2]
70\the    \dimen0
71\number \dimen2
72\meaning\dimen4
73\meaning\scratchdimen
74\stopbuffer
75
76\typebuffer[2][option=TEX]
77
78The results of these operations are:
79
80\startlines\tt
81\getbuffer[1,2]
82\stoplines
83
84The last two is not really useful but it is what you see when tracing options are
85set. Here \type {\scratchdimen} is a shortcut for a register. This is {\em not} a
86macro but a defined register. The low level \type {\dimendef} is used for this
87but in a macro package you should not use that one but the higher level \type
88{\newdimen} macro that uses it.
89
90\startbuffer[1]
91\newdimen\MyDimenA
92\def     \MyDimenB{\dimen999}
93\dimendef\MyDimenC998
94\stopbuffer
95
96\typebuffer[1][option=TEX]
97
98\startbuffer[2]
99\meaning\MyDimenA
100\meaning\MyDimenB
101\meaning\MyDimenC
102\stopbuffer
103
104\typebuffer[2][option=TEX]
105
106Watch the difference:
107
108\pushoverloadmode
109\startlines\tt
110\getbuffer[1,2]
111\stoplines
112\popoverloadmode
113
114The first definition uses a yet free register so you won't get a clash. The
115second one is just a shortcut using a macro and the third one too but again
116direct shortcut. Try to imagine how the second line gets interpreted:
117
118\starttyping[option=TEX]
119\MyDimenA10pt \MyDimenA10.5pt
120\MyDimenB10pt \MyDimenB10.5pt
121\MyDimenC10pt \MyDimenC10.5pt
122\stoptyping
123
124Also try to imagine what messing around with \type {\MyDimenC} will do when we
125also have defined a few hundred extra dimensions with \type {\newdimen}.
126
127In the case of dimensions the \type {\number} primitive will make the register
128serialize as scaled points without unit \type {sp}.
129
130Next we see some of the other registers being assigned:
131
132\starttyping[option=TEX]
133\count  0 = 100
134\skip   0 = 10pt plus 3pt minus 2pt
135\skip   0 = 10pt plus 1fill
136\muskip 0 = 10mu plus 3mu minus 2mu
137\muskip 0 = 10mu minus 1 fil
138\toks   0 = {hundred}
139\stoptyping
140
141When a number is expected, you can use for instance this:
142
143\starttyping[option=TEX]
144\scratchcounter\scratchcounterone
145\stoptyping
146
147Here we use a few predefined scratch registers. You can also do this:
148
149\starttyping[option=TEX]
150\scratchcounter\numexpr\scratchcounterone+\scratchcountertwo\relax
151\stoptyping
152
153There are some quantities that also qualify as number:
154
155\starttyping[option=TEX]
156\chardef\MyChar=123 % refers to character 123 (if present)
157\scratchcounter\MyChar
158\stoptyping
159
160In the past using \type {\chardef} was a way to get around the limited number of
161registers, but it still had (in traditional \TEX) a limitation: you could not go
162beyond 255. The \type {\mathchardef} could fo higher as it also encodes a family
163number and class. This limitation has been lifted in \LUATEX.
164
165A character itself can also be interpreted as number, in which case it has to be
166prefixed with a reverse quote: \type {`}, so:
167
168\startbuffer
169\scratchcounter\numexpr`0+5\relax
170\char\scratchcounter
171\stopbuffer
172
173\typebuffer[option=TEX]
174
175produces \quotation {\inlinebuffer} because the \type {`0} expands into the
176(\ASCII\ and \UTF8) slot {\tt \number`0} which represents the character zero. In
177this case the next makes more sense:
178
179\starttyping[option=TEX]
180\char\numexpr`0+5\relax
181\stoptyping
182
183If you want to know more about all these quantities, \quotation {\TEX\ By Topic}
184provides a good summary of what \TEX\ has to offer, and there is no need to repeat
185it here.
186
187\stopsectionlevel
188
189\startsectionlevel[title={\ETEX\ primitives}]
190
191Apart from the ability to use expressions, the contribution to registers that
192\ETEX\ brought was that suddenly we could use upto 65K of them, which is more
193than enough. The extra registers were not as efficient as the first 256 because
194they were stored in the hash table, but that was not really a problem. In \OMEGA\
195and later \LUATEX\ regular arrays were used, at the cost of more memory which in
196the meantime has become cheap. As \CONTEXT\ moved to \ETEX\ rather early its
197users never had to worry about it.
198
199\stopsectionlevel
200
201\startsectionlevel[title={\LUATEX\ primitives}]
202
203The \LUATEX\ engine introduced attributes. These are numeric properties that are
204bound to the nodes that are the result of typesetting operations. They are
205basically like integer registers but when set their values get bound and when
206unset they are kind of invisible.
207
208\startitemize
209\startitem
210    Attribute (attribute): a numeric property that when set becomes part of the
211    current attribute list that gets assigned to nodes.
212\stopitem
213\stopitemize
214
215Attributes can be used to communicate properties to \LUA\ callbacks. There are
216several functions available for setting them and querying them.
217
218\starttyping[option=TEX]
219\attribute999 = 123
220\stoptyping
221
222Using attributes this way is dangerous (of course I can only speak for \CONTEXT)
223because an attribute value might trigger some action in a callback that gives
224unwanted side effects. For convenience \CONTEXT\ provides:
225
226\startbuffer
227\newattribute\MyAttribute
228\stopbuffer
229
230\typebuffer[option=TEX] \getbuffer
231
232Which currently defines \type {\MyAttribute} as {\tt \meaning\MyAttribute} and is
233meant to be used as: \footnote {The low level \type {\attributedef} command is
234rather useless in the perspective of \CONTEXT.}
235
236\starttyping[option=TEX]
237\attribute\MyAttribute = 123
238\stoptyping
239
240Just be aware that defining attributes can have an impact on performance. As you
241cannot access them at the \TEX\ end you seldom need them. If you do you can
242better use the proper more high level definers (not discussed here).
243
244\stopsectionlevel
245
246\startsectionlevel[title={\LUAMETATEX\ primitives}]
247
248The fact that scanning stops at a non-number or \type {\relax} can be sort of
249unpredictable which is why in \LUAMETATEX\ we also support the following variant:
250
251\starttyping[option=TEX]
252\scratchdimen\dimexpr  10pt + 3pt \relax
253\scratchdimen\dimexpr {10pt + 3pt}
254\stoptyping
255
256At the cost of one more token braces can be used as boundaries instead of the
257single \type {\relax} boundary.
258
259An important property of registers is that they can be accessed by a number. This
260has big consequences for the implementation: they are part of the big memory
261store and consume dedicated ranges. If we had only named access \TEX's memory
262layout could be a bit leaner. In principle we could make the number of registers
263smaller because any limit on the amount at some point can be an obstacle. It is
264for that reason that we also have name-only variants:
265
266\starttyping[option=TEX]
267\dimensiondef \MyDimenA   12pt
268\integerdef   \MyIntegerA 12
269\gluespecdef  \MyGlueA    12pt + 3pt minus 4pt
270\mugluespecdef\MyMuA      12mu + 3mu minus 4mu
271\stoptyping
272
273These are as efficient but not accessible by number but they behave like
274registers which means that you (can) use \type {\the}, \type {\advance}, \type
275{\multiply} and \type {\divide} with them. \footnote {There are also the slightly
276more efficient \type {\advanceby}, \type {\multiplyby} and \type {\divideby} that
277don't check for the \type {by} keyword.} In case you wonder why there is no
278alternative for \type {\toksdef}, there actually are multiple: they are called
279macros.
280
281{\em todo: expressions}
282
283\stopsectionlevel
284
285\startsectionlevel[title=Units]
286
287The \LUAMETATEX\ engine supports the following units. The first batch is constant
288with hard coded fine tuned values. The second set is related to the current font.
289The last group is kind of special, the \type {es} is a replacement for the \type
290{in} and has a little sister in \type {ts}. The \type {dk} is dedicated to the
291master and makes a nice offset for so called \TEX\ pages that we use for demos.
292
293\starttabulate[|Tl|Tr|l|]
294\FL
295\NC pt \NC \thewithoutunit\dimexpr1pt \NC point \NC \NR
296\NC bp \NC \thewithoutunit\dimexpr1bp \NC big point (aka postscript point) \NC \NR
297\NC in \NC \thewithoutunit\dimexpr1in \NC inch \NC \NR
298\NC cm \NC \thewithoutunit\dimexpr1cm \NC centimeter \NC \NR
299\NC mm \NC \thewithoutunit\dimexpr1mm \NC milimeter \NC \NR
300\NC dd \NC \thewithoutunit\dimexpr1dd \NC didot \NC \NR
301\NC cc \NC \thewithoutunit\dimexpr1cc \NC cicero \NC \NR
302\NC pc \NC \thewithoutunit\dimexpr1pc \NC pica \NC \NR
303\NC sp \NC \thewithoutunit\dimexpr1sp \NC scaled points \NC \NR
304\NC px \NC \thewithoutunit\dimexpr1sp \NC pixel \NC \NR
305\ML
306\NC ex \NC \thewithoutunit\dimexpr1ex \NC ex height \NC \NR
307\NC em \NC \thewithoutunit\dimexpr1em \NC em width \NC \NR
308\NC mu \NC $\tt\thewithoutunit\onemuskip$ \NC math unit \NC \NR
309\ML
310\NC ts \NC \thewithoutunit\dimexpr1ts \NC tove \NC \NR
311\NC es \NC \thewithoutunit\dimexpr1es \NC edith \NC \NR
312\NC eu \NC \thewithoutunit\dimexpr1eu \NC european unit \NC \NR
313\NC dk \NC \thewithoutunit\dimexpr1dk \NC knuth \NC \NR
314\LL
315\stoptabulate
316
317The \type {fi[lll]} unit is not really a unit but a multiplier for infinite
318stretch and shrink; original \TEX\ doesn't have the simple \type {fi}.
319
320In addition to these we can have many more. In principle a user can define
321additional ones but there's always a danger of clashing. For users we reserve the
322units starting with an \type{u}. Here is how you define your own, we show three
323variants:
324
325\startbuffer
326\newdimension \FooA   \FooA 1.23pt
327\newdimen     \FooB   \FooB 12.3pt
328\protected\def\FooC   {\the\dimexpr\FooA +\FooB\relax}
329
330\pushoverloadmode % just in case
331    \newuserunit\FooA ua
332    \newuserunit\FooB ub
333    \newuserunit\FooC uc
334\popoverloadmode
335\stopbuffer
336
337\typebuffer[option=TEX] \getbuffer
338
339And this is how they show up:
340
341\startbuffer
342\the\dimexpr 2 ua \relax\quad
343\the\dimexpr 2 ub \relax\quad
344\the\dimexpr 2 uc \relax
345\stopbuffer
346
347\getbuffer
348
349with
350
351\typebuffer[option=TEX]
352
353The following additional units are predefined (reserved). The values are in
354points and some depend on the current layout and document font.
355
356\starttabulate[|T|Tr|l|]
357\NC pi \NC \thewithoutunit\dimexpr 1pi \NC {\tt\pi} for Mikael        \NC \NR
358\NC ft \NC \thewithoutunit\dimexpr 1ft \NC \type {foot} for Alan      \NC \NR
359\NC fs \NC \thewithoutunit\dimexpr 1fs \NC (global body) font size    \NC \NR
360\NC tw \NC \thewithoutunit\dimexpr 1tw \NC (layout) text width        \NC \NR
361\NC th \NC \thewithoutunit\dimexpr 1th \NC (layout) text height       \NC \NR
362\NC hs \NC \thewithoutunit\dimexpr 1hs \NC (current) hsize            \NC \NR
363\NC vs \NC \thewithoutunit\dimexpr 1vs \NC (current) vsize            \NC \NR
364\NC cd \NC \thewithoutunit\dimexpr 1cd \NC (when set) column distance \NC \NR % todo
365\NC cw \NC \thewithoutunit\dimexpr 1cw \NC (when set) column width    \NC \NR % todo
366\NC cx \NC \thewithoutunit\dimexpr 1cx \NC combination cell width     \NC \NR
367\NC uu \NC \thewithoutunit\dimexpr 1uu \NC user unit (\METAFUN)       \NC \NR
368\NC fw \NC \thewithoutunit\dimexpr 1fw \NC framed width               \NC \NR
369\NC fh \NC \thewithoutunit\dimexpr 1fh \NC framed height              \NC \NR
370\NC fo \NC \thewithoutunit\dimexpr 1fo \NC framed offset              \NC \NR
371\NC lw \NC \thewithoutunit\dimexpr 1lw \NC line width                 \NC \NR
372\NC sh \NC \thewithoutunit\dimexpr 1sh \NC strut height               \NC \NR
373\NC sd \NC \thewithoutunit\dimexpr 1sd \NC strut depth                \NC \NR
374\NC st \NC \thewithoutunit\dimexpr 1st \NC strut total                \NC \NR
375\NC ch \NC \thewithoutunit\dimexpr 1ch \NC width of zero (css)        \NC \NR
376\NC fa \NC \thewithoutunit\dimexpr 1fa \NC font ascender              \NC \NR
377\NC fd \NC \thewithoutunit\dimexpr 1fd \NC font descender             \NC \NR
378\NC fc \NC \thewithoutunit\dimexpr 1fc \NC font cap height            \NC \NR
379\stoptabulate
380
381Here is an example of usage:
382
383\startbuffer
384\startcombination[nx=4,ny=1]
385    {\ruledhbox to 1cx{\strut one}}   {1}
386    {\ruledhbox to 1cx{\strut two}}   {2}
387    {\ruledhbox to 1cx{\strut three}} {3}
388    {\ruledhbox to 1cx{\strut four}}  {4}
389\stopcombination
390\stopbuffer
391
392\usemodule[system-units]
393
394\startplacefigure[title=A map of available units,reference=fig:unitsmap]
395    \framed[offset=1ex]{\showunitsmap}
396\stopplacefigure
397
398\typebuffer[option=TEX]
399
400\startlinecorrection
401\getbuffer
402\stoplinecorrection
403
404The \type {uu} can be set by users using the \type {\uunit} dimension variable.
405The default valu sis 1cm. Its current value is also known at the \METAPOST\ end,
406as demonstrated in \in {figure} [fig:userunits].
407
408\startbuffer
409\startcombination[nx=2,ny=1]
410    \startcontent
411        \uunit=1cm
412        \framed[offset=1uu]
413            \bgroup
414                \startMPcode
415                    fill fullcircle scaled 3uu withcolor "darkred"   ;
416                    fill fullcircle scaled 2cm withcolor "darkgreen" ;
417                \stopMPcode
418            \egroup
419    \stopcontent
420    \startcaption
421        \type {\uunit = 1cm}
422    \stopcaption
423    \startcontent
424        \uunit=1cx
425        \framed[offset=.1uu]
426            \bgroup
427                \startMPcode
428                    fill fullcircle scaled .5uu withcolor "darkblue"   ;
429                    fill fullcircle scaled  2cm withcolor "darkyellow" ;
430                \stopMPcode
431            \egroup
432    \stopcontent
433    \startcaption
434        \type {\uunit = 1cx}
435    \stopcaption
436\stopcombination
437\stopbuffer
438
439% \framed[offset=1uu]
440%     \bgroup
441%         \startMPcode
442%             save uu ; numeric uu ; uu := 1cm ;
443%             fill fullcircle scaled 3uu withcolor "darkcyan"    ;
444%             fill fullcircle scaled 2cm withcolor "darkmagenta" ;
445%         \stopMPcode
446%     \egroup
447
448\typebuffer[option=TEX]
449
450There is one catch here. If you use your own \type {uu} as numeric, you might
451need this:
452
453\starttyping[option=MP]
454save uu ; numeric uu ; uu := 1cm ;
455\stoptyping
456
457That is: make sure the meaning is restored afterwards and explicitly declare the
458variable. But this is good practice anyway when you generate multiple graphics
459using the same \METAPOST\ instance.
460
461\startplacefigure[reference=fig:userunits,title={Shared user units in \TEX\ and \METAFUN.}]
462    \getbuffer
463\stopplacefigure
464
465There a few units not mentioned yet and those concern math, where we need to adapt to
466the current style.
467
468\protected\def\ShowMathUnits#1%
469  {\im{#1x\mathord{+
470     {\darkgray \vrule width 1pt depth 0pt height 1ex \relax}%
471     {\darkred  \vrule width 1pt depth 0pt height 1ma \relax}%
472     {\darkgreen\vrule width 1pt depth 0pt height 1mx \relax}%
473     {\darkblue \vrule width 1pt depth 0pt height 1mq \relax}%
474    x}}}
475
476\startlinecorrection
477\startcombination[nx=3,ny=1]
478    {\scale[scale=6000]{\ShowMathUnits\textstyle}}         {text style}
479    {\scale[scale=6000]{\ShowMathUnits\scriptstyle}}       {script style}
480    {\scale[scale=6000]{\ShowMathUnits\scriptscriptstyle}} {script script style}
481\stopcombination
482\stoplinecorrection
483
484The bars show \type {1ex}, \type {1ma} (axis), \type {1mx} (ex|-|height) and
485\type {1mq} (em|-|width or quad). The last three adapt themselves to the style.
486Often the \type {mx} makes more sense than \type {ex}.
487
488\stopsectionlevel
489
490\page
491
492\stopdocument
493