================================================================================
Declaration statements
================================================================================

package main

func main() {
  var x = y
  const x = 5
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (var_declaration
          (var_spec
            (identifier)
            (expression_list
              (identifier))))
        (const_declaration
          (const_spec
            (identifier)
            (expression_list
              (int_literal))))))))

================================================================================
Expression statements
================================================================================

package main

func main() {
  foo(5)
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (expression_statement
          (call_expression
            (identifier)
            (argument_list
              (int_literal))))))))

================================================================================
Send statements
================================================================================

package main

func main() {
  foo <- 5
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (send_statement
          (identifier)
          (int_literal))))))

================================================================================
Increment/Decrement statements
================================================================================

package main

func main() {
  i++
  j--
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (inc_statement
          (identifier))
        (dec_statement
          (identifier))))))

================================================================================
Assignment statements
================================================================================

package main

func main() {
  a = 1
  b, c += 2, 3
  d *= 3
  e += 1
  f /= 2
  g <<= 1
  h >>= 1
  i %= 1
  j &= 2
  k &^= 3
  l -= 1
  m |= 2
  n ^= 2
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier)
            (identifier))
          (expression_list
            (int_literal)
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))
        (assignment_statement
          (expression_list
            (identifier))
          (expression_list
            (int_literal)))))))

================================================================================
Short var declarations
================================================================================

package main

func main() {
  a, b := 1, 2
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (short_var_declaration
          (expression_list
            (identifier)
            (identifier))
          (expression_list
            (int_literal)
            (int_literal)))))))

================================================================================
If statements
================================================================================

package main

func main() {
  if a {
    b()
  }

  if a := b(); c {
    d()
  }

  if a {
    b()
  } else {
    c()
  }

  if b {
    c()
  } else if d {
    e()
  } else {
    f()
  }
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    name: (identifier)
    parameters: (parameter_list)
    body: (block
      (statement_list
        (if_statement
          condition: (identifier)
          consequence: (block
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list))))))
        (if_statement
          initializer: (short_var_declaration
            left: (expression_list
              (identifier))
            right: (expression_list
              (call_expression
                function: (identifier)
                arguments: (argument_list))))
          condition: (identifier)
          consequence: (block
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list))))))
        (if_statement
          condition: (identifier)
          consequence: (block
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list)))))
          alternative: (block
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list))))))
        (if_statement
          condition: (identifier)
          consequence: (block
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list)))))
          alternative: (if_statement
            condition: (identifier)
            consequence: (block
              (statement_list
                (expression_statement
                  (call_expression
                    function: (identifier)
                    arguments: (argument_list)))))
            alternative: (block
              (statement_list
                (expression_statement
                  (call_expression
                    function: (identifier)
                    arguments: (argument_list)))))))))))

================================================================================
For statements
================================================================================

package main

func main() {
  for {
    a()
    goto loop
  }

  loop: for i := 0; i < 5; i++ {
    a()
    break loop
  }

loop2:
  for ; i < 10; i++ {
    a()
    continue loop2
  }

  for ;; {
    a()
    continue
  }

  for x := range y {
    a(x)
    break
  }
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (for_statement
          (block
            (statement_list
              (expression_statement
                (call_expression
                  (identifier)
                  (argument_list)))
              (goto_statement
                (label_name)))))
        (labeled_statement
          (label_name)
          (for_statement
            (for_clause
              (short_var_declaration
                (expression_list
                  (identifier))
                (expression_list
                  (int_literal)))
              (binary_expression
                (identifier)
                (int_literal))
              (inc_statement
                (identifier)))
            (block
              (statement_list
                (expression_statement
                  (call_expression
                    (identifier)
                    (argument_list)))
                (break_statement
                  (label_name))))))
        (labeled_statement
          (label_name)
          (for_statement
            (for_clause
              (binary_expression
                (identifier)
                (int_literal))
              (inc_statement
                (identifier)))
            (block
              (statement_list
                (expression_statement
                  (call_expression
                    (identifier)
                    (argument_list)))
                (continue_statement
                  (label_name))))))
        (for_statement
          (for_clause)
          (block
            (statement_list
              (expression_statement
                (call_expression
                  (identifier)
                  (argument_list)))
              (continue_statement))))
        (for_statement
          (range_clause
            (expression_list
              (identifier))
            (identifier))
          (block
            (statement_list
              (expression_statement
                (call_expression
                  (identifier)
                  (argument_list
                    (identifier))))
              (break_statement))))))))

================================================================================
Switch statements
================================================================================

func main() {
  switch e {
    case 1, 2:
      a()
      fallthrough
    case 3:
      d()
    default:
      c()
      break
  }

  switch {
    case true:
      return
  }

  switch f := y(); f {
  }
}

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

(source_file
  (function_declaration
    name: (identifier)
    parameters: (parameter_list)
    body: (block
      (statement_list
        (expression_switch_statement
          value: (identifier)
          (expression_case
            value: (expression_list
              (int_literal)
              (int_literal))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list)))
              (fallthrough_statement)))
          (expression_case
            value: (expression_list
              (int_literal))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list)))))
          (default_case
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list)))
              (break_statement))))
        (expression_switch_statement
          (expression_case
            value: (expression_list
              (true))
            (statement_list
              (return_statement))))
        (expression_switch_statement
          initializer: (short_var_declaration
            left: (expression_list
              (identifier))
            right: (expression_list
              (call_expression
                function: (identifier)
                arguments: (argument_list))))
          value: (identifier))))))

