============================================
Function calls
============================================

int main() {
  printf("hi! %d\n", x);
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (function_call (identifier) (string) (identifier)))))

============================================
Character literals
============================================

int main() {
  'a';
  '\0';
  '\t';
  '\'';
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (char))
    (expression_statement (char))
    (expression_statement (char))
    (expression_statement (char))))

============================================
Field access
============================================

int main() {
  s.data1;
  p->data2;
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (field_access (identifier) (identifier)))
    (expression_statement (deref_field_access (identifier) (identifier)))))

============================================
Boolean operators
============================================

int main() {
  !x || !y && !z;
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (bool_op
      (bool_op (identifier))
      (bool_op (bool_op (identifier)) (bool_op (identifier)))))))

============================================
Math operators
============================================

int main() {
  -a / b + c * -d;
  a++ - ++b + c-- + --d;
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (math_op
      (math_op
        (math_op (identifier))
        (identifier))
      (math_op
        (identifier)
        (math_op (identifier)))))
    (expression_statement
      (math_op
        (math_op (identifier))
        (math_op
          (math_op (identifier))
          (math_op
            (math_op (identifier))
            (math_op (identifier))))))))

============================================
Assignments
============================================

int main() {
  static int a = 1;
  b = *c = 2;
  d.e = 3;
  f->g = 4;
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (var_declaration (identifier) (var_assignment (identifier) (number)))
    (expression_statement (assignment (identifier) (assignment (deref (identifier)) (number))))
    (expression_statement (assignment (field_access (identifier) (identifier)) (number)))
    (expression_statement (assignment (deref_field_access (identifier) (identifier)) (number)))))

============================================
Pointer operations
============================================

int main() {
  doSomething(&x, *x);
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (function_call (identifier)
      (address_of (identifier))
      (deref (identifier))))))

============================================
Compound literals
============================================

int main() {
  x = (SomeType) { .field1 = 5, .field2 = 6 };
  y = (struct SomeStruct) { 7, 8 };
}

---

(function_declaration (identifier) (identifier) (formal_parameters)
  (statement_block
    (expression_statement (assignment
      (identifier)
      (compound_literal (identifier)
        (struct_literal_field (identifier) (number))
        (struct_literal_field (identifier) (number)))))
    (expression_statement (assignment
      (identifier)
      (compound_literal (struct_type (identifier))
        (number)
        (number))))))
