% language=us runpath=texruns:manuals/cld

\startcomponent cld-variables

\environment cld-environment

\startchapter[title={Variables}]

\startsection[title={Introduction}]

\index {variables}

Sometimes a bit of experimenting and exploring the boundaries of the \TEX|-|\LUA\
interfaces results in new mechanisms. To what extent they are really useful is
hard to say but we just keep them around. Some are described here. This is, at
least for the moment, a \LMTX\ specific chapter.

\stopsection

\startsection[title={Simple tables}]

\index {variables+grouped tables}

The basic \TEX\ data types are counters (integers), dimensions (kind of floating
point variables with typographic dimensions), token lists, node lists (boxes),
fonts, and so on, but no data organized in tables. The first mechanism that we
discuss is one that obeys grouping. In that respect is behaves like regular
registers.

\startbuffer
\newhashedtable\somehashtable

\somehashtable{ foo = 123, bar = "foo" }
[123 = \the\somehashtable{foo}]
[foo = \the\somehashtable{bar}]

\bgroup
\somehashtable{ foo = 456, bar = "oof" }
[456 = \the\somehashtable{foo}]
[oof = \the\somehashtable{bar}]
\egroup

[123 = \the\somehashtable{foo}]
[foo = \the\somehashtable{bar}]

\bgroup
\global\somehashtable{ foo = 456 }
       \somehashtable{ bar = "oof" }
[456 = \the\somehashtable{foo}]
[oof = \the\somehashtable{bar}]
\egroup

[456 = \the\somehashtable{foo}]
[foo = \the\somehashtable{bar}]
\stopbuffer

\typebuffer

We define a hashed table, one with keys and values. The definition is global.
We can then assign values to this table where the assignments themselves are
hash tables. The above code generates:

\getbuffer

As you can see, the \type {\global} prefix makes the value persistent outside the
group. You can mix local and global assignments.

Instead of a hashed table, you can have an indexed table. This time the keys are
numbers.

\startbuffer
\newindexedtable\someindextable

\someindextable{ 123, "foo" }
[123 = \the\someindextable 1]
[foo = \the\someindextable 2]

\bgroup
\someindextable{ 456, "oof" }
[456 = \the\someindextable 1]
[oof = \the\someindextable 2]
\egroup

[123 = \the\someindextable 1]
[foo = \the\someindextable 2]

\bgroup
\global\someindextable{ [1] = 456 }
       \someindextable{ [2] = "oof" }
[456 = \the\someindextable 1]
[oof = \the\someindextable 2]
\egroup

[456 = \the\someindextable 1]
[foo = \the\someindextable 2]
\stopbuffer

\typebuffer

The outcome is the same as before:

\getbuffer

At the \LUA\ end you can access these tables too:

\startbuffer
\startluacode
context("[hashed : bar = %s]",context.hashedtables.somehashtable.bar)
context("[indexed : 2 = %s]", context.indexedtables.someindextable[2])
\stopluacode
\stopbuffer

\typebuffer

Indeed we get:

\getbuffer

\stopsection

\startsection[title={Data tables}]

\index {variables+data tables}

In \LUA, tables can be more complex than in the previous section. When you need
more complex tables, it is likely that your grouping needs are also different,
which is why we have another mechanism. This mechanism is build on top of another
model: data values. There are 64K integer registers in any modern \TEX\ engine
and normally that is more than enough. However, in addition in \LUAMETATEX\ we
have a variant integer storage unit, one that is lightweight and where the amount
is limited by the size of the hash table. It was added as part of the low level
cleanup up of the \LUA\ token interface (a bit more abstraction). Here is an
example of its usage:

