===========================
Values
===========================

x;;
\#let;;
M.x;;
M.\#in;;
( + );;
M.( + );;

---

(compilation_unit
  (expression_item
    (value_path
      (value_name)))
  (expression_item
    (value_path
      (value_name)))
  (expression_item
    (value_path
      (module_path
        (module_name))
      (value_name)))
  (expression_item
    (value_path
      (module_path
        (module_name))
      (value_name)))
  (expression_item
    (value_path
      (parenthesized_operator
        (add_operator))))
  (expression_item
    (value_path
      (module_path
        (module_name))
      (parenthesized_operator
        (add_operator)))))

===========================
Constants
===========================

493;;
10_000_000;;
0x1ed;;
0o644;;
0b111101101;;
4.93e2;;
493e+0;;
0x7b.4p2;;
'x';;
'\n';;
'\'';;
'\120';;
'\x78';;
'\o170';;
'
';;
"OCaml";;
"\"\079\u{43}aml\"";;
"OCaml\
 OCaml";;
"%d %05.2f";;
"@[%s@ %d@]@.";;
"
";;
" ";;
"";;
{|OCaml|};;
{id||id};;
{id|{|}id}|idd||id};;
{|%d@.|};;
{|
|};;
{| |};;
{xxxxxxxxxxxxxxxxxxxx||xxxxxxxxxxxxxxxxxxxx};;
{à||à};;
true;;
();;

---

(compilation_unit
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (number))
  (expression_item
    (character
      (character_content)))
  (expression_item
    (character
      (character_content
        (escape_sequence))))
  (expression_item
    (character
      (character_content
        (escape_sequence))))
  (expression_item
    (character
      (character_content
        (escape_sequence))))
  (expression_item
    (character
      (character_content
        (escape_sequence))))
  (expression_item
    (character
      (character_content
        (escape_sequence))))
  (expression_item
    (character
      (character_content)))
  (expression_item
    (string
      (string_content)))
  (expression_item
    (string
      (string_content
        (escape_sequence)
        (escape_sequence)
        (escape_sequence)
        (escape_sequence))))
  (expression_item
    (string
      (string_content
        (escape_sequence))))
  (expression_item
    (string
      (string_content
        (conversion_specification)
        (conversion_specification))))
  (expression_item
    (string
      (string_content
        (pretty_printing_indication)
        (conversion_specification)
        (pretty_printing_indication)
        (conversion_specification)
        (pretty_printing_indication)
        (pretty_printing_indication))))
  (expression_item
    (string
      (string_content)))
  (expression_item
    (string
      (string_content)))
  (expression_item
    (string))
  (expression_item
    (quoted_string
      (quoted_string_content)))
  (expression_item
    (quoted_string))
  (expression_item
    (quoted_string
      (quoted_string_content)))
  (expression_item
    (quoted_string
      (quoted_string_content
        (conversion_specification)
        (pretty_printing_indication))))
  (expression_item
    (quoted_string
      (quoted_string_content)))
  (expression_item
    (quoted_string
      (quoted_string_content)))
  (expression_item
    (quoted_string))
  (expression_item
    (quoted_string))
  (expression_item
    (boolean))
  (expression_item
    (unit)))

===========================
Typed expression
===========================

(x : t)

---

(compilation_unit
  (expression_item
    (typed_expression
      expression: (value_path
        (value_name))
      type: (type_constructor_path
        (type_constructor)))))

===========================
Lists, arrays and records
===========================

[];;
[x; x; x];;
x :: x :: xs;;
[||];;
[| x; x; x |];;
{ x = x; x; };;

---

(compilation_unit
  (expression_item
    (list_expression))
  (expression_item
    (list_expression
      (value_path
        (value_name))
      (value_path
        (value_name))
      (value_path
        (value_name))))
  (expression_item
    (cons_expression
      left: (value_path
        (value_name))
      right: (cons_expression
        left: (value_path
          (value_name))
        right: (value_path
          (value_name)))))
  (expression_item
    (array_expression))
  (expression_item
    (array_expression
      (value_path
        (value_name))
      (value_path
        (value_name))
      (value_path
        (value_name))))
  (expression_item
    (record_expression
      (field_expression
        (field_path
          (field_name))
        body: (value_path
          (value_name)))
      (field_expression
        (field_path
          (field_name))))))

===========================
Get and set expressions
===========================

x.y.z <- x;;
x.(0).[0].{0,0} <- x;;
x.%(0).M.%(0) <- x;;
1 #? x.%(0);;

