================================================================================
Do-notation
================================================================================

f = do
  pure 1

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_do
      (statement
        (exp_apply
          (exp_name
            (variable))
          (exp_literal
            (integer)))))))

================================================================================
Do-notation, bind-binders
================================================================================

f = do
  a <- b
  C d <- f
  G h i <- j
  pure 1

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_do
      (statement
        (bind_pattern
          (pat_name
            (variable))
          (exp_name
            (variable))))
      (statement
        (bind_pattern
          (pat_apply
            (pat_name
              (constructor))
            (pat_name
              (variable)))
          (exp_name
            (variable))))
      (statement
        (bind_pattern
          (pat_apply
            (pat_name
              (constructor))
            (pat_name
              (variable))
            (pat_name
              (variable)))
          (exp_name
            (variable))))
      (statement
        (exp_apply
          (exp_name
            (variable))
          (exp_literal
            (integer)))))))

================================================================================
Do-notation, let-binders
================================================================================

f = do
  let a = b
  let C d = f
  let G h i = j
  pure 1

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_do
      (statement
        (let
          (declarations
            (function
              name: (variable)
              rhs: (exp_name
                (variable))))))
      (statement
        (let
          (declarations
            (function
              pattern: (pat_apply
                (pat_name
                  (constructor))
                (pat_name
                  (variable)))
              rhs: (exp_name
                (variable))))))
      (statement
        (let
          (declarations
            (function
              pattern: (pat_apply
                (pat_name
                  (constructor))
                (pat_name
                  (variable))
                (pat_name
                  (variable)))
              rhs: (exp_name
                (variable))))))
      (statement
        (exp_apply
          (exp_name
            (variable))
          (exp_literal
            (integer)))))))

================================================================================
Do-notation, nested do-notation
================================================================================

f = do
  do
    pure 1

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_do
      (statement
        (exp_do
          (statement
            (exp_apply
              (exp_name
                (variable))
              (exp_literal
                (integer)))))))))

================================================================================
Ado-notation
================================================================================

f = ado
  in []

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_ado
      in: (exp_array))))

================================================================================
Ado-notation, bind-binders
================================================================================

f = ado
  a <- b
  C d <- f
  G h i <- j
  in []

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_ado
      (statement
        (bind_pattern
          (pat_name
            (variable))
          (exp_name
            (variable))))
      (statement
        (bind_pattern
          (pat_apply
            (pat_name
              (constructor))
            (pat_name
              (variable)))
          (exp_name
            (variable))))
      (statement
        (bind_pattern
          (pat_apply
            (pat_name
              (constructor))
            (pat_name
              (variable))
            (pat_name
              (variable)))
          (exp_name
            (variable))))
      in: (exp_array))))

================================================================================
Ado-notation, let-binders
================================================================================

f = ado
  let a = b
  let C d = f
  let G h i = j
  in 1

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_ado
      (statement
        (let
          (declarations
            (function
              name: (variable)
              rhs: (exp_name
                (variable))))))
      (statement
        (let
          (declarations
            (function
              pattern: (pat_apply
                (pat_name
                  (constructor))
                (pat_name
                  (variable)))
              rhs: (exp_name
                (variable))))))
      (statement
        (let
          (declarations
            (function
              pattern: (pat_apply
                (pat_name
                  (constructor))
                (pat_name
                  (variable))
                (pat_name
                  (variable)))
              rhs: (exp_name
                (variable))))))
      in: (exp_literal
        (integer)))))

================================================================================
Ado-notation, nested ado-notation
================================================================================

f = ado
  in ado
    in 1

g = ado
  a <- \_ → ado
    b <- case c of d -> ado
      e <- f
      in e
    in b
  let aa = a
  aaa <- aa
  in aaa

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_ado
      in: (exp_ado
        in: (exp_literal
          (integer)))))
  (function
    name: (variable)
    rhs: (exp_ado
      (statement
        (bind_pattern
          (pat_name
            (variable))
          (exp_lambda
            (pat_wildcard
              (pat_wildcard))
            (exp_ado
              (statement
                (bind_pattern
                  (pat_name
                    (variable))
                  (exp_case
                    condition: (exp_name
                      (variable))
                    (alts
                      (alt
                        pat: (pat_name
                          (variable))
                        exp: (exp_ado
                          (statement
                            (bind_pattern
                              (pat_name
                                (variable))
                              (exp_name
                                (variable))))
                          in: (exp_name
                            (variable))))))))
              in: (exp_name
                (variable))))))
      (statement
        (let
          (declarations
            (function
              name: (variable)
              rhs: (exp_name
                (variable))))))
      (statement
        (bind_pattern
          (pat_name
            (variable))
          (exp_name
            (variable))))
      in: (exp_name
        (variable)))))

================================================================================
Ado-notation, single line
================================================================================

e = ado            in [] -- fine
f = ado []         in [] -- fine
g = ado let a = [] in [] -- can't handle yet

--------------------------------------------------------------------------------

(purescript
  (function
    name: (variable)
    rhs: (exp_ado
      in: (exp_array)
      (comment)))
  (function
    name: (variable)
    rhs: (exp_ado
      (statement
        (exp_array))
      in: (exp_array)
      (comment)))
  (ERROR
    name: (variable)
    (statement
      (let
        (declarations
          (function
            name: (variable)
            rhs: (exp_apply
              (exp_array)
              (exp_name
                (variable))
              (exp_array)))
          (comment))))))

================================================================================
Ado-notation, layout edge case
================================================================================

module M
  where

a = ( ado
  b <- c
  in d )

e = ( ado
  f <- g
  in h )

--------------------------------------------------------------------------------

(purescript
  (qualified_module
    (module))
  (where)
  (function
    (variable)
    (exp_parens
      (exp_ado
        (statement
          (bind_pattern
            (pat_name
              (variable))
            (exp_name
              (variable))))
        (exp_name
          (variable)))))
  (function
    (variable)
    (exp_parens
      (exp_ado
        (statement
          (bind_pattern
            (pat_name
              (variable))
            (exp_name
              (variable))))
        (exp_name
          (variable))))))
