===
Addition
===

a + b

---

source_file
  statement:
    additive_expression
      lhs: simple_identifier "a"
      op: +
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "+"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Subtraction
===

a - b

---

source_file
  statement:
    additive_expression
      lhs: simple_identifier "a"
      op: -
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "-"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Multiplication
===

a * b

---

source_file
  statement:
    multiplicative_expression
      lhs: simple_identifier "a"
      op: *
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "*"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Division
===

a / b

---

source_file
  statement:
    multiplicative_expression
      lhs: simple_identifier "a"
      op: /
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "/"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Operator precedence: addition and multiplication
===

a + b * c

---

source_file
  statement:
    additive_expression
      lhs: simple_identifier "a"
      op: +
      rhs:
        multiplicative_expression
          lhs: simple_identifier "b"
          op: *
          rhs: simple_identifier "c"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "+"
          left:
            name_expr
              identifier: identifier "a"
          right:
            binary_expr
              operator: infix_operator "*"
              left:
                name_expr
                  identifier: identifier "b"
              right:
                name_expr
                  identifier: identifier "c"

===
Parenthesised expression
===

(a + b) * c

---

source_file
  statement:
    multiplicative_expression
      lhs:
        tuple_expression
          element:
            tuple_expression_item
              value:
                additive_expression
                  lhs: simple_identifier "a"
                  op: +
                  rhs: simple_identifier "b"
      op: *
      rhs: simple_identifier "c"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "*"
          left: tuple_expr "(a + b)"
          right:
            name_expr
              identifier: identifier "c"

===
Comparison
===

a < b

---

source_file
  statement:
    comparison_expression
      lhs: simple_identifier "a"
      op: <
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "<"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Equality
===

a == b

---

source_file
  statement:
    equality_expression
      lhs: simple_identifier "a"
      op: ==
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "=="
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Logical and
===

a && b

---

source_file
  statement:
    conjunction_expression
      lhs: simple_identifier "a"
      op: &&
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "&&"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Logical or
===

a || b

---

source_file
  statement:
    disjunction_expression
      lhs: simple_identifier "a"
      op: ||
      rhs: simple_identifier "b"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "||"
          left:
            name_expr
              identifier: identifier "a"
          right:
            name_expr
              identifier: identifier "b"

===
Logical not
===

!a

---

source_file
  statement:
    prefix_expression
      operation: bang "!"
      target: simple_identifier "a"

---

top_level
  body:
    block
      stmt:
        unary_expr
          operand:
            name_expr
              identifier: identifier "a"
          operator: prefix_operator "!"

===
Range operator
===

1...10

---

source_file
  statement:
    range_expression
      end: integer_literal "10"
      op: ...
      start: integer_literal "1"

---

top_level
  body:
    block
      stmt:
        binary_expr
          operator: infix_operator "..."
          left: int_literal "1"
          right: int_literal "10"