---

(compilation_unit
  (expression_item
    (set_expression
      (field_get_expression
        record: (field_get_expression
          record: (value_path
            (value_name))
          field: (field_path
            (field_name)))
        field: (field_path
          (field_name)))
      body: (value_path
        (value_name))))
  (expression_item
    (set_expression
      (bigarray_get_expression
        array: (string_get_expression
          string: (array_get_expression
            array: (value_path
              (value_name))
            index: (number))
          index: (number))
        index: (tuple_expression
          (number)
          (number)))
      body: (value_path
        (value_name))))
  (expression_item
    (set_expression
      (array_get_expression
        array: (array_get_expression
          array: (value_path
            (value_name))
          operator: (indexing_operator_path
            (indexing_operator))
          index: (number))
        operator: (indexing_operator_path
          (module_path
            (module_name))
          (indexing_operator))
        index: (number))
      body: (value_path
        (value_name))))
  (expression_item
    (hash_expression
      left: (number)
      operator: (hash_operator)
      right: (array_get_expression
        array: (value_path
          (value_name))
        operator: (indexing_operator_path
          (indexing_operator))
        index: (number)))))

===========================
Coercions
===========================

(x :> t);;
(x : t :> t);;

---

(compilation_unit
  (expression_item
    (coercion_expression
      expression: (value_path
        (value_name))
      coercion: (type_constructor_path
        (type_constructor))))
  (expression_item
    (coercion_expression
      expression: (value_path
        (value_name))
      type: (type_constructor_path
        (type_constructor))
      coercion: (type_constructor_path
        (type_constructor)))))

===========================
Local opens
===========================

M.(x);;
M.[x; x];;

---

(compilation_unit
  (expression_item
    (local_open_expression
      (module_path
        (module_name))
      expression: (value_path
        (value_name))))
  (expression_item
    (local_open_expression
      (module_path
        (module_name))
      expression: (list_expression
        (value_path
          (value_name))
        (value_path
          (value_name))))))

===========================
Package expressions
===========================

(module M);;
(module M : T);;

---

(compilation_unit
  (expression_item
    (package_expression
      module: (module_path
        (module_name))))
  (expression_item
    (package_expression
      module: (module_path
        (module_name))
      module_type: (module_type_path
        (module_type_name)))))

===========================
Tuple expressions
===========================

x, y, z;;
(x, y);;
~a:x, ~b, ~(c:int), d;;

---

(compilation_unit
  (expression_item
    (tuple_expression
      (value_path
        (value_name))
      (value_path
        (value_name))
      (value_path
        (value_name))))
  (expression_item
    (parenthesized_expression
      expression: (tuple_expression
        (value_path
          (value_name))
        (value_path
          (value_name)))))
  (expression_item
    (tuple_expression
      (labeled_tuple_element
        (label_name)
        expression: (value_path
          (value_name)))
      (labeled_tuple_element
        (label_name))
      (labeled_tuple_element
        (label_name)
        type: (type_constructor_path
          (type_constructor)))
      (value_path
        (value_name)))))

===========================
Constructors
===========================

A;;
M.A;;
A x;;
( :: ) (x, l);;

---

(compilation_unit
  (expression_item
    (constructor_path
      (constructor_name)))
  (expression_item
    (constructor_path
      (module_path
        (module_name))
      (constructor_name)))
  (expression_item
    (application_expression
      function: (constructor_path
        (constructor_name))
      argument: (value_path
        (value_name))))
  (expression_item
    (application_expression
      function: (constructor_path
        (constructor_name))
      argument: (parenthesized_expression
        expression: (tuple_expression
          (value_path
            (value_name))
          (value_path
            (value_name)))))))

===========================
Tags
===========================

`A;;
`A x;;

---

(compilation_unit
  (expression_item
    (tag))
  (expression_item
    (application_expression
      function: (tag)
      argument: (value_path
        (value_name)))))

===========================
Function application
===========================

f x;;
f \#let;;
f x x;;
f ~x ?x:x ~(x:x);;
f ~\#type ?\#module:x ~(\#val:x);;

---

