===
If statement
===

if x > 0 {
  print(x)
}

---

source_file
  statement:
    if_statement
      body:
        block
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: simple_identifier "x"
      condition:
        if_condition
          kind:
            comparison_expression
              lhs: simple_identifier "x"
              op: >
              rhs: integer_literal "0"

---

top_level
  body:
    block
      stmt:
        if_expr
          condition:
            binary_expr
              operator: infix_operator ">"
              left:
                name_expr
                  identifier: identifier "x"
              right: int_literal "0"
          then:
            block
              stmt:
                call_expr
                  argument:
                    argument
                      value:
                        name_expr
                          identifier: identifier "x"
                  callee:
                    name_expr
                      identifier: identifier "print"

===
If-else
===

if x > 0 {
  print(x)
} else {
  print(-x)
}

---

source_file
  statement:
    if_statement
      body:
        block
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: simple_identifier "x"
      condition:
        if_condition
          kind:
            comparison_expression
              lhs: simple_identifier "x"
              op: >
              rhs: integer_literal "0"
      else_branch:
        block
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value:
                            prefix_expression
                              operation: -
                              target: simple_identifier "x"

---

top_level
  body:
    block
      stmt:
        if_expr
          condition:
            binary_expr
              operator: infix_operator ">"
              left:
                name_expr
                  identifier: identifier "x"
              right: int_literal "0"
          else:
            block
              stmt:
                call_expr
                  argument:
                    argument
                      value:
                        unary_expr
                          operand:
                            name_expr
                              identifier: identifier "x"
                          operator: prefix_operator "-"
                  callee:
                    name_expr
                      identifier: identifier "print"
          then:
            block
              stmt:
                call_expr
                  argument:
                    argument
                      value:
                        name_expr
                          identifier: identifier "x"
                  callee:
                    name_expr
                      identifier: identifier "print"

===
If-else-if chain
===

if x > 0 {
  print(1)
} else if x < 0 {
  print(2)
} else {
  print(3)
}

---

source_file
  statement:
    if_statement
      body:
        block
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: integer_literal "1"
      condition:
        if_condition
          kind:
            comparison_expression
              lhs: simple_identifier "x"
              op: >
              rhs: integer_literal "0"
      else_branch:
        if_statement
          body:
            block
              statement:
                call_expression
                  function: simple_identifier "print"
                  suffix:
                    call_suffix
                      arguments:
                        value_arguments
                          argument:
                            value_argument
                              value: integer_literal "2"
          condition:
            if_condition
              kind:
                comparison_expression
                  lhs: simple_identifier "x"
                  op: <
                  rhs: integer_literal "0"
          else_branch:
            block
              statement:
                call_expression
                  function: simple_identifier "print"
                  suffix:
                    call_suffix
                      arguments:
                        value_arguments
                          argument:
                            value_argument
                              value: integer_literal "3"

---

top_level
  body:
    block
      stmt:
        if_expr
          condition:
            binary_expr
              operator: infix_operator ">"
              left:
                name_expr
                  identifier: identifier "x"
              right: int_literal "0"
          else:
            if_expr
              condition:
                binary_expr
                  operator: infix_operator "<"
                  left:
                    name_expr
                      identifier: identifier "x"
                  right: int_literal "0"
              else:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value: int_literal "3"
                      callee:
                        name_expr
                          identifier: identifier "print"
              then:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value: int_literal "2"
                      callee:
                        name_expr
                          identifier: identifier "print"
          then:
            block
              stmt:
                call_expr
                  argument:
                    argument
                      value: int_literal "1"
                  callee:
                    name_expr
                      identifier: identifier "print"

===
If-let optional binding
===

if let value = optional {
  print(value)
}

---

source_file
  statement:
    if_statement
      body:
        block
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: simple_identifier "value"
      condition:
        if_condition
          kind:
            if_let_binding
              pattern:
                pattern
                  binding:
                    value_binding_pattern
                      mutability: let
                  bound_identifier: simple_identifier "value"
              value: simple_identifier "optional"

---

