==============================
Value specification
==============================

val x : t

---

(compilation_unit
  (value_specification
    (value_name)
    (type_constructor_path (type_constructor))))

==============================
Value definition
==============================

let x = y
let ( + ) = x
let rec x = y and y = x
let x, y = y, x
let x : 'a . 'a t = y
let f ~x ~l:y ~(x : t) ?(l = y) ?l:((x, y) : t = xy) = x
let f (type t) x : t = x
let+ x = a and+ y = b

---

(compilation_unit
  (value_definition
    (let_binding (value_name) (value_path (value_name))))
  (value_definition
    (let_binding
      (value_name (infix_operator))
      (value_path (value_name))))
  (value_definition
    (let_binding (value_name) (value_path (value_name)))
    (let_binding (value_name) (value_path (value_name))))
  (value_definition
    (let_binding
      (tuple_pattern (value_name) (value_name))
      (product_expression (value_path (value_name)) (value_path (value_name)))))
  (value_definition
    (let_binding
      (value_name)
      (polymorphic_type
        (type_variable)
        (constructed_type (type_variable) (type_constructor_path (type_constructor))))
      (value_path (value_name))))
  (value_definition
    (let_binding
      (value_name)
      (parameter (label (label_name)))
      (parameter (label (label_name)) (value_name))
      (parameter (label_name) (type_constructor_path (type_constructor)))
      (parameter (label_name) (value_path (value_name)))
      (parameter
        (label (label_name))
        (parenthesized_pattern
          (tuple_pattern (value_name) (value_name)))
        (type_constructor_path (type_constructor))
        (value_path (value_name)))
      (value_path (value_name))))
  (value_definition
    (let_binding
      (value_name)
      (abstract_type (type_constructor))
      (parameter (value_name))
      (type_constructor_path (type_constructor))
      (value_path (value_name))))
  (value_definition
    (let_operator)
    (let_binding (value_name) (value_path (value_name)))
    (and_operator)
    (let_binding (value_name) (value_path (value_name)))))

==============================
External
==============================

external x : int = "x"

---

(compilation_unit
  (external
    (value_name)
    (type_constructor_path (type_constructor))
    (string)))

==============================
Type definition
==============================

type t
type nonrec 'a t = t and ('a, 'b) t = t
type t = private t
type t = A | B of t | C of t * t | D of {x : t}
type _ t =
  | A : 'a -> 'a t
type t = {
  mutable x : t;
}
type t = t constraint 'a = t
type t = |

---

(compilation_unit
  (type_definition (type_binding (type_constructor)))
  (type_definition
    (type_binding
      (type_variable)
      (type_constructor)
      (type_constructor_path (type_constructor)))
    (type_binding
      (type_variable) (type_variable)
      (type_constructor)
      (type_constructor_path (type_constructor))))
  (type_definition (type_binding (type_constructor) (type_constructor_path (type_constructor))))
  (type_definition
    (type_binding
      (type_constructor)
      (variant_declaration
        (constructor_declaration (constructor_name))
        (constructor_declaration
          (constructor_name)
          (type_constructor_path (type_constructor)))
        (constructor_declaration
          (constructor_name)
          (type_constructor_path (type_constructor))
          (type_constructor_path (type_constructor)))
        (constructor_declaration
          (constructor_name)
          (record_declaration
            (field_declaration
              (field_name)
              (type_constructor_path (type_constructor))))))))
  (type_definition
    (type_binding
      (type_variable)
      (type_constructor)
      (variant_declaration
        (constructor_declaration
          (constructor_name)
          (type_variable)
          (constructed_type (type_variable) (type_constructor_path (type_constructor)))))))
  (type_definition
    (type_binding
      (type_constructor)
      (record_declaration
        (field_declaration (field_name) (type_constructor_path (type_constructor))))))
  (type_definition
    (type_binding
      (type_constructor)
      (type_constructor_path (type_constructor))
      (type_constraint (type_variable) (type_constructor_path (type_constructor)))))
  (type_definition
    (type_binding
      (type_constructor)
      (variant_declaration))))

==============================
Exception definition
==============================

exception E
exception E of t

---

(compilation_unit
  (exception_definition (constructor_declaration (constructor_name)))
  (exception_definition
    (constructor_declaration
      (constructor_name)
      (type_constructor_path (type_constructor)))))

==============================
Module definition
==============================

module M
module M : T
module M (M : T) : E
module rec M : T and M : T

module M = M
module M : T = M
module M (M : T) = M
module rec M = N and N = M

module _ (_ : T) = M

---

(compilation_unit
  (module_definition
    (module_binding
      (module_name)))
  (module_definition
    (module_binding
      (module_name)
      (module_type_path (module_type_name))))
  (module_definition
    (module_binding
      (module_name)
      (module_parameter (module_name) (module_type_path (module_type_name)))
      (module_type_path (module_type_name))))
  (module_definition
    (module_binding
      (module_name)
      (module_type_path (module_type_name)))
    (module_binding
      (module_name)
      (module_type_path (module_type_name))))

  (module_definition
    (module_binding
      (module_name)
      (module_name)))
  (module_definition
    (module_binding
      (module_name)
      (module_type_path (module_type_name))
      (module_name)))
  (module_definition
    (module_binding
      (module_name)
      (module_parameter (module_name) (module_type_path (module_type_name)))
      (module_name)))
  (module_definition
    (module_binding
      (module_name)
      (module_name))
    (module_binding
      (module_name)
      (module_name)))
  (module_definition
    (module_binding
      (module_name)
      (module_parameter (module_name) (module_type_path (module_type_name)))
      (module_name))))

==============================
Module type definition
==============================

module type T = T

---

(compilation_unit
  (module_type_definition
    (module_type_name)
    (module_type_path (module_type_name))))

==============================
Open and include directives
==============================

open M
open! M
open ! M
include M
include t
include M.M
include M.t
include M.M.M
include M.M.t
include M(M)
include M(M).M
include M(M).t
include M(M(M)).M(M)
include M(M(M)).M(M).M
include M(M(M)).M(M).t

---

(compilation_unit
  (open_statement (module_name))
  (open_statement (module_name))
  (open_statement (module_name))
  (include_statement (module_type_path (module_type_name)))
  (include_statement (module_type_path (module_type_name)))
  (include_statement (module_type_path (module_name) (module_type_path (module_type_name))))
  (include_statement (module_type_path (module_name) (module_type_path (module_type_name))))
  (include_statement
    (module_type_path
      (module_name)
      (module_type_path (module_name) (module_type_path (module_type_name)))))
  (include_statement
    (module_type_path
      (module_name)
      (module_type_path (module_name) (module_type_path (module_type_name)))))
  (include_statement (module_application (module_name) (module_name)))
  (include_statement
    (module_type_path
      (module_name)
      (module_path (module_name)) (module_type_path (module_type_name))))
  (include_statement
    (module_type_path
      (module_name)
      (module_path (module_name)) (module_type_path (module_type_name))))
  (include_statement
    (submodule
      (module_application
        (module_name)
        (module_application (module_name) (module_name)))
      (module_application (module_name) (module_name))))
  (include_statement
    (module_type_path
      (module_name)
      (module_path (module_name) (module_path (module_name)))
      (module_type_path
        (module_name)
        (module_path (module_name))
        (module_type_path (module_type_name)))))
  (include_statement
    (module_type_path
      (module_name)
      (module_path (module_name) (module_path (module_name)))
      (module_type_path
        (module_name)
        (module_path (module_name))
        (module_type_path (module_type_name))))))
