cld-variables.tex /size: 9079 b    last modification: 2021-10-28 13:50
1% language=us runpath=texruns:manuals/cld
2
3\startcomponent cld-variables
4
5\environment cld-environment
6
7\startchapter[title={Variables}]
8
9\startsection[title={Introduction}]
10
11\index {variables}
12
13Sometimes a bit of experimenting and exploring the boundaries of the \TEX|-|\LUA\
14interfaces results in new mechanisms. To what extent they are really useful is
15hard to say but we just keep them around. Some are described here. This is, at
16least for the moment, a \LMTX\ specific chapter.
17
18\stopsection
19
20\startsection[title={Simple tables}]
21
22\index {variables+grouped tables}
23
24The basic \TEX\ data types are counters (integers), dimensions (kind of floating
25point variables with typographic dimensions), token lists, node lists (boxes),
26fonts, and so on, but no data organized in tables. The first mechanism that we
27discuss is one that obeys grouping. In that respect is behaves like regular
28registers.
29
30\startbuffer
31\newhashedtable\somehashtable
32
33\somehashtable{ foo = 123, bar = "foo" }
34[123 = \the\somehashtable{foo}]
35[foo = \the\somehashtable{bar}]
36
37\bgroup
38\somehashtable{ foo = 456, bar = "oof" }
39[456 = \the\somehashtable{foo}]
40[oof = \the\somehashtable{bar}]
41\egroup
42
43[123 = \the\somehashtable{foo}]
44[foo = \the\somehashtable{bar}]
45
46\bgroup
47\global\somehashtable{ foo = 456 }
48       \somehashtable{ bar = "oof" }
49[456 = \the\somehashtable{foo}]
50[oof = \the\somehashtable{bar}]
51\egroup
52
53[456 = \the\somehashtable{foo}]
54[foo = \the\somehashtable{bar}]
55\stopbuffer
56
57\typebuffer
58
59We define a hashed table, one with keys and values. The definition is global.
60We can then assign values to this table where the assignments themselves are
61hash tables. The above code generates:
62
63\getbuffer
64
65As you can see, the \type {\global} prefix makes the value persistent outside the
66group. You can mix local and global assignments.
67
68Instead of a hashed table, you can have an indexed table. This time the keys are
69numbers.
70
71\startbuffer
72\newindexedtable\someindextable
73
74\someindextable{ 123, "foo" }
75[123 = \the\someindextable 1]
76[foo = \the\someindextable 2]
77
78\bgroup
79\someindextable{ 456, "oof" }
80[456 = \the\someindextable 1]
81[oof = \the\someindextable 2]
82\egroup
83
84[123 = \the\someindextable 1]
85[foo = \the\someindextable 2]
86
87\bgroup
88\global\someindextable{ [1] = 456 }
89       \someindextable{ [2] = "oof" }
90[456 = \the\someindextable 1]
91[oof = \the\someindextable 2]
92\egroup
93
94[456 = \the\someindextable 1]
95[foo = \the\someindextable 2]
96\stopbuffer
97
98\typebuffer
99
100The outcome is the same as before:
101
102\getbuffer
103
104At the \LUA\ end you can access these tables too:
105
106\startbuffer
107\startluacode
108context("[hashed : bar = %s]",context.hashedtables.somehashtable.bar)
109context("[indexed : 2 = %s]", context.indexedtables.someindextable[2])
110\stopluacode
111\stopbuffer
112
113\typebuffer
114
115Indeed we get:
116
117\getbuffer
118
119\stopsection
120
121\startsection[title={Data tables}]
122
123\index {variables+data tables}
124
125In \LUA, tables can be more complex than in the previous section. When you need
126more complex tables, it is likely that your grouping needs are also different,
127which is why we have another mechanism. This mechanism is build on top of another
128model: data values. There are 64K integer registers in any modern \TEX\ engine
129and normally that is more than enough. However, in addition in \LUAMETATEX\ we
130have a variant integer storage unit, one that is lightweight and where the amount
131is limited by the size of the hash table. It was added as part of the low level
132cleanup up of the \LUA\ token interface (a bit more abstraction). Here is an
133example of its usage:
134
135\startbuffer
136\dorecurse {100} {
137    \setdatavalue{#1}{#1}
138}
139
140\start \tttf \darkred \raggedright \dorecurse {100} {
141    #1=\scratchcounter\getdatavalue{#1}\the\scratchcounter
142} \par \stop \blank
143
144\start \tttf \darkgreen \raggedright \dorecurse {100} {
145    #1=\thedatavalue{#1}%
146} \par \stop \blank
147\stopbuffer
148
149\typebuffer
150
151\getbuffer
152
153We define hundred values which are a simple numeric macros. Here we use two
154auxiliary macros because we prefer to use a dedicated namespace for these
155variables. However, there are also primitives that deal with these data values:
156
157\startbuffer[usage]
158\setdatavalue{my-data}{12345}%
159\integerdef   \MyDataI 67890
160\dimensiondef \MyDataD 12345pt
161\thedatavalue{my-data}, \the\MyDataI, \the\MyDataD.
162\stopbuffer
163
164\typebuffer[usage]
165
166gives: \inlinebuffer[usage]
167
168But, when more is needed than simple integers, tables come into view. This interface
169is different from the simple one and involves more commands. The next examples show
170about all:
171
172\startbuffer
173\newluatable\testtable
174\setluatable\testtable{ foo = 123, bar = "456", oof = "rab" }
175% \inspectluatable\testtable
176\darkcyan
177foo = \getfromluatable\testtable{foo}\par
178bar = \getfromluatable\testtable{bar}\par
179oof = \getfromluatable\testtable{oof}\par
180\bgroup
181    \useluatable\testtable
182    \setluatable\testtable{ foo = 123123, bar = "456456" }
183  % \inspectluatable\testtable
184    \darkmagenta
185    foo = \getfromluatable\testtable{foo}\par
186    bar = \getfromluatable\testtable{bar}\par
187    oof = \getfromluatable\testtable{oof}\par
188    \startluacode
189        local t = context.luatables.get("testtable")
190        context("<%s %s %s>",t.foo,t.bar,t.oof)
191    \stopluacode \par
192\egroup
193\darkyellow
194foo = \getfromluatable\testtable{foo}\par
195bar = \getfromluatable\testtable{bar}\par
196oof = \getfromluatable\testtable{oof}\par
197\startluacode
198    local t = context.luatables.get("testtable")
199    context("<%s %s %s>",t.foo,t.bar,t.oof)
200\stopluacode \par
201% \inspectluatable\testtable
202\stopbuffer
203
204\typebuffer
205
206The tables are semi|-|local: \type {\newluatable} creates a table and \type
207{\useluatable} will create a local copy that is discarded when the group ends.
208
209\startpacked
210\tttf \getbuffer
211\stoppacked
212
213Hashed and indexed tables can be used mixed, but there are additional accessors
214for indexed tables because there we expect numbers.
215
216\startbuffer
217\newluatable\moretable
218\setluatable\moretable{ 1, "foo" }
219\darkcyan
220[1] = \getfromluatable\moretable{1}\par
221[2] = \idxfromluatable\moretable 2 \par
222\bgroup
223    \useluatable\moretable
224    \setluatable\moretable{ foo = 123123, bar = "456456" }
225    \darkmagenta
226    [1] = \getfromluatable\moretable{1}\par
227    [2] = \idxfromluatable\moretable 2 \par
228    \startluacode
229        local t = context.luatables.get("moretable")
230        context("<%s %s>",t[1],t[2])
231    \stopluacode \par
232\egroup
233\darkyellow
234[1] = \getfromluatable\moretable{1}\par
235[2] = \idxfromluatable\moretable 2 \par
236\startluacode
237    local t = context.luatables.get("moretable")
238    context("<%s %s>",t[1],t[2])
239\stopluacode \par
240\stopbuffer
241
242\typebuffer
243
244\startpacked
245\tttf \getbuffer
246\stoppacked
247
248You can create more complex (nested) tables that you can handle at the \LUA\
249end in the usual way. Basically any \LUA\ that makes a table can go between
250the curly braces.
251
252\stopsection
253
254\startsection[title=Named variables]
255
256\index {variables+named}
257\index {variables+integers}
258\index {variables+cardinals}
259\index {variables+floats}
260\index {integers}
261\index {cardinals}
262\index {floats}
263
264Just because it can be done, and maybe it even has it use, we offer additional
265numbers, stored and accessible by name. The different types all live in their
266own namespace:
267
268\startbuffer[definition]
269\luainteger bar 123456
270\luafloat   bar 123.456e12
271\luainteger gnu = 0xFFFF
272\stopbuffer
273
274\startbuffer[usage]
275{\darkcyan   \the\luainteger bar}
276{\darkmagenta\the\luafloat   bar}
277{\darkyellow \the\luainteger gnu}
278\stopbuffer
279
280\typebuffer[definition,usage] \getbuffer[definition]
281
282These serialize like: \getbuffer[usage]\removeunwantedspaces , and when not set they
283default to zero. There is an extra type, cardinal:
284
285\startbuffer
286\luainteger  a  0x7FFFFFFFFFFFFFFF
287\luainteger  b -0x7FFFFFFFFFFFFFFF
288\luacardinal c  0xFFFFFFFFFFFFFFFF
289\stopbuffer
290
291\typebuffer \getbuffer
292
293We cheat a bit behind the screens because it is actually a double but we scan
294it as positive integer and serialize it as such.
295
296\startbuffer
297[\the \luainteger  a\relax]\par
298[\the \luainteger  b\relax]\par
299[\the \luacardinal c\relax]\par
300\stopbuffer
301
302\typebuffer \getbuffer
303
304You have access to the numbers at the \LUA\ end, as in:
305
306\startbuffer
307\luainteger one 123 \luafloat two 456.678
308\luaexpr{interfaces.numbers.one/1000 + interfaces.numbers.two/10000}
309\stopbuffer
310
311\typebuffer
312
313There are \type {integers}, \type {cardinals} and \type {floats} but the \type
314{numbers} one is the most generic as it tries to resolve it from one of these
315namespaces, so we get: [\inlinebuffer\space\space]. There is also a related
316expression command:
317
318\startbuffer
319(?: \luaexpression          {n.one/1000 + n.two/10000})
320(f: \luaexpression float    {n.one/1000 + n.two/10000})
321(i: \luaexpression integer  {n.one/1000 + n.two/10000})
322(c: \luaexpression cardinal {n.one/1000 + n.two/10000})
323(l: \luaexpression lua      {n.one/1000 + n.two/10000})
324\stopbuffer
325
326\typebuffer
327
328It typesets this (watch the \type {lua} variant, which is a precise
329roundtrip serialization method):
330
331\startlines
332\tttf \getbuffer
333\stoplines
334
335The \type {n} table is just a shortcut to \type {interfaces.numbers}.
336
337\stopsection
338
339\stopchapter
340
341\stopcomponent
342