Lua.AST.Builder (Lua v1.0.0-rc.0)

View Source

Helpers for programmatically constructing AST nodes.

Provides a convenient API for building AST without manually creating all the struct fields. Useful for:

  • Code generation
  • AST transformations
  • Testing
  • Metaprogramming with quote/unquote

Examples

import Lua.AST.Builder

# Build a simple expression: 2 + 2
binop(:add, number(2), number(2))

# Build a local assignment: local x = 42
local(["x"], [number(42)])

# Build a function: function add(a, b) return a + b end
func_decl("add", ["a", "b"], [
  return_stmt([binop(:add, var("a"), var("b"))])
])

Summary

Functions

Creates an assignment statement.

Creates a binary operation.

Creates a Block node.

Creates a boolean literal

Creates a break statement

Creates a function call.

Creates a function call statement.

Creates a Chunk node.

Creates a do block.

Creates a generic for loop (for-in).

Creates a function declaration.

Creates a function expression.

Creates a goto statement

Creates an index access (obj[index])

Creates a label

Creates a local variable declaration.

Creates a local function declaration.

Creates a method call (obj:method(args))

Creates a nil literal

Creates a number literal

Creates a property access (obj.prop)

Creates a return statement.

Creates a string literal

Creates a table constructor.

Creates a unary operation.

Creates a variable reference

Creates a vararg expression (...)

Functions

assign(targets, values, meta \\ nil)

Creates an assignment statement.

Examples

# x = 10
assign([var("x")], [number(10)])

# x, y = 1, 2
assign([var("x"), var("y")], [number(1), number(2)])

binop(op, left, right, meta \\ nil)

Creates a binary operation.

Operators

  • :add, :sub, :mul, :div, :floor_div, :mod, :pow
  • :concat
  • :eq, :ne, :lt, :gt, :le, :ge
  • :and, :or

Examples

binop(:add, number(2), number(3))  # 2 + 3
binop(:lt, var("x"), number(10))    # x < 10

block(stmts, meta \\ nil)

@spec block([Lua.AST.Statement.t()], Lua.AST.Meta.t() | nil) :: Lua.AST.Block.t()

Creates a Block node.

Examples

block([
  local(["x"], [number(10)]),
  assign([var("x")], [number(20)])
])

bool(value, meta \\ nil)