================================================================================
Type switch statements
================================================================================

func main() {
  switch e.(type) {
    case []Person:
      a()
    case *Dog:
      break
  }
  switch i := x.(type) {
    case nil:
    	printString("x is nil")
    case int:
    	printInt(i)
    case float64:
    	printFloat64(i)
    case func(int) float64:
    	printFunction(i)
    case bool, string:
    	printString("type is bool or string")
    default:
    	printString("don't know the type")
  }
}

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

(source_file
  (function_declaration
    name: (identifier)
    parameters: (parameter_list)
    body: (block
      (statement_list
        (type_switch_statement
          value: (identifier)
          (type_case
            type: (slice_type
              element: (type_identifier))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list)))))
          (type_case
            type: (pointer_type
              (type_identifier))
            (statement_list
              (break_statement))))
        (type_switch_statement
          alias: (expression_list
            (identifier))
          value: (identifier)
          (type_case
            type: (type_identifier)
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (interpreted_string_literal
                      (interpreted_string_literal_content)))))))
          (type_case
            type: (type_identifier)
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (identifier))))))
          (type_case
            type: (type_identifier)
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (identifier))))))
          (type_case
            type: (function_type
              parameters: (parameter_list
                (parameter_declaration
                  type: (type_identifier)))
              result: (type_identifier))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (identifier))))))
          (type_case
            type: (type_identifier)
            type: (type_identifier)
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (interpreted_string_literal
                      (interpreted_string_literal_content)))))))
          (default_case
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (interpreted_string_literal
                      (interpreted_string_literal_content))))))))))))

================================================================================
Select statements
================================================================================

package main

func main() {
  select {
    case x := <-c:
      println(x)
    case y <- c:
      println(5)
    case <-time.After(1):
      println(6)
    default:
      return
  }
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    name: (identifier)
    parameters: (parameter_list)
    body: (block
      (statement_list
        (select_statement
          (communication_case
            communication: (receive_statement
              left: (expression_list
                (identifier))
              right: (unary_expression
                operand: (identifier)))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (identifier))))))
          (communication_case
            communication: (send_statement
              channel: (identifier)
              value: (identifier))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (int_literal))))))
          (communication_case
            communication: (receive_statement
              right: (unary_expression
                operand: (call_expression
                  function: (selector_expression
                    operand: (identifier)
                    field: (field_identifier))
                  arguments: (argument_list
                    (int_literal)))))
            (statement_list
              (expression_statement
                (call_expression
                  function: (identifier)
                  arguments: (argument_list
                    (int_literal))))))
          (default_case
            (statement_list
              (return_statement))))))))

================================================================================
Go and defer statements
================================================================================

package main

func main() {
  defer x.y()
  go x.y()
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (defer_statement
          (call_expression
            (selector_expression
              (identifier)
              (field_identifier))
            (argument_list)))
        (go_statement
          (call_expression
            (selector_expression
              (identifier)
              (field_identifier))
            (argument_list)))))))

================================================================================
Nested statement blocks
================================================================================

func main() {
  {
    println("hi")
  }
  {
    println("bye")
  }
}

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

(source_file
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (block
          (statement_list
            (expression_statement
              (call_expression
                (identifier)
                (argument_list
                  (interpreted_string_literal
                    (interpreted_string_literal_content)))))))
        (block
          (statement_list
            (expression_statement
              (call_expression
                (identifier)
                (argument_list
                  (interpreted_string_literal
                    (interpreted_string_literal_content)))))))))))

================================================================================
Labels at the ends of statement blocks
================================================================================

func main() {
  {
  end_of_block:
  }
}

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

(source_file
  (function_declaration
    name: (identifier)
    parameters: (parameter_list)
    body: (block
      (statement_list
        (block
          (statement_list
            (labeled_statement
              label: (label_name))))))))

================================================================================
Empty statements
================================================================================

package main

func main() {
	;
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (empty_statement)))))

================================================================================
Nested control statements
================================================================================

package main

func main() {
  for i, v := range vectors {
    func() {
      if v == v {
        fmt.Println("something: %v", vectors[i])
      }
    }()
  }
}

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

(source_file
  (package_clause
    (package_identifier))
  (function_declaration
    (identifier)
    (parameter_list)
    (block
      (statement_list
        (for_statement
          (range_clause
            (expression_list
              (identifier)
              (identifier))
            (identifier))
          (block
            (statement_list
              (expression_statement
                (call_expression
                  (func_literal
                    (parameter_list)
                    (block
                      (statement_list
                        (if_statement
                          (binary_expression
                            (identifier)
                            (identifier))
                          (block
                            (statement_list
                              (expression_statement
                                (call_expression
                                  (selector_expression
                                    (identifier)
                                    (field_identifier))
                                  (argument_list
                                    (interpreted_string_literal
                                      (interpreted_string_literal_content))
                                    (index_expression
                                      (identifier)
                                      (identifier)))))))))))
                  (argument_list))))))))))

================================================================================
Top-level statements
================================================================================

foo(5)
x := T { a: b }

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

(source_file
  (expression_statement
    (call_expression
      (identifier)
      (argument_list
        (int_literal))))
  (short_var_declaration
    (expression_list
      (identifier))
    (expression_list
      (composite_literal
        (type_identifier)
        (literal_value
          (keyed_element
            (literal_element
              (identifier))
            (literal_element
              (identifier))))))))