(compilation_unit
  (expression_item
    (application_expression
      function: (value_path
        (value_name))
      argument: (value_path
        (value_name))))
  (expression_item
    (application_expression
      function: (value_path
        (value_name))
      argument: (value_path
        (value_name))))
  (expression_item
    (application_expression
      function: (value_path
        (value_name))
      argument: (value_path
        (value_name))
      argument: (value_path
        (value_name))))
  (expression_item
    (application_expression
      function: (value_path
        (value_name))
      argument: (labeled_argument
        (label_name))
      argument: (labeled_argument
        (label_name)
        expression: (value_path
          (value_name)))
      argument: (labeled_argument
        (label_name)
        type: (type_constructor_path
          (type_constructor)))))
  (expression_item
    (application_expression
      function: (value_path
        (value_name))
      argument: (labeled_argument
        (label_name))
      argument: (labeled_argument
        (label_name)
        expression: (value_path
          (value_name)))
      argument: (labeled_argument
        (label_name)
        type: (type_constructor_path
          (type_constructor))))))

===========================
Operators
===========================

!x;;
~-x;;
-x;;
x - y;;
x lsl 1;;

---

(compilation_unit
  (expression_item
    (prefix_expression
      operator: (prefix_operator)
      expression: (value_path
        (value_name))))
  (expression_item
    (prefix_expression
      operator: (prefix_operator)
      expression: (value_path
        (value_name))))
  (expression_item
    (sign_expression
      operator: (sign_operator)
      expression: (value_path
        (value_name))))
  (expression_item
    (infix_expression
      left: (value_path
        (value_name))
      operator: (add_operator)
      right: (value_path
        (value_name))))
  (expression_item
    (infix_expression
      left: (value_path
        (value_name))
      operator: (pow_operator)
      right: (number))))

===========================
If, while and for
===========================

if x then y;;
if x then y else z;;
while x do y done;;
for i = 1 to n do x done;;

---

(compilation_unit
  (expression_item
    (if_expression
      condition: (value_path
        (value_name))
      (then_clause
        expression: (value_path
          (value_name)))))
  (expression_item
    (if_expression
      condition: (value_path
        (value_name))
      (then_clause
        expression: (value_path
          (value_name)))
      (else_clause
        expression: (value_path
          (value_name)))))
  (expression_item
    (while_expression
      condition: (value_path
        (value_name))
      (do_clause
        (value_path
          (value_name)))))
  (expression_item
    (for_expression
      name: (value_pattern)
      from: (number)
      to: (value_path
        (value_name))
      (do_clause
        (value_path
          (value_name))))))

===========================
Sequence expressions
===========================

x; y; z;;

---

(compilation_unit
  (expression_item
    (sequence_expression
      (value_path
        (value_name))
      (value_path
        (value_name))
      (value_path
        (value_name)))))

===========================
Match expressions
===========================

match x with
| x -> x
| x when x -> x
| x | x -> x
| exception x -> x;;
match+ x with x -> x;;

---

(compilation_unit
  (expression_item
    (match_expression
      expression: (value_path
        (value_name))
      (match_case
        pattern: (value_pattern)
        body: (value_path
          (value_name)))
      (match_case
        pattern: (value_pattern)
        (guard
          expression: (value_path
            (value_name)))
        body: (value_path
          (value_name)))
      (match_case
        pattern: (or_pattern
          (value_pattern)
          (value_pattern))
        body: (value_path
          (value_name)))
      (match_case
        pattern: (exception_pattern
          pattern: (value_pattern))
        body: (value_path
          (value_name)))))
  (expression_item
    (match_expression
      (match_operator)
      expression: (value_path
        (value_name))
      (match_case
        pattern: (value_pattern)
        body: (value_path
          (value_name))))))

===========================
Function expressions
===========================

function 0 -> 0 | x -> 1;;
function A (type a) x -> 1;;

---

(compilation_unit
  (expression_item
    (function_expression
      (match_case
        pattern: (number)
        body: (number))
      (match_case
        pattern: (value_pattern)
        body: (number))))
  (expression_item
    (function_expression
      (match_case
        pattern: (constructor_pattern
          (constructor_path
            (constructor_name))
          (abstract_type
            (type_constructor))
          pattern: (value_pattern))
        body: (number)))))

===========================
Try expressions
===========================

try x with Exception -> ()

---

(compilation_unit
  (expression_item
    (try_expression
      expression: (value_path
        (value_name))
      (match_case
        pattern: (constructor_path
          (constructor_name))
        body: (unit)))))

===========================
Let expressions
===========================

let x = 0 in x;;
let rec x = y and y = x in x;;

---