top_level
  body:
    block
      stmt:
        if_expr
          condition:
            pattern_guard_expr
              pattern:
                constructor_pattern
                  element:
                    pattern_element
                      pattern:
                        name_pattern
                          identifier: identifier "value"
                  constructor:
                    member_access_expr
                      base:
                        named_type_expr
                          name: identifier "Optional"
                      member: identifier "some"
              value:
                name_expr
                  identifier: identifier "optional"
          then:
            block
              stmt:
                call_expr
                  argument:
                    argument
                      value:
                        name_expr
                          identifier: identifier "value"
                  callee:
                    name_expr
                      identifier: identifier "print"

===
Guard let
===

guard let value = optional else { return }

---

source_file
  statement:
    guard_statement
      body:
        block
          statement:
            control_transfer_statement
              kind: return
      condition:
        if_condition
          kind:
            if_let_binding
              pattern:
                pattern
                  binding:
                    value_binding_pattern
                      mutability: let
                  bound_identifier: simple_identifier "value"
              value: simple_identifier "optional"

---

top_level
  body:
    block
      stmt:
        guard_if_stmt
          condition:
            pattern_guard_expr
              pattern:
                constructor_pattern
                  element:
                    pattern_element
                      pattern:
                        name_pattern
                          identifier: identifier "value"
                  constructor:
                    member_access_expr
                      base:
                        named_type_expr
                          name: identifier "Optional"
                      member: identifier "some"
              value:
                name_expr
                  identifier: identifier "optional"
          else:
            block
              stmt: return_expr "return"

===
Ternary expression
===

let y = x > 0 ? 1 : -1

---

source_file
  statement:
    property_declaration
      binding:
        value_binding_pattern
          mutability: let
      declarator:
        property_binding
          name:
            pattern
              bound_identifier: simple_identifier "y"
          value:
            ternary_expression
              condition:
                comparison_expression
                  lhs: simple_identifier "x"
                  op: >
                  rhs: integer_literal "0"
              if_false:
                prefix_expression
                  operation: -
                  target: integer_literal "1"
              if_true: integer_literal "1"

---

top_level
  body:
    block
      stmt:
        variable_declaration
          modifier: modifier "let"
          pattern:
            name_pattern
              identifier: identifier "y"
          value:
            if_expr
              condition:
                binary_expr
                  operator: infix_operator ">"
                  left:
                    name_expr
                      identifier: identifier "x"
                  right: int_literal "0"
              else:
                unary_expr
                  operand: int_literal "1"
                  operator: prefix_operator "-"
              then: int_literal "1"

===
Switch statement
===

switch x {
case 1:
  print("one")
case 2, 3:
  print("two or three")
default:
  print("other")
}

---

source_file
  statement:
    switch_statement
      entry:
        switch_entry
          pattern:
            switch_pattern
              pattern:
                pattern
                  kind: integer_literal "1"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value:
                            line_string_literal
                              text: line_str_text "one"
        switch_entry
          pattern:
            switch_pattern
              pattern:
                pattern
                  kind: integer_literal "2"
            switch_pattern
              pattern:
                pattern
                  kind: integer_literal "3"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value:
                            line_string_literal
                              text: line_str_text "two or three"
        switch_entry
          default: default_keyword "default"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value:
                            line_string_literal
                              text: line_str_text "other"
      expr: simple_identifier "x"

---

top_level
  body:
    block
      stmt:
        switch_expr
          case:
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value: string_literal "\"one\""
                      callee:
                        name_expr
                          identifier: identifier "print"
              pattern:
                expr_equality_pattern
                  expr: int_literal "1"
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value: string_literal "\"two or three\""
                      callee:
                        name_expr
                          identifier: identifier "print"
              pattern:
                expr_equality_pattern
                  expr: int_literal "2"
                expr_equality_pattern
                  expr: int_literal "3"
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value: string_literal "\"other\""
                      callee:
                        name_expr
                          identifier: identifier "print"
          value:
            name_expr
              identifier: identifier "x"

===
Switch with binding pattern
===

switch shape {
case .circle(let r):
  print(r)
case .square(let s):
  print(s)
}

---