@spec bool(boolean(), Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.Bool.t()

Creates a boolean literal

break_stmt(meta \\ nil)

@spec break_stmt(Lua.AST.Meta.t() | nil) :: Lua.AST.Statement.Break.t()

Creates a break statement

call(func, args, meta \\ nil)

Creates a function call.

Examples

call(var("print"), [string("hello")])  # print("hello")
call(property(var("io"), "write"), [string("test")])  # io.write("test")

call_stmt(call_expr, meta \\ nil)

Creates a function call statement.

Examples

call_stmt(call(var("print"), [string("hello")]))

chunk(stmts, meta \\ nil)

@spec chunk([Lua.AST.Statement.t()], Lua.AST.Meta.t() | nil) :: Lua.AST.Chunk.t()

Creates a Chunk node.

Examples

chunk([local(["x"], [number(42)])])

do_block(body_stmts, meta \\ nil)

@spec do_block([Lua.AST.Statement.t()], Lua.AST.Meta.t() | nil) ::
  Lua.AST.Statement.Do.t()

Creates a do block.

Examples

# do local x = 10; print(x) end
do_block([
  local(["x"], [number(10)]),
  call_stmt(call(var("print"), [var("x")]))
])

for_in(vars, iterators, body_stmts, meta \\ nil)

Creates a generic for loop (for-in).

Examples

# for k, v in pairs(t) do print(k, v) end
for_in(
  ["k", "v"],
  [call(var("pairs"), [var("t")])],
  [call_stmt(call(var("print"), [var("k"), var("v")]))]
)

for_num(var_name, start, limit, body_stmts, opts \\ [])

Creates a numeric for loop.

Examples

# for i = 1, 10 do print(i) end
for_num("i", number(1), number(10), [
  call_stmt(call(var("print"), [var("i")]))
])

# for i = 1, 10, 2 do print(i) end
for_num("i", number(1), number(10), [...], step: number(2))

func_decl(name, params, body_stmts, opts \\ [])

@spec func_decl(
  String.t() | [String.t()],
  [String.t()],
  [Lua.AST.Statement.t()],
  keyword()
) ::
  Lua.AST.Statement.FuncDecl.t()

Creates a function declaration.

Examples

# function add(a, b) return a + b end
func_decl("add", ["a", "b"], [
  return_stmt([binop(:add, var("a"), var("b"))])
])

# function math.add(a, b) return a + b end
func_decl(["math", "add"], ["a", "b"], [...])

function_expr(params, body_stmts, opts \\ [])

@spec function_expr([String.t()], [Lua.AST.Statement.t()], keyword()) ::
  Lua.AST.Expr.Function.t()

Creates a function expression.

Examples

# function(x, y) return x + y end
function_expr(["x", "y"], [
  return_stmt([binop(:add, var("x"), var("y"))])
])

# function(...) return ... end
function_expr([], [return_stmt([vararg()])], vararg: true)

goto_stmt(label, meta \\ nil)

@spec goto_stmt(String.t(), Lua.AST.Meta.t() | nil) :: Lua.AST.Statement.Goto.t()

Creates a goto statement

if_stmt(condition, then_stmts, opts \\ [])

Creates an if statement.

Examples

# if x > 0 then print(x) end
if_stmt(
  binop(:gt, var("x"), number(0)),
  [call_stmt(call(var("print"), [var("x")]))]
)

# if x > 0 then ... elseif x < 0 then ... else ... end
if_stmt(
  binop(:gt, var("x"), number(0)),
  [call_stmt(...)],
  elseif: [{binop(:lt, var("x"), number(0)), [call_stmt(...)]}],
  else: [call_stmt(...)]
)

index(table, key, meta \\ nil)

Creates an index access (obj[index])

Examples

index(var("t"), number(1))  # t[1]

label(name, meta \\ nil)

@spec label(String.t(), Lua.AST.Meta.t() | nil) :: Lua.AST.Statement.Label.t()

Creates a label

local(names, values \\ [], meta \\ nil)

@spec local([String.t()], [Lua.AST.Expr.t()], Lua.AST.Meta.t() | nil) ::
  Lua.AST.Statement.Local.t()

Creates a local variable declaration.

Examples

# local x
local(["x"], [])

# local x = 10
local(["x"], [number(10)])

# local x, y = 1, 2
local(["x", "y"], [number(1), number(2)])

local_func(name, params, body_stmts, opts \\ [])

Creates a local function declaration.

Examples

# local function add(a, b) return a + b end
local_func("add", ["a", "b"], [
  return_stmt([binop(:add, var("a"), var("b"))])
])

method_call(object, method, args, meta \\ nil)

@spec method_call(
  Lua.AST.Expr.t(),
  String.t(),
  [Lua.AST.Expr.t()],
  Lua.AST.Meta.t() | nil
) ::
  Lua.AST.Expr.MethodCall.t()

Creates a method call (obj:method(args))

Examples

method_call(var("file"), "read", [string("*a")])  # file:read("*a")

nil_lit(meta \\ nil)

@spec nil_lit(Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.Nil.t()

Creates a nil literal

number(value, meta \\ nil)

@spec number(number(), Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.Number.t()

Creates a number literal

property(table, field, meta \\ nil)

@spec property(Lua.AST.Expr.t(), String.t(), Lua.AST.Meta.t() | nil) ::
  Lua.AST.Expr.Property.t()

Creates a property access (obj.prop)

Examples

property(var("io"), "write")  # io.write

repeat_stmt(body_stmts, condition, meta \\ nil)

Creates a repeat-until loop.

Examples

# repeat x = x - 1 until x <= 0
repeat_stmt(
  [assign([var("x")], [binop(:sub, var("x"), number(1))])],
  binop(:le, var("x"), number(0))
)

return_stmt(values, meta \\ nil)

@spec return_stmt([Lua.AST.Expr.t()], Lua.AST.Meta.t() | nil) ::
  Lua.AST.Statement.Return.t()

Creates a return statement.

Examples

# return
return_stmt([])

# return 42
return_stmt([number(42)])

# return x, y
return_stmt([var("x"), var("y")])

string(value, meta \\ nil)

@spec string(String.t(), Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.String.t()

Creates a string literal

table(fields, meta \\ nil)

@spec table(
  [{:list, Lua.AST.Expr.t()} | {:record, Lua.AST.Expr.t(), Lua.AST.Expr.t()}],
  Lua.AST.Meta.t() | nil
) :: Lua.AST.Expr.Table.t()

Creates a table constructor.

Field types

  • {:list, expr} - array-style field (value only)
  • {:record, key_expr, value_expr} - key-value field

Examples

# Empty table: {}
table([])

# Array: {1, 2, 3}
table([
  {:list, number(1)},
  {:list, number(2)},
  {:list, number(3)}
])

# Record: {x = 10, y = 20}
table([
  {:record, string("x"), number(10)},
  {:record, string("y"), number(20)}
])

unop(op, operand, meta \\ nil)

@spec unop(atom(), Lua.AST.Expr.t(), Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.UnOp.t()

Creates a unary operation.

Operators

  • :not - logical not
  • :neg - negation (-)
  • :len - length operator (#)

Examples

unop(:neg, var("x"))   # -x
unop(:not, var("flag")) # not flag
unop(:len, var("list")) # #list

var(name, meta \\ nil)

@spec var(String.t(), Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.Var.t()

Creates a variable reference

vararg(meta \\ nil)

@spec vararg(Lua.AST.Meta.t() | nil) :: Lua.AST.Expr.Vararg.t()

Creates a vararg expression (...)

while_stmt(condition, body_stmts, meta \\ nil)

Creates a while loop.

Examples

# while x > 0 do x = x - 1 end
while_stmt(
  binop(:gt, var("x"), number(0)),
  [assign([var("x")], [binop(:sub, var("x"), number(1))])]
)