Lua
1 Calling Lua from Racket
1.1 Requiring Modules
1.2 Evaluating Code at Runtime
2 Calling Racket from Lua
3 Differences from Lua
3.1 Chunks
3.2 The goto Statement and Labels
3.3 Values
4 REPL
5 Reference
5.1 Values
lua-value/  c
nil
nil?
~lua-bytes
~lua
table?
make-table
in-table
table-ref
table-set!
table-length
table-metatable
set-table-metatable!
5.2 Environments
make-initial-environment
current-racket-imports-enabled?
current-global-environment
current-standard-library-modules
8.12

Lua🔗ℹ

Bogdan Popa <bogdan@defn.io>

 (require lua) package: lua-lang

This package provides a #lang implementation of the Lua programming language. It is still a work in progress, but much of the core language is supported already.

1 Calling Lua from Racket🔗ℹ

1.1 Requiring Modules🔗ℹ

Lua modules can be imported directly from Racket. Every Lua module provides a list called #%chunk which represents the set of return values of that module. For example, if you save the following program to a file named "add1.lua":

#lang lua
 
function add1(x)
  return 1 + x
end
 
return {add1 = add1}

You can use it from Racket like so:

(require lua/value "add1.lua")
(define add1 (table-ref (car #%chunk) #"add1"))
(add1 5)

1.2 Evaluating Code at Runtime🔗ℹ

You can run Lua code at runtime using racket/sandbox. For example:

> (require racket/sandbox)
> ((make-module-evaluator "#lang lua\nreturn 42") '#%chunk)

'(42)

> ((make-module-evaluator "#lang lua\nreturn 42, 43") '#%chunk)

'(42 43)

>
> (define dangerous-prog
    (string-append
     "#lang lua\n"
     "\n"
     "return io.input('/etc/passwd'):read('a')"))
> ((make-module-evaluator dangerous-prog) '#%chunk)

open-input-file: `read' access denied for /etc/passwd

> (define chunk
    (parameterize ([sandbox-path-permissions '((read #rx#".*"))])
      ((make-module-evaluator dangerous-prog) '#%chunk)))
> (subbytes (car chunk) 0 5)

#"root:"

2 Calling Racket from Lua🔗ℹ

Lua modules can access values from racket/base by indexing into the racket global. This is only allowed when the value of current-racket-imports-enabled? is #t.

#lang lua
 
local list = racket.list
print(list(1, 2, 3))

You can also alter the global environment in any way you like via the current-global-environment parameter.

3 Differences from Lua🔗ℹ

3.1 Chunks🔗ℹ

Chunks may return multiple values, but everything after the first value is discarded when the results get bound to #%chunk.

3.2 The goto Statement and Labels🔗ℹ

Labels are lexically scoped so the goto statement cannot jump to labels that have not yet been defined at the time the statement is executed or that are outside its scope.

3.3 Values🔗ℹ

Integers are backed by regular Racket integer? values, so they do not overflow.

4 REPL🔗ℹ

You can run a Lua REPL by loading the lua/repl module:

  racket -l lua/repl -i  

Note that unlike a typical REPL, since lua is statement oriented, you must return values for them to be printed. Multi-line statements can be entered by bracketing them with :{ and :}. For example:

> :{

| do

|   local x = 42

|   print(x)

| end

| :}

42

Individual local declarations at the top level have no effect.

5 Reference🔗ℹ

5.1 Values🔗ℹ

 (require lua/value) package: lua-lib

The contract that identifies Lua values. Note that Lua strings map to bytes? values.

value

nil : nil?

procedure

(nil? v)  boolean?

  v : any/c
The nil value and the predicate that identifies it.

procedure

(~lua-bytes v)  bytes?

  v : lua-value/c
Returns the result of calling the lua tostring procedure on v.

procedure

(~lua v)  string?

  v : lua-value/c
Like ~lua-bytes but converts the result to a string, decoding the bytes as UTF-8 and replacing any invalid sequences with #\�.

procedure

(table? v)  boolean?

  v : any/c
Returns #t when v is a table.

procedure

(make-table v ...)  table?

  v : (or/c lua-value/c (cons/c lua-value/c lua-value/c))
Creates a table?. Plain values are indexed sequentially, consed values represent key-value pairs and do not modify the sequence number.

Examples:
> (require lua/value)
> (make-table 1 2 nil 3 (cons #"a" #"b"))

(make-table 1 2 nil 3 '(#"a" . #"b"))

procedure

(in-table t)  sequence?

  t : table?
Converts t to a sequence, returning values up to one of its borders.

procedure

(table-ref t k [default-proc])  lua-value/c

  t : table?
  k : lua-value/c
  default-proc : (-> lua-value/c) = default
Retrieves the value at k from t. If t doesn’t contain k, the default-proc is called. When not provided, the default-proc looks up missing keys in the table’s metatable.

This procedure is used during index lookups in Lua code.

procedure

(table-set! t k v)  void?

  t : table?
  k : lua-value/c
  v : lua-value/c
Adds v to t under v, replacing any existing values. If v is nil, the key is removed from the table instead.

This procedure is used during index assignments in Lua code.

procedure

(table-length t)  exact-nonnegative-integer?

  t : table?
Returns a border of t.

procedure

(table-metatable t)  (or/c nil? table?)

  t : table?
Returns t’s metatable.

This procedure is accessible from Lua code as getmetatable.

procedure

(set-table-metatable! t meta)  table?

  t : table?
  meta : table?
Sets t’s metatable to meta and returns t.

This procedure is accessible from Lua code as setmetatable.

5.2 Environments🔗ℹ

 (require lua/env) package: lua-lib

Returns a table? representing the initial environment. This procedure creates a new table each time it is called, but the values inside it may be shared between calls.

parameter

(current-racket-imports-enabled?)  boolean?

(current-racket-imports-enabled? enabled?)  void?
  enabled? : boolean?
 = #f
Controls whether or not Lua modules can access Racket code via the racket global. Defaults to #f, except during the time when the Lua standard library (distributed with this package) is loaded.

Holds the global environment that is used when Lua chunks are evaluated.

parameter

(current-standard-library-modules)

  
(listof (cons/c bytes?
                (or/c module-path?
                      resolved-module-path?
                      module-path-index?)))
(current-standard-library-modules modules)  void?
  modules : 
(listof (cons/c bytes?
                (or/c module-path?
                      resolved-module-path?
                      module-path-index?)))
Holds the set of modules that are loaded into every Lua module. You can remove values from this set in order to disable certain bits of functionality (eg. file i/o), or you may add new modules to the set to inject your own functionality. The modules are loaded in order, and there may be dependencies from latter modules to earlier ones.

Modules in this list are typically only instantiated once so they must not modify the global environment because the global environment may change to a fresh table after these modules are loaded for the first time.