Search by

cosmira / lua-builder

tabuna

Expressive, framework-independent Lua code generation for PHP.

Package info

github.com/cosmira/lua-builder

pkg:composer/cosmira/lua-builder

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-09-10 01:50 UTC

This package is auto-updated.

Last update: 2026-10-13 07:03:53 UTC


README

Coding Guidelines Tests Code Coverage

Generate Lua scripts from PHP.

Build configuration files and application-generated scripts from your PHP data. Compose functions, conditions, and loops while the builder takes care of quoting, expression grouping, and indentation.

use Cosmira\Lua\Lua;

echo Lua::script()->return([
    'name' => 'Moonlight',
    'enabled' => true,
    'servers' => ['127.0.0.1', '192.168.1.1'],
]);
return {["name"] = "Moonlight", ["enabled"] = true, ["servers"] = {"127.0.0.1", "192.168.1.1"}};

Requires PHP 8.2+. No framework or runtime dependencies. Generated syntax targets Lua 5.1–5.4 and LuaJIT. The package generates source; your application decides where to save or execute it.

Installation

The development version is available directly from GitHub. In your PHP project:

composer config repositories.cosmira-lua vcs https://github.com/cosmira/lua-builder
composer require cosmira/lua-builder:dev-main

Load vendor/autoload.php when running the examples outside a framework. A stable Packagist release has not been published yet.

Three concepts

Concept Example Meaning
PHP values 'hello', 42, ['enabled' => true] Data, quoted and encoded automatically
Expressions Lua::var('score')->greaterThan(80) A value Lua computes when the script runs
A script Lua::script()->call('print', 'hello') Commands emitted in order

Strings always mean data. Use Lua::var() for a variable and Lua::call() when you need the result of a function call. The script's ->call() adds a standalone call. Start an expression from a literal with Lua::value().

Lua::script()
    ->local('maximum', Lua::call('math.max', 10, 20))
    ->call('print', Lua::var('maximum'));

Functions and conditions

Callbacks describe nested bodies using the same script API:

use Cosmira\Lua\Lua;
use Cosmira\Lua\Script;

$score = Lua::var('score');

echo Lua::script()
    ->localFunction('grade', ['score'], function (Script $lua) use ($score) {
        $lua->if(
            $score->greaterThanOrEqual(80),
            fn (Script $lua) => $lua->return('passed'),
        );

        $lua->return('try again');
    })
    ->call('print', Lua::call('grade', 90));
local function grade(score)
    if (score >= 80) then
        return "passed";
    end
    return "try again";
end
print(grade(90));

->if($condition, $then, $otherwise) generates a Lua conditional. Both supplied PHP callbacks run while constructing their branches; Lua evaluates the condition when the generated program executes. The otherwise callback is optional.

Tables and loops

echo Lua::script()
    ->local('services', ['api', 'worker'])
    ->forEach(
        ['index', 'service'],
        Lua::call('ipairs', Lua::var('services')),
        fn (Script $lua) => $lua->call('print', Lua::var('index'), Lua::var('service')),
    );
local services = {"api", "worker"};
for index, service in ipairs(services) do
    print(index, service);
end

Expressions are immutable. Scripts accumulate commands and can be cloned to create independent variants. Literal strings preserve arbitrary bytes, including quotes, UTF-8 emoji, Windows-1251, Japanese encodings, and NUL. No encoding conversion or Unicode normalization is performed. Names and operators are validated.

Lua's data model applies: lists start at 1, nil removes table entries, and numeric precision depends on the Lua runtime. Raw source is an explicit escape hatch for trusted code only. See the API reference for all operations, value semantics, errors, and supported syntax.

Building rules from application data

The executable rules example combines nested filter tables, optional date bounds, generated callbacks, and ordered actions. PHP decides which rules to emit; Lua evaluates their conditions later. Opaque rule IDs are table keys, so they can contain punctuation or Japanese text without becoming function names. Runtime tests exercise matching, short-circuiting, date boundaries, and action order.

Keep model access, sorting, encoding conversion, and domain validation in your application. Pass plain arrays and values into the builder. The host supplies application behavior when Lua executes.

Development

git clone https://github.com/cosmira/lua-builder.git
cd lua-builder
composer install
LUA_BIN=lua5.1 composer test
LUA_BIN=lua5.1 composer check

Install PHP, Composer, and Lua first. Set LUA_BIN to your interpreter's name or absolute path; it defaults to lua. Runtime tests require a working interpreter. Coverage requires PCOV or an enabled Xdebug coverage driver.

composer check runs Pint, PHPStan, Rector, tests, 100% line coverage, and 100% mutation score gates. GitHub Actions tests PHP 8.2–8.5, Lua 5.1–5.4, and LuaJIT. Reports are uploaded as CI artifacts. See CONTRIBUTING.md for individual commands, project structure, and release conventions.

License

MIT. Maintained by Alexandr Chernyaev and Cosmira. See LICENSE.md.