source_file
  statement:
    switch_statement
      entry:
        switch_entry
          pattern:
            switch_pattern
              pattern:
                pattern
                  kind:
                    case_pattern
                      arguments:
                        tuple_pattern
                          item:
                            tuple_pattern_item
                              pattern:
                                pattern
                                  kind:
                                    binding_pattern
                                      binding:
                                        value_binding_pattern
                                          mutability: let
                                      pattern:
                                        pattern
                                          bound_identifier: simple_identifier "r"
                      dot: .
                      name: simple_identifier "circle"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: simple_identifier "r"
        switch_entry
          pattern:
            switch_pattern
              pattern:
                pattern
                  kind:
                    case_pattern
                      arguments:
                        tuple_pattern
                          item:
                            tuple_pattern_item
                              pattern:
                                pattern
                                  kind:
                                    binding_pattern
                                      binding:
                                        value_binding_pattern
                                          mutability: let
                                      pattern:
                                        pattern
                                          bound_identifier: simple_identifier "s"
                      dot: .
                      name: simple_identifier "square"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: simple_identifier "s"
      expr: simple_identifier "shape"

---

top_level
  body:
    block
      stmt:
        switch_expr
          case:
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value:
                            name_expr
                              identifier: identifier "r"
                      callee:
                        name_expr
                          identifier: identifier "print"
              pattern:
                constructor_pattern
                  element:
                    pattern_element
                      pattern:
                        name_pattern
                          identifier: identifier "r"
                  constructor:
                    member_access_expr
                      base: inferred_type_expr "."
                      member: identifier "circle"
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value:
                            name_expr
                              identifier: identifier "s"
                      callee:
                        name_expr
                          identifier: identifier "print"
              pattern:
                constructor_pattern
                  element:
                    pattern_element
                      pattern:
                        name_pattern
                          identifier: identifier "s"
                  constructor:
                    member_access_expr
                      base: inferred_type_expr "."
                      member: identifier "square"
          value:
            name_expr
              identifier: identifier "shape"

===
Switch with labeled case pattern arguments
===

switch x {
case .implicit(isAcknowledged: false):
  print("yes")
case .thread(threadRowId: _, let rowId):
  print(rowId)
}

---

source_file
  statement:
    switch_statement
      entry:
        switch_entry
          pattern:
            switch_pattern
              pattern:
                pattern
                  kind:
                    case_pattern
                      arguments:
                        tuple_pattern
                          item:
                            tuple_pattern_item
                              name: simple_identifier "isAcknowledged"
                              pattern:
                                pattern
                                  kind:
                                    boolean_literal
                      dot: .
                      name: simple_identifier "implicit"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value:
                            line_string_literal
                              text: line_str_text "yes"
        switch_entry
          pattern:
            switch_pattern
              pattern:
                pattern
                  kind:
                    case_pattern
                      arguments:
                        tuple_pattern
                          item:
                            tuple_pattern_item
                              name: simple_identifier "threadRowId"
                              pattern:
                                pattern
                                  kind: wildcard_pattern "_"
                            tuple_pattern_item
                              pattern:
                                pattern
                                  kind:
                                    binding_pattern
                                      binding:
                                        value_binding_pattern
                                          mutability: let
                                      pattern:
                                        pattern
                                          bound_identifier: simple_identifier "rowId"
                      dot: .
                      name: simple_identifier "thread"
          statement:
            call_expression
              function: simple_identifier "print"
              suffix:
                call_suffix
                  arguments:
                    value_arguments
                      argument:
                        value_argument
                          value: simple_identifier "rowId"
      expr: simple_identifier "x"

---

top_level
  body:
    block
      stmt:
        switch_expr
          case:
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value: string_literal "\"yes\""
                      callee:
                        name_expr
                          identifier: identifier "print"
              pattern:
                constructor_pattern
                  element:
                    pattern_element
                      key: identifier "isAcknowledged"
                      pattern:
                        expr_equality_pattern
                          expr: boolean_literal "false"
                  constructor:
                    member_access_expr
                      base: inferred_type_expr "."
                      member: identifier "implicit"
            switch_case
              body:
                block
                  stmt:
                    call_expr
                      argument:
                        argument
                          value:
                            name_expr
                              identifier: identifier "rowId"
                      callee:
                        name_expr
                          identifier: identifier "print"
              pattern:
                constructor_pattern
                  element:
                    pattern_element
                      key: identifier "threadRowId"
                      pattern: ignore_pattern "_"
                    pattern_element
                      pattern:
                        name_pattern
                          identifier: identifier "rowId"
                  constructor:
                    member_access_expr
                      base: inferred_type_expr "."
                      member: identifier "thread"
          value:
            name_expr
              identifier: identifier "x"
