# `a` `a` embeds a Lua interpreter and adds a standard library and IO access, so a script can reach the outside world — today an HTTP client and SQLite, with more of the surface below planned — without additional setup. ```sh a file.lua # run a script a # start an interactive REPL ``` Run `a` with a script path to execute it, or with no arguments to start an interactive REPL. ## The REPL Running `a` with no arguments starts a read-eval-print loop in the same sandboxed environment used for scripts, with the full standard library available. It is convenient for trying out the library or exploring data. - Bare expressions print their value (`1 + 1` → `2`); tables are pretty-printed with `utils.dump`. - Statements that span several lines (a `for` loop, a function body) are detected as incomplete and keep reading until they parse. - Async calls such as `os.sleep`, `http.get`, and `task.join` suspend and resume just as they do in a script — each entry runs on the async executor. - Line editing and history are provided, with history persisted to `~/.a_history`. Press Ctrl-D to exit (`os.exit` is not available in the sandbox). Each entry is compiled as its own chunk, so a `local` declared on one line is not visible on the next — assign to a global (drop the `local`) to keep a value across entries. ## What it is `a` is not a Lua implementation; it embeds [Lua 5.5](https://www.lua.org/) (via [`mlua`](https://github.com/mlua-rs/mlua)) and adds the parts stock Lua omits. Plain Lua ships almost no standard library and no way to reach the outside world without C modules and a build toolchain. `a` provides a standard library written partly in Rust and partly in Lua, together with IO access. The result is a single binary that runs a `.lua` file. There is no package manager, build step, or project scaffolding. ## The standard library The standard library is the main purpose of `a`. Available today: - **Networking** — HTTP client (WebSocket and MQTT are planned). - **SQLite** — access to embedded SQLite databases. - **Core helpers** — `math`, `table`, and `utils` extensions, structured `log`, `os` time helpers, and `task.join` concurrency. Planned: - **Filesystem** — read/write/glob/walk without stock Lua's `io` boilerplate. - **Terminal UI** — interactive line editing and full-screen TUI, comparable to `ncurses`. The intent is for the common case to be a single call rather than a multi-step setup. ## How it works - Embeds Lua 5.5 via `mlua`, on an async core ([`tokio`](https://tokio.rs/)) so IO-heavy scripts don't block. - A single self-contained binary. No LuaRocks, no make, no virtualenv. - Scripts run in a **sandboxed** environment modeled on [Luau's safe environment](https://luau.org/sandbox): `io`, `package`, and `debug` are not loaded; `os` is trimmed to its time functions; the bytecode/chunk-loading escape hatches (`load`, `loadfile`, `dofile`, `string.dump`) are removed. The library `a` provides is the supported way to reach the outside world. - A leading `#!` shebang line is skipped (after an optional UTF-8 BOM), so scripts can be made executable directly. Script files need not be valid UTF-8 — Lua source is byte-oriented. - Scripts can be split into files with a sandboxed [`require`](docs/require.md): modules are looked up next to the main script (symlinks resolved, so an executable script symlinked into `~/.local/bin` finds its files) and in `$A_INCLUDE_PATHS`, which can also be set in a `.env` beside the script. ## Building ```sh cargo build --release # binary at target/release/a cargo run -- lua/test.lua # run a script during development ``` Requires a Rust toolchain (2024 edition). Lua is vendored and built from source, so no system Lua is needed.