4 | `Do{ stat* (`Return{expr*} | `Break)? }
5 | `Set{ {lhs+} {expr+} } -- lhs1, lhs2... = e1, e2...
6 | `While{ expr block } -- while e do b end
7 | `Repeat{ block expr } -- repeat b until e
8 | `If{ (expr block)+ block? } -- if e1 then b1 [elseif e2 then b2] ... [else bn] end
9 | `Fornum{ ident expr expr expr? block } -- for ident = e, e[, e] do b end
10 | `Forin{ {ident+} {expr+} block } -- for i1, i2... in e1, e2... do b end
11 | `Local{ {ident+} {expr+}? } -- local i1, i2... = e1, e2...
12 | `Localrec{ ident expr } -- no syntax expect in 'local function'
13 | `Goto{ <string> } -- no syntax
14 | `Label{ <string> } -- no syntax
15 | `Return{ <expr*> } -- allowed anywhere, unlike in plain Lua
16 | `Break -- allowed anywhere, unlike in plain Lua
20 | `Nil | `Dots | `True | `False
23 | `Function{ { ident* `Dots? } block }
24 | `Table{ ( `Pair{ expr expr } | expr )* }
25 | `Op{ opid expr expr? }
26 | `Stat{ block, expr }
33 | `Invoke{ expr `String{ <string> } expr* }
35 lhs: ident | `Index{ expr expr }
37 ident: `Id{ <string> }
39 opid: 'add' | 'sub' | 'mul' | 'div'
40 | 'mod' | 'pow' | 'concat'| 'eq'
41 | 'lt' | 'le' | 'and' | 'or'
45 ----------------------------------------------------------------------
46 -- The following lists some tolerances on the syntax, i.e. some
47 -- sloppy AST idioms that will not be produced as metalua output,
48 -- but which metalua will accept as input.
49 -- BEWARE: as of metalua 0.4, this is NOT implemented.
50 -- Constructive criticism is welcome, though.
51 ----------------------------------------------------------------------
56 These operations are automatically performed on AST, allowing users to
57 type/generate them in a somewhat sloppy form:
59 - When a list of ids/statements is expected and a lone id/stat is found,
60 it's lifted as a single-element list. Applies in:
61 `Set, `Fornum, `Forin, `Local, `Localrec
63 - In `Localrec and `Local, the right-hand-side list can be ommitted.
65 - When there are too many elements in Forin/Fornum/While/Repeat/Function,
66 the extra ones are regrouped as a block.
67 `While{ cond, foo, bar } -> `While{ cond, { foo, bar } }
69 - Numbers, strings, booleans are automatically lifted
72 - operators accept a direct form:
73 `Add{ a, b } -> `Op{ 'add', a, b }
75 - `Index{ a, b, c } is folded left -> `Index{ `Index{ a, b }, c }
77 - List are flattened in blocks: { a, { b, c }, d, { } , e } ->
80 - Parens around statements are tolerated:
81 `Paren{ `Call { foo, bar } } -> `Call{ foo, bar }
83 - `Boolean{ true } and `Boolean{ false } are accepted as aliases for
84 `True and `False, for the sake of uniform constant lifting.