`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, SQLite and interactive terminal prompts, with more of the surface below planned — without additional setup.
Luna embeds a Lua interpreter and adds a standard library and IO access, so a script can reach the outside world — today an HTTP client, SQLite and interactive terminal prompts, with more of the surface below planned — without additional setup.
```sh
a file.lua # run a script
a # start an interactive REPL
luna file.lua # run a script
luna # start an interactive REPL
```
Run `a` with a script path to execute it, or with no arguments to start an
Run `luna` 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
Running `luna` 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.
@ -23,7 +23,7 @@ available. It is convenient for trying out the library or exploring data.
- 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
`~/.luna_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
@ -32,13 +32,13 @@ 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.
Luna 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. Luna 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:
The standard library is the main purpose of Luna. Available today:
- **Networking** — HTTP client (WebSocket and MQTT are planned).
- **SQLite** — access to embedded SQLite databases.
@ -57,15 +57,15 @@ The intent is for the common case to be a single call rather than a multi-step s
- 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.
- 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 Luna 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.
- 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 `$LUNA_INCLUDE_PATHS`, which can also be set in a `.env` beside the script.
## Building
```sh
cargo build --release
# binary at target/release/a
# binary at target/release/luna
cargo run -- lua/test.lua # run a script during development