| | {{infobox |
| | | title = ALB Lua backend |
| | | tool = `albl.exe` ("ALBL — AdaLogic BASIC Lua transpiler") |
| | | produces = One self-contained `.lua` file (Lua 5.1+ / LuaJIT) |
| | | runs_on = stock Lua or LuaJIT + `alb_sdl3.dll` + `SDL3.dll` |
| | | emitter_unit = `Emit_Native_Lua` (emit_native_lua.adb) — ~8,500 lines |
| | | sibling = [[ALB MoonScript backend]] — the same runtime through a prettier dialect |
| | | status = Scriptable ALB — no compiler needed at the destination |
| | }} |
| | |
| | The **ALB Lua backend** — **ALBL** — compiles [[AdaLogic BASIC]] into **one self-contained `.lua` file**: program, runtime, and all. No compiler is needed where it lands — drop it next to `alb_sdl3.dll` and `SDL3.dll`, run `lua program.lua` (or `luajit`), and a BASIC program with a Prolog engine and a framebuffer comes alive inside the most embeddable scripting runtime ever made. |
| | |
| | ```alb One-liner |
| | albl game.alb --build |
| | → game.lua + SDL3.dll + run.bat → lua game.lua |
| | ``` |
| | |
| | ## Why Lua, and why it works |
| | |
| | Lua's proposition is unique among the backends: the emitted file is *portable source* that runs anywhere a Lua interpreter lives — game engines with Lua scripting, mods, tools, embedded hosts. The emitted header says it plainly: *"self-contained Lua 5.1+/LuaJIT runtime"* — the file doesn't even insist on LuaJIT; plain Lua 5.1 and up will do. |
| | |
| | The catch — that Lua is a *small* language — is exactly where the emitter earns its keep. Everything ALB needs that Lua doesn't have gets built out of Lua tables. |
| | |
| | ## A computer inside a script |
| | |
| | The runtime reconstructs ALB's machinery the way the [[ALB TypeScript backend|TypeScript backend]] does it in typed arrays — here, in plain tables: |
| | |
| | - **`albVas`** — the virtual address space: framebuffer and memory-mapped state as a Lua table |
| | - **`albGcAlive` / `albGcRefs` / `albGcChildA`–`D`** — the Dumptruck claim-grid, running *inside* Lua's own garbage collector (two collectors, one process) |
| | - **`albTextRows` + a cursor** — the console-overlay model: `PRINT` writes to a character grid, `LOCATE` positions the cursor — a terminal inside the window, killed only by `MODE NO CONSOLE` in source |
| | - **`albSaveStore` + `ALB_serialize_state`/`ALB_deserialize_state`** — whole-program `SAVE STATE`/`LOAD STATE`, Lua-side |
| | - **PURE arithmetic, for real** — `albPureGcd` reduces rationals properly; `PURE_ADD/SUB/MUL/DIV/POW` keep numerator and denominator separate so ⅓ stays exactly ⅓ |
| | - **64-bit-safe math shims** — `albDiv`, `albMod`, `albPowInt`, `ALB_shl`/`shr` — because Lua numbers are doubles and precision past 2^53 is a cliff, the emitter implements sized-integer ops as algorithms instead of trusting the operators |
| | - **The capability firewall** — `ALB_FIREWALL_ENTER/LEAVE/READ/WRITE/TOUCH` with per-frame allow tables — in a scripting language, where sandboxing is the whole *point* |
| | - **`ALB_KNOWS_GET/HAS/SET`** — the Knows store |
| | - **INI files, PPM export, `ALB_FILE_XOR`, bitmap/system fonts** — the file-and-format suite didn't get left behind either |
| | |
| | ## The Logic pillar, with rules |
| | |
| | This backend doesn't ship a toy Prolog — it ships the rule engine: |
| | |
| | ```lua |
| | local albRelPred = {}; local albRelArity = {} |
| | local albRelArg1 = {}; local albRelArg4 = {} |
| | local albRuleHeadPred = {}; local albRuleBodyLen = {} |
| | local albRuleBodyPred = {}; local albRuleBodyArgMode = {} |
| | ``` |
| | |
| | Facts live in one table family (`albRel*`), **rules** in another — `albRuleHeadPred` (the rule's head predicate), `albRuleBodyLen` and `albRuleBodyPred`/`ArgMode` (the body, with per-argument modes). `ALB_INIT_LOGIC` wires it up; `AST_Logic_Var` handles real unification variables; watch nodes re-evaluate when the KB changes. The Logic in Ada**Logic** BASIC, running in a language that fits in a few hundred kilobytes. |
| | |
| | ## The `alb_sdl3` bridge |
| | |
| | Graphics and input don't use LuaJIT's FFI at all — both script backends share one design: **`alb_sdl3.dll`, a Lua C-module** loaded by name: |
| | |
| | ```lua |
| | local ok, mod = pcall(require, "alb_sdl3") |
| | if not ok then ALB_FATAL("ALBL requires alb_sdl3.dll next to the .lua (and Lua 5.4).") end |
| | albSDL = mod |
| | albSDL.init() |
| | ``` |
| | |
| | One bridge, one call surface — `create_window`, `prepare_frame`, `color`, `clear`, `plot`, `draw_rect`, `fill_rect`, `draw_line`, `ticks` — behind which `SDL3.dll` does the actual work. Lazy-loaded via `albEnsureSDL()` so programs that never draw never pay for it, and `pcall` wraps the load so the failure message is friendly. |
| | |
| | ```fact The honest architecture note |
| | The driver's banner still advertises "LuaJIT FFI" — but the emitted code went a better way: `alb_sdl3.dll` as a shared C-module means the *same* binding serves stock Lua, LuaJIT, and (through moonc) the MoonScript sibling. One bridge to maintain instead of two FFI dialects. |
| | ``` |
| | |
| | ## The game loop |
| | |
| | `ON TICK` / `ON PAINT` / `ON KEY` blocks become literal Lua functions wired into a `while ALB_Running` loop that pumps the bridge's event queue — the same frame model as every other backend, expressed in `local function`s and tables. |
| | |
| | ## Flags and output |
| | |
| | `-o`, `--outdir`, `--metrics`, `--walker`, `--quiet`; `--build` stages `SDL3.dll` + a `run.bat` beside the `.lua` in `lua_<name>/`; `--run` finds `luajit.exe` (deps tree or PATH) and runs it in place. |
| | |
| | ## Under the hood |
| | |
| | `Emit_Native_Lua` (~8,500 lines, SPARK-annotated) is the AST-walker architecture: `Compile_To_File(Root, Output_Filename)` receives the whole tree and walks it top-down — the same shape as the [[ALB TypeScript backend|TypeScript]] and [[ALB Ada backend|Ada]] emitters, and *literally mirrored* by the MoonScript sibling, which shares the runtime design, the bridge, and most of its source structure. |
| | |
| | ## See also |
| | |
| | - [[AdaLogic BASIC]] — the language |
| | - [[ALB MoonScript backend]] — the sibling: same runtime, sweeter syntax, through `moonc` |
| | - [[ALB TypeScript backend]] — the other "computer in a file" |
| | - [[ALB FASM backend]] · [[ALB C backend]] · [[ALB .NET backend]] · [[ALB Ada backend]] · [[ALB NASM backend]] · [[ALB FASM16 backend]] |
| | |
| + | ## References |
| + | |
| + | 1. ALB Handbook — alb-lang.org/handbook — the language reference for all backends. |
| + | 2. ALB Technology page — alb-lang.org/technology — the sixteen-backend matrix. |
| + | 3. ALB source — github.com/rockyoliver454/AdaLogic-BASIC-ALB-Programming-Language — the emitter sources are Apache 2.0. |
| + | |
| | [[Category:Backends]] |
| | [[Category:AdaLogic BASIC]] |
| | |