Skip to content

ashevin/swift-lua-interpreter

Repository files navigation

LuaInterpreter

A Lua 5.5 interpreter written in Swift. It includes a complete lexer, recursive-descent parser, and tree-walking interpreter with a standard library, metatable support, and an interactive REPL.

Building

Requires Swift 5.10+ and Swift Package Manager.

swift build

Running

Interactive REPL

swift run LuaREPL
Lua 5.5 REPL (Swift)
Type Lua code to execute. Use 'exit' or Ctrl-D to quit.

> print("hello")
hello
> 2 + 2
4

Execute a file

swift run LuaREPL script.lua

Run the test suite

swift run LuaREPL test.lua

See docs/testing.md for details on using test.lua to compare against other Lua implementations.

Using the library

LuaInterpreter is also a Swift library. Add it as a dependency in your Package.swift:

.package(url: "https://github.com/ashevin/swift-lua-interpreter.git", from: "..."),

// In your target:
.product(name: "LuaInterpreter", package: "swift-lua-interpreter"),

One-shot execution

import LuaInterpreter

let results = try Lua.run("return 2 + 2")
// results == [.int(4)]

Persistent interpreter

let interp = Lua.createInterpreter()
try interp.execute("x = 10")
try interp.execute("x = x + 1")
print(interp.globals["x"])  // .int(11)

Registering native functions

let interp = Lua.createInterpreter()

// Full form: receives [LuaValue], returns [LuaValue]
interp.register("add") { args in
    guard case .int(let a) = args[0],
          case .int(let b) = args[1] else {
        throw LuaRuntimeError("expected integers")
    }
    return [.int(a + b)]
}

// Convenience: return a single Swift value directly
interp.register("double") { (args: [LuaValue]) -> Int64 in
    guard case .int(let n) = args.first else { return 0 }
    return n * 2
}

// Void return
interp.register("log") { (args: [LuaValue]) -> Void in
    print(args)
}

try interp.execute("print(add(1, 2))")    // 3
try interp.execute("print(double(21))")   // 42

Reading and writing globals

interp.globals["greeting"] = .string("hello")

let value = interp.globals["greeting"]  // .string("hello")

Syntax highlighting

let tokens = try Lua.highlight("local x = 10\nprint(x)")
for token in tokens {
    print(token.kind, token.range)
}
// keyword 0..<5, localVar 6..<7, operator 8..<9, number 10..<12,
// builtinVar 13..<18, punctuation 18..<19, localVar 19..<20, punctuation 20..<21

Project structure

Sources/
  LuaInterpreterParser/     # Frontend (internal SPM target)
    Lexer.swift             # Tokenization
    Token.swift             # Token types
    Parser.swift            # Recursive-descent parser → AST
    AST.swift               # Block, Statement, Expression, …
    Optimizer.swift         # Constant folding, dead code, unused locals
    SyntaxHighlighter.swift # Lua.highlight() / highlightPartial()
    LuaInterpreter.swift    # Lua.parse / optimize / highlight

  LuaInterpreterCore/       # Runtime foundation
    LuaValue.swift          # Runtime value type (enum)
    LuaTable.swift          # Lua table implementation
    Environment.swift       # Lexical scope chain
    Coercion.swift          # Numeric/string type coercion
    StandardLibrary.swift   # Built-in functions and libraries
    LuaInterpreterProtocol.swift
    LuaValueConvertible.swift
    LuaPattern.swift        # Pattern-matching engine

  LuaInterpreterTreeWalk/   # Tree-walking execution backend
    Interpreter.swift
    Lua+Execution.swift     # Lua.run / createInterpreter

  LuaInterpreterBytecode/   # Register-based bytecode VM
    Compiler.swift
    BytecodeInterpreter.swift
    …                       # Instruction, Prototype, CallFrame, …
    Lua+BytecodeExecution.swift

  LuaInterpreter/           # Public shim (re-exports all targets)
    Shim.swift
    Lua+UnifiedExecution.swift
    Lua+BlockExecution.swift

  LuaREPL/
    main.swift              # Interactive REPL and file runner

Tests/
  LuaInterpreterTests/      # Swift Testing suite
test.lua                    # Lua-level regression suite (432 tests)

Import LuaInterpreter for the full API. Individual products (LuaInterpreterCore, LuaInterpreterTreeWalk, LuaInterpreterBytecode) are also published; the parser target is internal-only and linked automatically by the backends.

Documentation

Running Swift tests

swift test

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors