DrakonTech
DrakonTech
Download

Generating Lua Code

Lua Logo

DrakonTech creates a single Lua module for a project.

The module code returns an object with exported functions.

To place code at the beginning of the module, create a function with the special name module.

The Lua code generator supports classes and state machines.

The generated Lua code looks roughly like this:

local math = require("math")
local os = require("os")
setfenv(1, {}) 

function random()
    return math.randomseed(os.time())
end

return {
    random = random
}

Automatic Variable Declaration

In ordinary Lua functions, DrakonTech declares variables automatically. This means that the local keyword is forbidden inside a function body.

If you need to declare a local variable, simply assign a value to it. The code generator will declare the variable automatically.

You write:

x = 10

The code generator produces:

local x
x = 10

There are two exceptions:

  1. In the module function, the local keyword is allowed but not required.
  2. In closures, variables must be declared explicitly with local.

In the following example, the items variable is declared automatically, while leftName and rightName must be declared manually because they are inside a closure:

items = {
    { name = "Charlie" },
    { name = "Alice" },
    { name = "Bob" }
}
table.sort(items, function(left, right)
    local leftName = left.name or ""
    local rightName = right.name or ""
    return leftName < rightName
end)

Foreach Loop

The Foreach Loop icon is the DRAKON equivalent of for and foreach loops.

In DRAKON-Lua, there are three ways to specify a Foreach Loop:

  1. Iteration over an array. The construct for _, item in ipairs(array) do ... end is written in the loop icon as item; array.
  2. Iteration over an object. The construct for key, item in pairs(map) do ... end is written as key, item; map.
  3. A for-style loop. The construct i = 0; i < count; i = i + 1 works the same way as in JavaScript.
Array Iteration in Lua

Array Iteration in Lua

Object Iteration in Lua

Object Iteration in Lua

For-Style Loop in Lua

For-Style Loop in Lua

An important feature is that for Lua, the generator does not add pairs() or ipairs() in certain cases:

  1. When the collection is a function call, for example: x, y; fun.iter(some_object).
  2. When the collection is an iterator expression, for example: i, code; utf8.next, text.
Looping Over a Value Returned by a Function in Lua

Looping Over a Value Returned by a Function in Lua

Iterator Loop in Lua

Iterator Loop in Lua

Module Isolation

In DrakonTech Lua modules, the module must be isolated from the global environment. This is necessary because DrakonTech declares functions globally, that is, without using the local keyword. As a result, the global environment becomes polluted. Using local function is impossible because of Lua's limit on the maximum number of local variables.

To isolate a module in LuaJIT 5.1, use the following expression:

setfenv(1, {})

This expression should be placed inside the module function. Example:

local table = table
local string = string
local pairs = pairs
local ipairs = ipairs
local type = type
local math = require("math")
local os = require("os")
setfenv(1, {})

For newer versions of Lua, a different trick is used to isolate the module:

local _ENV = {
    print = print,
    pairs = pairs,
    ipairs = ipairs,
    tostring = tostring,
    tonumber = tonumber,
    table = table,
    string = string,
    math = math,
    os = os
}

For Tarantool and Redis, setfenv(1, {}) is usually appropriate. For Lua 5.2 and later, _ENV = {...} is used instead.

Feedback

drakon.editor@gmail.com