Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

luawa

A Lua 5.4 implementation in Rust. Currently an AST-walking interpreter built on gc-arena; the long-term goal is to experiment with JIT compilation while keeping high compatibility.

$ cargo run --release -- script.lua [args...]

Architecture

  • src/lexer.rs — hand-written lexer for the full 5.4 token set (long strings/comments, all escapes, int/float/hex/hex-float numerals, PUC-style near '...' error context). Also home to parse_number, the string-to-number coercion used by tonumber and arithmetic.
  • src/ast.rs, src/parser.rs — recursive-descent parser doing single-pass scope resolution in the style of PUC's lparser.c: every variable reference is resolved at parse time to a frame slot, an upvalue index (threaded through enclosing functions), or a global; goto/label validity and <const> assignments are checked at parse time. String constants are deduplicated into a per-chunk string table.
  • src/value.rs, src/table.rs — the object model. Value is a small Copy enum over gc-arena Gc pointers; strings are immutable byte strings with precomputed hashes; tables have an array part plus an insertion-ordered hash part with Lua's key normalization (float keys with integer values collapse to integers; next stays valid when fields are cleared during traversal).
  • src/interp.rs — the tree-walking evaluator. Locals live in per- declaration heap cells (Gc<Lock<Value>>), so closures capture variables per loop iteration exactly like real Lua. Full 5.4 numeric semantics: integer/float subtypes, wrapping integer arithmetic, floor division/modulo, mathematically exact mixed int/float comparisons. Errors carry chunk:line: positions and PUC-style culprit info (local 'x', field 'y', ...).
  • src/pattern.rs — a faithful port of lstrlib.c's pattern matcher over byte slices.
  • src/stdlib/ — base library (print, pairs, pcall, error, load, ...), string (patterns, format including %q/%p), table, math (PUC's exact xoshiro256** PRNG), os, io, and minimal debug/utf8 stubs.

The interpreter recurses on the Rust stack, so luawa::run executes chunks on a dedicated thread with a 1 GiB (lazily committed) stack; Lua call depth is capped at 32k and raises a catchable stack overflow error.

Deliberately not implemented (yet)

Metatables (and metamethods), coroutines, _ENV, garbage-collector control (collection runs implicitly; collectgarbage is a stub), weak tables and finalizers, string.pack/string.dump, io file objects, and the utf8 library. getmetatable truthfully returns nil; setmetatable with a non-nil metatable raises an error rather than silently misbehaving. String values index the string library directly, so ("x"):rep(2) works without a string metatable.

Tests

$ cargo test
  • Unit tests live with each module (lexer, parser, interpreter semantics, pattern matcher, every stdlib module).
  • tests/scripts/*.lua are our own assert-based feature tests, run by the lua_scripts integration test.
  • tests/lua-5.4.8/ vendors the official Lua 5.4.8 test suite. A curated subset runs as integration tests: vararg, code, and math unmodified, and goto, literals, pm, sort, constructs, and strings with minimal, clearly marked -- [luawa] patches that disable only the sections needing unsupported features (metatables, coroutines, <close>, _ENV rebinding, string.pack, %a hex floats, string interning). Every patch site is greppable via the [luawa] marker.

About

Experimental toy Lua implementation

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages