================================================================================
variable assignments
================================================================================

x, y = 5.25, -3.5
r, g, b, a = 0xf2, 0x3b, 0x2c

--------------------------------------------------------------------------------

(chunk
  (variable_assignment
    (variable_list
      (variable
        name: (identifier))
      (variable
        name: (identifier)))
    (expression_list
      value: (number)
      value: (number)))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier))
      (variable
        name: (identifier))
      (variable
        name: (identifier))
      (variable
        name: (identifier)))
    (expression_list
      value: (number)
      value: (number)
      value: (number))))

================================================================================
local variable declarations
================================================================================

local pi<const> = math.pi

local circumference, nothing<close> = 2 * pi * 24

--------------------------------------------------------------------------------

(chunk
  (local_variable_declaration
    (variable_list
      (variable
        name: (identifier)
        (attribute
          name: (identifier))))
    (expression_list
      value: (variable
        table: (identifier)
        field: (identifier))))
  (local_variable_declaration
    (variable_list
      (variable
        name: (identifier))
      (variable
        name: (identifier)
        (attribute
          name: (identifier))))
    (expression_list
      value: (binary_expression
        left: (binary_expression
          left: (number)
          right: (variable
            name: (identifier)))
        right: (number)))))

================================================================================
function calls (as statement)
================================================================================

print(_G)
print''
print""
print[[]]
print{}

io.output()
io.output():read()

--------------------------------------------------------------------------------

(chunk
  (call
    function: (variable
      name: (identifier))
    arguments: (argument_list
      (expression_list
        (variable
          name: (identifier)))))
  (call
    function: (variable
      name: (identifier))
    arguments: (argument_list
      (string)))
  (call
    function: (variable
      name: (identifier))
    arguments: (argument_list
      (string)))
  (call
    function: (variable
      name: (identifier))
    arguments: (argument_list
      (string)))
  (call
    function: (variable
      name: (identifier))
    arguments: (argument_list
      (table)))
  (call
    function: (variable
      table: (identifier)
      field: (identifier))
    arguments: (argument_list))
  (call
    function: (variable
      table: (call
        function: (variable
          table: (identifier)
          field: (identifier))
        arguments: (argument_list))
      method: (identifier))
    arguments: (argument_list)))

================================================================================
labels
================================================================================

goto next_line
:: next_line ::

--------------------------------------------------------------------------------

(chunk
  (goto_statement
    name: (identifier))
  (label_statement
    name: (identifier)))

================================================================================
simple conditional structures
================================================================================

if true then end
if false then else end
if false then elseif true then end
if false then elseif false then elseif false then elseif true then else end

temperature = math.random(0, 50)
if temperature > 25 then
  print"is hot"
end

n = math.random(0, 100)
if n % 2 == 0 then
  print"is even"
else
  print"is odd"
end

weathers = {"rain", "windy"}
weather = weathers[math.random(2)]
if weather == "rain" then
  print"just stay home, it's raining"
elseif weather == "windy" then
  print"just stay home, it's too windy"
end

average_note = math.random(0, 10)
if average_note >= 7.5 then
  print"A"
elseif average_note >= 6 then
  print"B"
elseif average_note >= 4 then
  print"C"
elseif average_note >= 2 then
  print"D"
else
  print"E"
end

--------------------------------------------------------------------------------

(chunk
  (if_statement
    condition: (true))
  (if_statement
    condition: (false)
    alternative: (else_clause))
  (if_statement
    condition: (false)
    alternative: (elseif_clause
      condition: (true)))
  (if_statement
    condition: (false)
    alternative: (elseif_clause
      condition: (false))
    alternative: (elseif_clause
      condition: (false))
    alternative: (elseif_clause
      condition: (true))
    alternative: (else_clause))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (call
        function: (variable
          table: (identifier)
          field: (identifier))
        arguments: (argument_list
          (expression_list
            (number)
            (number))))))
  (if_statement
    condition: (binary_expression
      left: (variable
        name: (identifier))
      right: (number))
    consequence: (block
      (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (string)))))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (call
        function: (variable
          table: (identifier)
          field: (identifier))
        arguments: (argument_list
          (expression_list
            (number)
            (number))))))
  (if_statement
    condition: (binary_expression
      left: (binary_expression
        left: (variable
          name: (identifier))
        right: (number))
      right: (number))
    consequence: (block
      (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (string))))
    alternative: (else_clause
      body: (block
        (call
          function: (variable
            name: (identifier))
          arguments: (argument_list
            (string))))))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (table
        (field_list
          (field
            value: (string))
          (field
            value: (string))))))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (variable
        table: (identifier)
        field: (call
          function: (variable
            table: (identifier)
            field: (identifier))
          arguments: (argument_list
            (expression_list
              (number)))))))
  (if_statement
    condition: (binary_expression
      left: (variable
        name: (identifier))
      right: (string))
    consequence: (block
      (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (string))))
    alternative: (elseif_clause
      condition: (binary_expression
        left: (variable
          name: (identifier))
        right: (string))
      consequence: (block
        (call
          function: (variable
            name: (identifier))
          arguments: (argument_list
            (string))))))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (call
        function: (variable
          table: (identifier)
          field: (identifier))
        arguments: (argument_list
          (expression_list
            (number)
            (number))))))
  (if_statement
    condition: (binary_expression
      left: (variable
        name: (identifier))
      right: (number))
    consequence: (block
      (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (string))))
    alternative: (elseif_clause
      condition: (binary_expression
        left: (variable
          name: (identifier))
        right: (number))
      consequence: (block
        (call
          function: (variable
            name: (identifier))
          arguments: (argument_list
            (string)))))
    alternative: (elseif_clause
      condition: (binary_expression
        left: (variable
          name: (identifier))
        right: (number))
      consequence: (block
        (call
          function: (variable
            name: (identifier))
          arguments: (argument_list
            (string)))))
    alternative: (elseif_clause
      condition: (binary_expression
        left: (variable
          name: (identifier))
        right: (number))
      consequence: (block
        (call
          function: (variable
            name: (identifier))
          arguments: (argument_list
            (string)))))
    alternative: (else_clause
      body: (block
        (call
          function: (variable
            name: (identifier))
          arguments: (argument_list
            (string)))))))

================================================================================
conditional loop structures
================================================================================

while false do end
repeat until true

ten = 10
while ten > 0 do
  ten = ten - 1
end

repeat
  ten = ten + 1
until ten < 10

--------------------------------------------------------------------------------

(chunk
  (while_statement
    condition: (false))
  (repeat_statement
    condition: (true))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (number)))
  (while_statement
    condition: (binary_expression
      left: (variable
        name: (identifier))
      right: (number))
    body: (block
      (variable_assignment
        (variable_list
          (variable
            name: (identifier)))
        (expression_list
          value: (binary_expression
            left: (variable
              name: (identifier))
            right: (number))))))
  (repeat_statement
    body: (block
      (variable_assignment
        (variable_list
          (variable
            name: (identifier)))
        (expression_list
          value: (binary_expression
            left: (variable
              name: (identifier))
            right: (number)))))
    condition: (binary_expression
      left: (variable
        name: (identifier))
      right: (number))))

================================================================================
numeric for loops
================================================================================

for i = 0, 0 do end
for i = 0, 0, 1 do end

zero = 0
for i = zero, 10 do
  zero = i
end

for i = zero, 0, -1 do
  zero = i
end

--------------------------------------------------------------------------------

(chunk
  (for_numeric_statement
    name: (identifier)
    start: (number)
    end: (number))
  (for_numeric_statement
    name: (identifier)
    start: (number)
    end: (number)
    step: (number))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (number)))
  (for_numeric_statement
    name: (identifier)
    start: (variable
      name: (identifier))
    end: (number)
    body: (block
      (variable_assignment
        (variable_list
          (variable
            name: (identifier)))
        (expression_list
          value: (variable
            name: (identifier))))))
  (for_numeric_statement
    name: (identifier)
    start: (variable
      name: (identifier))
    end: (number)
    step: (number)
    body: (block
      (variable_assignment
        (variable_list
          (variable
            name: (identifier)))
        (expression_list
          value: (variable
            name: (identifier)))))))

================================================================================
generic for loops
================================================================================

for i, v in ipairs({}) do end

weathers = {"rain", "sleet", "snow", "freezing fog", "sunny", "cloudy", "ice pellets", "windy"}
for _, weather in ipairs(weathers) do
  print(weather)
end

--------------------------------------------------------------------------------

(chunk
  (for_generic_statement
    left: (variable_list
      name: (identifier)
      name: (identifier))
    right: (expression_list
      value: (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (expression_list
            (table))))))
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (table
        (field_list
          (field
            value: (string))
          (field
            value: (string))
          (field
            value: (string))
          (field
            value: (string))
          (field
            value: (string))
          (field
            value: (string))
          (field
            value: (string))
          (field
            value: (string))))))
  (for_generic_statement
    left: (variable_list
      name: (identifier)
      name: (identifier))
    right: (expression_list
      value: (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (expression_list
            (variable
              name: (identifier))))))
    body: (block
      (call
        function: (variable
          name: (identifier))
        arguments: (argument_list
          (expression_list
            (variable
              name: (identifier))))))))

================================================================================
scope blocks
================================================================================

do end

scope_level = 0
do
  local scope_level = scope_level + 1
  do
    local scope_level = scope_level + 1
  end
end

--------------------------------------------------------------------------------

(chunk
  (do_statement)
  (variable_assignment
    (variable_list
      (variable
        name: (identifier)))
    (expression_list
      value: (number)))
  (do_statement
    body: (block
      (local_variable_declaration
        (variable_list
          (variable
            name: (identifier)))
        (expression_list
          value: (binary_expression
            left: (variable
              name: (identifier))
            right: (number))))
      (do_statement
        body: (block
          (local_variable_declaration
            (variable_list
              (variable
                name: (identifier)))
            (expression_list
              value: (binary_expression
                left: (variable
                  name: (identifier))
                right: (number)))))))))

================================================================================
function definitions (syntactic sugar)
================================================================================

function noop() end

function is_even(x) return x % 2 == 0 end
function sum(a, b) return a + b end

function make_list(...) return {...} end
function apply(func, ...) return func(...) end

function _G.noop() end
function _G._G.noop() end
function _G._G:noop() end

--------------------------------------------------------------------------------

(chunk
  (function_definition_statement
    name: (identifier))
  (function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      name: (identifier))
    body: (block
      (return_statement
        (expression_list
          (binary_expression
            left: (binary_expression
              left: (variable
                name: (identifier))
              right: (number))
            right: (number))))))
  (function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      name: (identifier)
      name: (identifier))
    body: (block
      (return_statement
        (expression_list
          (binary_expression
            left: (variable
              name: (identifier))
            right: (variable
              name: (identifier)))))))
  (function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      (vararg_expression))
    body: (block
      (return_statement
        (expression_list
          (table
            (field_list
              (field
                value: (vararg_expression))))))))
  (function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      name: (identifier)
      (vararg_expression))
    body: (block
      (return_statement
        (expression_list
          (call
            function: (variable
              name: (identifier))
            arguments: (argument_list
              (expression_list
                (vararg_expression))))))))
  (function_definition_statement
    name: (variable
      table: (identifier)
      field: (identifier)))
  (function_definition_statement
    name: (variable
      table: (variable
        table: (identifier)
        field: (identifier))
      field: (identifier)))
  (function_definition_statement
    name: (variable
      table: (variable
        table: (identifier)
        field: (identifier))
      method: (identifier))))

================================================================================
local function definitions (syntactic sugar)
================================================================================

local function _noop() end

local function _is_even(x) return x % 2 == 0 end
local function _sum(a, b) return a + b end

local function _make_list(...) return {...} end
local function _apply(func, ...) return func(...) end

--------------------------------------------------------------------------------

(chunk
  (local_function_definition_statement
    name: (identifier))
  (local_function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      name: (identifier))
    body: (block
      (return_statement
        (expression_list
          (binary_expression
            left: (binary_expression
              left: (variable
                name: (identifier))
              right: (number))
            right: (number))))))
  (local_function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      name: (identifier)
      name: (identifier))
    body: (block
      (return_statement
        (expression_list
          (binary_expression
            left: (variable
              name: (identifier))
            right: (variable
              name: (identifier)))))))
  (local_function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      (vararg_expression))
    body: (block
      (return_statement
        (expression_list
          (table
            (field_list
              (field
                value: (vararg_expression))))))))
  (local_function_definition_statement
    name: (identifier)
    parameters: (parameter_list
      name: (identifier)
      (vararg_expression))
    body: (block
      (return_statement
        (expression_list
          (call
            function: (variable
              name: (identifier))
            arguments: (argument_list
              (expression_list
                (vararg_expression)))))))))