\startbuffer
\dorecurse {100} {
    \setdatavalue{#1}{#1}
}

\start \tttf \darkred \raggedright \dorecurse {100} {
    #1=\scratchcounter\getdatavalue{#1}\the\scratchcounter
} \par \stop \blank

\start \tttf \darkgreen \raggedright \dorecurse {100} {
    #1=\thedatavalue{#1}%
} \par \stop \blank
\stopbuffer

\typebuffer

\getbuffer

We define hundred values which are a simple numeric macros. Here we use two
auxiliary macros because we prefer to use a dedicated namespace for these
variables. However, there are also primitives that deal with these data values:

\startbuffer[usage]
\setdatavalue{my-data}{12345}%
\integerdef   \MyDataI 67890
\dimensiondef \MyDataD 12345pt
\thedatavalue{my-data}, \the\MyDataI, \the\MyDataD.
\stopbuffer

\typebuffer[usage]

gives: \inlinebuffer[usage]

But, when more is needed than simple integers, tables come into view. This interface
is different from the simple one and involves more commands. The next examples show
about all:

\startbuffer
\newluatable\testtable
\setluatable\testtable{ foo = 123, bar = "456", oof = "rab" }
% \inspectluatable\testtable
\darkcyan
foo = \getfromluatable\testtable{foo}\par
bar = \getfromluatable\testtable{bar}\par
oof = \getfromluatable\testtable{oof}\par
\bgroup
    \useluatable\testtable
    \setluatable\testtable{ foo = 123123, bar = "456456" }
  % \inspectluatable\testtable
    \darkmagenta
    foo = \getfromluatable\testtable{foo}\par
    bar = \getfromluatable\testtable{bar}\par
    oof = \getfromluatable\testtable{oof}\par
    \startluacode
        local t = context.luatables.get("testtable")
        context("<%s %s %s>",t.foo,t.bar,t.oof)
    \stopluacode \par
\egroup
\darkyellow
foo = \getfromluatable\testtable{foo}\par
bar = \getfromluatable\testtable{bar}\par
oof = \getfromluatable\testtable{oof}\par
\startluacode
    local t = context.luatables.get("testtable")
    context("<%s %s %s>",t.foo,t.bar,t.oof)
\stopluacode \par
% \inspectluatable\testtable
\stopbuffer

\typebuffer

The tables are semi|-|local: \type {\newluatable} creates a table and \type
{\useluatable} will create a local copy that is discarded when the group ends.

\startpacked
\tttf \getbuffer
\stoppacked

Hashed and indexed tables can be used mixed, but there are additional accessors
for indexed tables because there we expect numbers.

\startbuffer
\newluatable\moretable
\setluatable\moretable{ 1, "foo" }
\darkcyan
[1] = \getfromluatable\moretable{1}\par
[2] = \idxfromluatable\moretable 2 \par
\bgroup
    \useluatable\moretable
    \setluatable\moretable{ foo = 123123, bar = "456456" }
    \darkmagenta
    [1] = \getfromluatable\moretable{1}\par
    [2] = \idxfromluatable\moretable 2 \par
    \startluacode
        local t = context.luatables.get("moretable")
        context("<%s %s>",t[1],t[2])
    \stopluacode \par
\egroup
\darkyellow
[1] = \getfromluatable\moretable{1}\par
[2] = \idxfromluatable\moretable 2 \par
\startluacode
    local t = context.luatables.get("moretable")
    context("<%s %s>",t[1],t[2])
\stopluacode \par
\stopbuffer

\typebuffer

\startpacked
\tttf \getbuffer
\stoppacked

You can create more complex (nested) tables that you can handle at the \LUA\
end in the usual way. Basically any \LUA\ that makes a table can go between
the curly braces.

\stopsection

\startsection[title=Named variables]

\index {variables+named}
\index {variables+integers}
\index {variables+cardinals}
\index {variables+floats}
\index {integers}
\index {cardinals}
\index {floats}

Just because it can be done, and maybe it even has it use, we offer additional
numbers, stored and accessible by name. The different types all live in their
own namespace:

\startbuffer[definition]
\luainteger bar 123456
\luafloat   bar 123.456e12
\luainteger gnu = 0xFFFF
\stopbuffer

\startbuffer[usage]
{\darkcyan   \the\luainteger bar}
{\darkmagenta\the\luafloat   bar}
{\darkyellow \the\luainteger gnu}
\stopbuffer

\typebuffer[definition,usage] \getbuffer[definition]

These serialize like: \getbuffer[usage]\removeunwantedspaces , and when not set they
default to zero. There is an extra type, cardinal:

\startbuffer
\luainteger  a  0x7FFFFFFFFFFFFFFF
\luainteger  b -0x7FFFFFFFFFFFFFFF
\luacardinal c  0xFFFFFFFFFFFFFFFF
\stopbuffer

\typebuffer \getbuffer

We cheat a bit behind the screens because it is actually a double but we scan
it as positive integer and serialize it as such.

\startbuffer
[\the \luainteger  a\relax]\par
[\the \luainteger  b\relax]\par
[\the \luacardinal c\relax]\par
\stopbuffer

\typebuffer \getbuffer

You have access to the numbers at the \LUA\ end, as in:

\startbuffer
\luainteger one 123 \luafloat two 456.678
\luaexpr{interfaces.numbers.one/1000 + interfaces.numbers.two/10000}
\stopbuffer

\typebuffer

There are \type {integers}, \type {cardinals} and \type {floats} but the \type
{numbers} one is the most generic as it tries to resolve it from one of these
namespaces, so we get: [\inlinebuffer\space\space]. There is also a related
expression command:

\startbuffer
(?: \luaexpression          {n.one/1000 + n.two/10000})
(f: \luaexpression float    {n.one/1000 + n.two/10000})
(i: \luaexpression integer  {n.one/1000 + n.two/10000})
(c: \luaexpression cardinal {n.one/1000 + n.two/10000})
(l: \luaexpression lua      {n.one/1000 + n.two/10000})
\stopbuffer

\typebuffer

It typesets this (watch the \type {lua} variant, which is a precise
roundtrip serialization method):

\startlines
\tttf \getbuffer
\stoplines

The \type {n} table is just a shortcut to \type {interfaces.numbers}.

\stopsection

\stopchapter

\stopcomponent
