Skip to content

Latest commit

 

History

History
167 lines (119 loc) · 3.29 KB

File metadata and controls

167 lines (119 loc) · 3.29 KB

Nimble

Nimble is an indentation-sensitive scripting language implemented as a register-based bytecode VM in Rust. It aims for Python-like readability with a small pragmatic standard library, optional type annotations, colorful diagnostics, and fast startup.

Current Status

Implemented today:

  • Register-based VM execution
  • Functions, lambdas, classes/struct-like objects, named arguments
  • if / elif / else, while, for, ranges, for ... step ...
  • Strings, lists, maps, ranges, interpolation
  • Errors as values with ? propagation
  • Local modules plus built-in stdlib modules
  • run, check, and repl CLI workflows
  • FFI stdlib for calling symbols from single .dll, .so, and .dylib files

Still experimental / limited:

  • JIT scaffolding exists but is not wired into normal execution
  • FFI currently supports native C ABI calls with primitive scalars, pointers, and C strings
  • FFI does not yet support callbacks, variadic functions, or by-value struct marshalling

Quick Start

Build:

cargo build --release

Create hello.nmb:

fn main():
    out("Hello, Nimble!")

main()

Run it:

cargo run --release -- run hello.nmb

Type-check only:

cargo run --release -- check hello.nmb

Start the REPL:

cargo run --release -- repl

Language Snapshot

fn fib(n int) -> int:
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

for i in 0..10 step 2:
    out("fib({i}) = {fib(i)}")

Nimble supports optional type annotations, named arguments, interpolated strings, module loading, and error propagation:

load io

fn first_line(path str) -> str | error:
    lines = io.read_lines(path)?
    if len(lines) == 0:
        return error("empty file")
    return lines[0]

out(first_line("data.txt")?)

Standard Library

The current stdlib includes:

  • io
  • ffi
  • json
  • list
  • map
  • math
  • net
  • os
  • path
  • process
  • regex
  • string
  • time

The FFI module can load a single dynamic library file directly and call exported symbols:

load ffi

lib = ffi.open("./native/mylib.dll")?
result = ffi.call(lib, "add", ["i32", "i32"], "i32", [2, 3])?
out(result)

For cross-platform loading:

load ffi

lib = ffi.open_any([
    "./native/mylib.dll",
    "./native/libmylib.so",
    "./native/libmylib.dylib",
])?

Examples

The repository ships runnable examples under examples/ for both core language features and each stdlib module.

Run a single example:

cargo run --release -- run examples/stdlib/json/roundtrip.nmb

On Windows, run the full release example sweep with:

.\rae.ps1

Verification

The repo includes integration coverage for:

  • shipped examples
  • language features like named arguments and stepped ranges
  • stdlib behavior
  • FFI examples

Typical verification commands:

cargo test
cargo build --release

License

MIT. See LICENSE.