Skip to main content

Module lua

Module lua 

Source
Expand description

The Lua backend of the shared codec walk.

DDS-XTypes 1.3 §7.4 from the clause, the same as runtime/c, runtime/python and the rest do, and none of them calls another. Where two columns disagree on an octet, one has misread the specification — which is the only reason to have another.

§The shapes this column holds a value in

adapter/lua.rs is the authority and this file spells nothing it does not declare:

  • a struct, a union, a bitset, a sequence, an array and a map are all tables — a sequence 1-based, a map an array of { key = …, value = … } pairs;
  • a char and a wchar are integers holding the code point, which is why Lua::code_point is the identity and a character case label stays the number it arrived as;
  • an unsigned long long is the 64-bit two’s-complement bit pattern in a Lua integer, which is why Lua::unsigned_less answers math.ult at eight octets — Lua’s < on two patterns is signed and sorted 16045690984833335998 after 7;
  • a long double and a fixed are decimal strings, converted at the octet by runtime/lua;
  • an absent @optional member is an absent key: v.m ~= nil is the presence test and v.m = nil the removal, because in Lua the absence of a value is the absence of the key.

§The four decisions this column turns on

Codecs live in one table. Every generated routine is function ZD.zd_enc_T(w, v) … end and every call is ZD.zd_enc_T, because a chunk holds at most 200 locals and a corpus case’s codecs, defaulters and dumpers together would cross that as local functions. A table lookup also resolves at the call and not at the definition, so a recursive or mutually recursive type needs no forward declaration — Lua::routine answers None for one, exactly as the Python backend does. The caller binds local ZD = {} before the declarations, the same contract adapter::lua::lua_items has for M.

An assignment is a statement. a = b is not a Lua expression. The shared walk builds one through T::perform(T::binary("=", …)) at every assignment site, so Lua::perform recognises that shape and answers lua::Stat::Assign; everything else it receives is a call, which is the one expression Lua’s grammar takes as a statement.

A counted loop stays zero-based and the subscript adds one. The walk counts 0 .. bound exclusive and compares counters against ranks; a backend that moved the loop to 1 .. bound would have to move the rank arithmetic with it. So Lua::count_up writes for i = 0, bound - 1 and Lua::index writes t[(i) + 1], and the 1-based convention is decided in exactly one method.

The boolean spellings are Lua’s. &&, ||, ! and != become and, or, not and ~=; false before true — the raw token the walk escapes through Literal::Int — is rewritten to the literal, as the Python backend does for False.

§What Lua cannot check, said plainly

Nothing in a generated chunk declares a type, so a wrong shape here is not a compile error anywhere — it is a wrong octet in the measurement or an error at run time. That is why this backend leans on the two loud failure modes Lua does have: a call through a name ZD does not hold reports the name at the line, and runtime/lua range-checks every value at the octet.

Structs§

Lua
The Lua backend.
LuaType
The nominal type a local is annotated with — which in Lua is nothing at all, so the type is a tag this backend keeps for its own two decisions: whether a cast target is boolean (a union label becomes true/false), and whether a storage request is the map entry marker. Everything else is carried through untouched.

Constants§

CODECS
The table the generated codecs, defaulters and dumpers live in.
RUNTIME
The table the runtime is required into: local zdw = require("zerodds_wire"). Prefixed like every other generated name, so no IDL identifier the corpus declares reaches it.