(compilation_unit
  (expression_item
    (let_expression
      (value_definition
        (let_binding
          pattern: (value_name)
          body: (number)))
      body: (value_path
        (value_name))))
  (expression_item
    (let_expression
      (value_definition
        (let_binding
          pattern: (value_name)
          body: (value_path
            (value_name)))
        (let_binding
          pattern: (value_name)
          body: (value_path
            (value_name))))
      body: (value_path
        (value_name)))))

===========================
Assert expressions
===========================

assert x

---

(compilation_unit
  (expression_item
    (assert_expression
      expression: (value_path
        (value_name)))))

===========================
Lazy expressions
===========================

lazy x

---

(compilation_unit
  (expression_item
    (lazy_expression
      expression: (value_path
        (value_name)))))

===========================
Let module, open, exception
===========================

let module M = M in x;;
let open M in x;;
let exception E in x;;

---

(compilation_unit
  (expression_item
    (let_module_expression
      (module_definition
        (module_binding
          (module_name)
          body: (module_path
            (module_name))))
      body: (value_path
        (value_name))))
  (expression_item
    (let_open_expression
      (open_module
        module: (module_path
          (module_name)))
      body: (value_path
        (value_name))))
  (expression_item
    (let_exception_expression
      (exception_definition
        (constructor_declaration
          (constructor_name)))
      body: (value_path
        (value_name)))))

===========================
Parenthesized expressions
===========================

let x = (x)

---

(compilation_unit
  (value_definition
    (let_binding
      pattern: (value_name)
      body: (parenthesized_expression
        expression: (value_path
          (value_name))))))

===========================
Precedence
===========================

let x = x in if x then x <- x := ! x . x ## x # x x x lsl x ** x * x mod x + x - x :: x :: x @ x ^ x < x > x & x && x or x || x, x, x; x; x

---

(compilation_unit
  (expression_item
    (let_expression
      (value_definition
        (let_binding
          pattern: (value_name)
          body: (value_path
            (value_name))))
      body: (sequence_expression
        (if_expression
          condition: (value_path
            (value_name))
          (then_clause
            expression: (set_expression
              (instance_variable_name)
              body: (infix_expression
                left: (value_path
                  (value_name))
                operator: (assign_operator)
                right: (tuple_expression
                  (infix_expression
                    left: (infix_expression
                      left: (infix_expression
                        left: (infix_expression
                          left: (infix_expression
                            left: (cons_expression
                              left: (infix_expression
                                left: (infix_expression
                                  left: (infix_expression
                                    left: (infix_expression
                                      left: (infix_expression
                                        left: (application_expression
                                          function: (method_invocation
                                            object: (hash_expression
                                              left: (field_get_expression
                                                record: (prefix_expression
                                                  operator: (prefix_operator)
                                                  expression: (value_path
                                                    (value_name)))
                                                field: (field_path
                                                  (field_name)))
                                              operator: (hash_operator)
                                              right: (value_path
                                                (value_name)))
                                            method: (method_name))
                                          argument: (value_path
                                            (value_name))
                                          argument: (value_path
                                            (value_name)))
                                        operator: (pow_operator)
                                        right: (infix_expression
                                          left: (value_path
                                            (value_name))
                                          operator: (pow_operator)
                                          right: (value_path
                                            (value_name))))
                                      operator: (mult_operator)
                                      right: (value_path
                                        (value_name)))
                                    operator: (mult_operator)
                                    right: (value_path
                                      (value_name)))
                                  operator: (add_operator)
                                  right: (value_path
                                    (value_name)))
                                operator: (add_operator)
                                right: (value_path
                                  (value_name)))
                              right: (cons_expression
                                left: (value_path
                                  (value_name))
                                right: (value_path
                                  (value_name))))
                            operator: (concat_operator)
                            right: (infix_expression
                              left: (value_path
                                (value_name))
                              operator: (concat_operator)
                              right: (value_path
                                (value_name))))
                          operator: (rel_operator)
                          right: (value_path
                            (value_name)))
                        operator: (rel_operator)
                        right: (value_path
                          (value_name)))
                      operator: (and_operator)
                      right: (infix_expression
                        left: (value_path
                          (value_name))
                        operator: (and_operator)
                        right: (value_path
                          (value_name))))
                    operator: (or_operator)
                    right: (infix_expression
                      left: (value_path
                        (value_name))
                      operator: (or_operator)
                      right: (value_path
                        (value_name))))
                  (value_path
                    (value_name))
                  (value_path
                    (value_name)))))))
        (value_path
          (value_name))
        (value_path
          (value_name))))))
