=======
module
=======

module foo

---

(program
  (modulepath
    (varid
      (id)))
  (moduledecl))

================
long modulepath
================

module foo/bar/baz

---

(program
  (modulepath
    (qvarid
      (qid)))
  (moduledecl))

========
imports
========

import foo
import foo/bar/baz

import foo = bar
import foo/bar/baz = quux

---

(program
  (moduledecl)
  (modulebody
    (importdecl
      (modulepath
        (varid
          (id))))
    (importdecl
      (modulepath
        (qvarid
          (qid))))
    (importdecl
      (modulepath
        (varid
          (id)))
        (modulepath
          (varid
            (id))))
    (importdecl
      (modulepath
        (qvarid
          (qid)))
        (modulepath
          (varid
            (id))))))

=======
fixity
=======

pub infixr 80  (^)
pub infixl 70  (*), (%), (/), cdiv, cmod
pub infixl 60  (+), (-)
pub infix  40  (!=), (==), (<=), (>=), (<), (>)

---

(program
  (moduledecl)
  (modulebody
    (fixitydecl
      (fixity
        (int))
      (oplist
        (identifier
          (idop))))
    (fixitydecl
      (fixity
        (int))
      (oplist
        (identifier
          (idop))
        (identifier
          (idop))
        (identifier
          (idop))
        (identifier
          (varid
            (id)))
        (identifier
          (varid
            (id)))))
    (fixitydecl
      (fixity
        (int))
      (oplist
        (identifier
          (idop))
        (identifier
          (idop))))
    (fixitydecl
      (fixity
        (int))
      (oplist
        (identifier
          (idop))
        (identifier
          (idop))
        (identifier
          (idop))
        (identifier
          (idop))
        (identifier
          (idop))
        (identifier
          (idop))))))

========
externs
========

extern import
  cs file "regex-inline.cs"
  js file "regex-inline.js"
  c  file "regex-inline.c"

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (externdecl
        (externimpbody
          (externimp
            (externtarget)
            (varid
              (id))
            (string))
          (externimp
            (externtarget)
            (varid
              (id))
            (string))
          (externimp
            (externtarget)
            (varid
              (id))
            (string)))))))

========
numbers
========

val a = 80123456789
val b = -89612
val c = 0
val d = -0
val e = 0x0123456789abcdef
val f = -0XABCDEF
val g = 0x0
val h = -0x0
val i = 13512.45_315_315e+30531
val j = -13512E-30531
val k = 13512.45_315e315
val l = 0.45_315_315e+30531
val m = -0x135EA12.45_31CD5_315p+30531
val n = 0X135f12P-30531
val o = -0x1fAcED3512.45_3e15_315
val p = -0x0.45_31CD5_315p+30531

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (float)))))))))))))

========
opexprs
========

val a = n / 2

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))
                (qoperator
                  (op))
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))))

==========
typedecls
==========

pub open type exception-info
  ExnError      // Generic error
  ExnAssert
  ExnTodo
  ExnRange
  ExnPattern( location : string, definition : string )
  ExnSystem( errno : int )
  ExnInternal( name : string )

pub value struct exception( message :string, info :exception-info )

pub named scoped effect exn
  // Throw an exception
  ctl throw-exn( exn : exception ) : a

pub effect fun utc() : timescale

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (typedecl
        (typemod)
        (typeid
          (varid
            (id)))
        (typebody
          (constructors
            (constructor
              (conid))
            (linecomment)
            (constructor
              (conid))
            (constructor
              (conid))
            (constructor
              (conid))
            (constructor
              (conid)
              (conparams
                (parameters
                  (parameter
                    (paramid
                      (identifier
                        (varid
                          (id))))
                    (type
                      (tarrow
                        (tatomic
                          (tbasic
                            (typeapp
                              (typecon
                                (varid
                                  (id)))))))))
                  (parameter
                    (paramid
                      (identifier
                        (varid
                          (id))))
                    (type
                      (tarrow
                        (tatomic
                          (tbasic
                            (typeapp
                              (typecon
                                (varid
                                  (id))))))))))))
            (constructor
              (conid)
              (conparams
                (parameters
                  (parameter
                    (paramid
                      (identifier
                        (varid
                          (id))))
                    (type
                      (tarrow
                        (tatomic
                          (tbasic
                            (typeapp
                              (typecon
                                (varid
                                  (id))))))))))))
            (constructor
              (conid)
              (conparams
                (parameters
                  (parameter
                    (paramid
                      (identifier
                        (varid
                          (id))))
                    (type
                      (tarrow
                        (tatomic
                          (tbasic
                            (typeapp
                              (typecon
                                (varid
                                  (id))))))))))))))))
    (topdecl
      (typedecl
        (structmod)
        (typeid
          (varid
            (id)))
        (conparams
          (parameters
            (parameter
              (paramid
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))
            (parameter
              (paramid
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))))))
    (topdecl
      (typedecl
        (varid
          (id))
        (opdecls
          (linecomment)
          (operations
            (operation
              (identifier
                (varid
                  (id)))
              (parameters
                (parameter
                  (paramid
                    (identifier
                      (varid
                        (id))))
                  (type
                    (tarrow
                      (tatomic
                        (tbasic
                          (typeapp
                            (typecon
                              (varid
                                (id))))))))))
              (tatomic
                (tbasic
                  (typeapp
                    (typecon
                      (varid
                        (id)))))))))))
    (topdecl
      (typedecl
        (operation
          (identifier
            (varid
              (id)))
          (tatomic
            (tbasic
              (typeapp
                (typecon
                  (varid
                    (id)))))))))))

===========
simple var
===========

val foo = bar

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
          (blockexpr
            (expr
              (basicexpr
                (opexpr
                  (prefixexpr
                    (appexpr
                      (atom
                        (qidentifier
                          (identifier
                            (varid
                              (id)))))))))))))))

=======
string
=======

val foo = "bar"
val baz = "https://www.ietf.org/timezones/data/leap-seconds.list"
val quux = "a /* foo */ b"

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (string)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (string)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (string)))))))))))))

===========
raw string
===========

val foo = r"bar"
val foo = r#"bar"#
val foo = r###"bar"##baz"###

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
          (blockexpr
            (expr
              (basicexpr
                (opexpr
                  (prefixexpr
                    (appexpr
                      (atom
                        (literal
                          (string)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
          (blockexpr
            (expr
              (basicexpr
                (opexpr
                  (prefixexpr
                    (appexpr
                      (atom
                        (literal
                          (string)))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
          (blockexpr
            (expr
              (basicexpr
                (opexpr
                  (prefixexpr
                    (appexpr
                      (atom
                        (literal
                          (string)))))))))))))

=====
list
=====

val ns : list<int> = [
  1,
  2,
  3
]

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id)))
          (type
            (tarrow
              (tatomic
                (tbasic
                  (typeapp
                    (typecon
                      (varid
                        (id)))
                    (targuments
                      (anntype
                        (type
                          (tarrow
                            (tatomic
                              (tbasic
                                (typeapp
                                  (typecon
                                    (varid
                                      (id))))))))))))))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (cexprs
                        (aexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (literal
                                        (int)))))))))
                        (aexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (literal
                                        (int)))))))))
                        (aexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (literal
                                        (int)))))))))))))))))))))

====
fun
====

fun main()
  return 0

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (returnexpr
                        (expr
                          (basicexpr
                            (opexpr
                              (prefixexpr
                                (appexpr
                                  (atom
                                    (literal
                                      (int))))))))))))))))))))

============
linecomment
============

// a comment

// more
// comments

val foo = 0 // another comment

---

(program
  (moduledecl
    (linecomment)
    (linecomment)
    (linecomment))
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (linecomment)))

=============
blockcomment
=============

/* a comment */

/* more
 comments
 */

val foo = 0 /* another comment */

/* a /* very /* nested */ comment */ structure */
---

(program
  (moduledecl
    (blockcomment)
    (blockcomment))
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int)))))))))))
    (blockcomment)
    (blockcomment
      (blockcomment
        (blockcomment)))))

====================
top level statments
====================

with foo
var bar := baz

---

(program
  (statements
    (statement
      (withstat
        (basicexpr
          (opexpr
            (prefixexpr
              (appexpr
                (atom
                  (qidentifier
                    (identifier
                      (varid
                        (id)))))))))))
    (statement
      (decl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))))))))))

=============================
no semis no trailing newline
=============================

val foo = bar
---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))))))))))

=================================
no semis easy start continuation
=================================

val foo = a
 + b

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))
                (qoperator
                  (op))
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))))))))))

===============================
advanced keyword continuations
===============================

val a = if b
  then c
  elif d
  then e
  else f
val a = if b
  then 'c'
  elif'
  else'

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (ifexpr
                (expr
                  (basicexpr
                    (opexpr
                      (prefixexpr
                        (appexpr
                          (atom
                            (qidentifier
                              (identifier
                                (varid
                                  (id))))))))))
                (blockexpr
                  (expr
                    (basicexpr
                      (opexpr
                        (prefixexpr
                          (appexpr
                            (atom
                              (qidentifier
                                (identifier
                                  (varid
                                    (id)))))))))))
                (elifs
                  (expr
                    (basicexpr
                      (opexpr
                        (prefixexpr
                          (appexpr
                            (atom
                              (qidentifier
                                (identifier
                                  (varid
                                    (id))))))))))
                (blockexpr
                  (expr
                    (basicexpr
                      (opexpr
                        (prefixexpr
                          (appexpr
                            (atom
                              (qidentifier
                                (identifier
                                  (varid
                                    (id)))))))))))
                (blockexpr
                  (expr
                    (basicexpr
                      (opexpr
                        (prefixexpr
                          (appexpr
                            (atom
                              (qidentifier
                                (identifier
                                  (varid
                                    (id))))))))))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (ifexpr
                (expr
                  (basicexpr
                    (opexpr
                      (prefixexpr
                        (appexpr
                          (atom
                            (qidentifier
                              (identifier
                                (varid
                                  (id))))))))))
                (blockexpr
                  (expr
                    (basicexpr
                      (opexpr
                        (prefixexpr
                          (appexpr
                            (appexpr
                              (atom
                                (literal
                                  (char))))
                            (block
                              (statements
                                (statement
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id))))))))))
                                (statement
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id))))))))))))))))))))))))))

=======================================
advanced keyword continuation, no semi
=======================================

fun a()
  if a then
    w + x
  elif b then
    x + y
  else
    y + z

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (ifexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (qidentifier
                                        (identifier
                                          (varid
                                            (id))))))))))
                          (blockexpr
                            (expr
                              (block
                                (statements
                                  (statement
                                    (basicexpr
                                      (opexpr
                                        (prefixexpr
                                          (appexpr
                                            (atom
                                              (qidentifier
                                                (identifier
                                                  (varid
                                                    (id)))))))
                                        (qoperator
                                          (op))
                                        (prefixexpr
                                          (appexpr
                                            (atom
                                              (qidentifier
                                                (identifier
                                                  (varid
                                                    (id))))))))))))))
                          (elifs
                            (expr
                              (basicexpr
                                (opexpr
                                  (prefixexpr
                                    (appexpr
                                      (atom
                                        (qidentifier
                                          (identifier
                                            (varid
                                              (id))))))))))
                            (blockexpr
                              (expr
                                (block
                                  (statements
                                    (statement
                                      (basicexpr
                                        (opexpr
                                          (prefixexpr
                                            (appexpr
                                              (atom
                                                (qidentifier
                                                  (identifier
                                                    (varid
                                                      (id)))))))
                                          (qoperator
                                            (op))
                                          (prefixexpr
                                            (appexpr
                                              (atom
                                                (qidentifier
                                                  (identifier
                                                    (varid
                                                      (id))))))))))))))
                            (blockexpr
                              (expr
                                (block
                                  (statements
                                    (statement
                                      (basicexpr
                                        (opexpr
                                          (prefixexpr
                                            (appexpr
                                              (atom
                                                (qidentifier
                                                  (identifier
                                                    (varid
                                                      (id)))))))
                                          (qoperator
                                            (op))
                                          (prefixexpr
                                            (appexpr
                                              (atom
                                                (qidentifier
                                                  (identifier
                                                    (varid
                                                      (id))))))))))))))))))))))))))))

================================
advanced operator continuations
================================

val a = b
  < c
val a = b
  >| d
val a = b
  > d
fun a() : a
  !b

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))
                (qoperator
                  (op))
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))
                (qoperator
                  (op))
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))))))))
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))
                (qoperator
                  (op))
                (prefixexpr
                  (appexpr
                    (atom
                      (qidentifier
                        (identifier
                          (varid
                            (id)))))))))))))
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (tresult
            (tatomic
              (tbasic
                (typeapp
                  (typecon
                    (varid
                      (id)))))))
          (block
            (statements
              (statement
                (basicexpr
                  (opexpr
                    (prefixexpr
                      (prefixexpr
                        (appexpr
                          (atom
                            (qidentifier
                              (identifier
                                (varid
                                  (id))))))))))))))))))

==================
braced modulebody
==================

module foo/bar {
  infixl 1 (>>=)

  pub val a = 0
}

---

(program
  (modulepath
    (qvarid
      (qid)))
  (moduledecl)
  (moduledecl)
  (modulebody
    (fixitydecl
      (fixity
        (int))
      (oplist
        (identifier
          (idop)))))
  (modulebody
    (topdecl
      (puredecl
        (binder
          (identifier
            (varid
              (id))))
        (blockexpr
          (expr
            (basicexpr
              (opexpr
                (prefixexpr
                  (appexpr
                    (atom
                      (literal
                        (int))))))))))))
  (moduledecl)
  (moduledecl))

======
match
======

fun a()
  match a
    foo/A ->
      5
    B ->
      3
  val i = 1

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (matchexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (qidentifier
                                        (identifier
                                          (varid
                                            (id))))))))))
                          (matchrules
                            (matchrule
                              (patterns
                                (pattern
                                  (qconstructor
                                    (qconid))))
                              (blockexpr
                                (expr
                                  (block
                                    (statements
                                      (statement
                                        (basicexpr
                                          (opexpr
                                            (prefixexpr
                                              (appexpr
                                                (atom
                                                  (literal
                                                    (int)))))))))))))
                            (matchrule
                              (patterns
                                (pattern
                                  (qconstructor
                                    (conid))))
                              (blockexpr
                                (expr
                                  (block
                                    (statements
                                      (statement
                                        (basicexpr
                                          (opexpr
                                            (prefixexpr
                                              (appexpr
                                                (atom
                                                  (literal
                                                    (int)))))))))))))))))
                    (statement
                      (decl
                        (apattern
                          (pattern
                            (identifier
                              (varid
                                (id)))))
                        (blockexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (literal
                                        (int)))))))))))))))))))))

=========
readline
=========

pub fun readline() : <asyncx,console> string {
  await-exn1 fn(cb) {
    val id = prim-readline(cb)
    Just( { prim-cancel-readline(id) })
  }
}

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (tresult
            (tatomic
              (targuments
                (anntype
                  (type
                    (tarrow
                      (tatomic
                        (tbasic
                          (typeapp
                            (typecon
                              (varid
                                (id)))))))))
                (anntype
                  (type
                    (tarrow
                      (tatomic
                        (tbasic
                          (typeapp
                            (typecon
                              (varid
                                (id)))))))))))
            (tbasic
              (typeapp
                (typecon
                  (varid
                    (id))))))
          (block
            (statements
              (statement
                (basicexpr
                  (opexpr
                    (prefixexpr
                      (appexpr
                        (appexpr
                          (atom
                            (qidentifier
                              (identifier
                                (varid
                                  (id))))))
                        (fnexpr
                          (funbody
                            (pparameters
                              (pparameter
                                (pattern
                                  (identifier
                                    (varid
                                      (id))))))
                            (bodyexpr
                              (blockexpr
                                (expr
                                  (block
                                    (statements
                                      (statement
                                        (decl
                                          (apattern
                                            (pattern
                                              (identifier
                                                (varid
                                                  (id)))))
                                          (blockexpr
                                            (expr
                                              (basicexpr
                                                (opexpr
                                                  (prefixexpr
                                                    (appexpr
                                                      (appexpr
                                                        (atom
                                                          (qidentifier
                                                            (identifier
                                                              (varid
                                                                (id))))))
                                                      (arguments
                                                        (argument
                                                          (expr
                                                            (basicexpr
                                                              (opexpr
                                                                (prefixexpr
                                                                  (appexpr
                                                                    (atom
                                                                      (qidentifier
                                                                        (identifier
                                                                          (varid
                                                                            (id))))))))))))))))))))
                                      (statement
                                        (basicexpr
                                          (opexpr
                                            (prefixexpr
                                              (appexpr
                                                (appexpr
                                                  (atom
                                                    (qconstructor
                                                      (conid))))
                                                (arguments
                                                  (argument
                                                    (expr
                                                      (block
                                                        (statements
                                                          (statement
                                                            (basicexpr
                                                              (opexpr
                                                                (prefixexpr
                                                                  (appexpr
                                                                    (appexpr
                                                                      (atom
                                                                        (qidentifier
                                                                          (identifier
                                                                            (varid
                                                                              (id))))))
                                                                    (arguments
                                                                      (argument
                                                                        (expr
                                                                          (basicexpr
                                                                            (opexpr
                                                                              (prefixexpr
                                                                                (appexpr
                                                                                  (atom
                                                                                    (qidentifier
                                                                                      (identifier
                                                                                        (varid
                                                                                          (id))))))))))))))))))))))))))))))))))))))))))))))

===============================
statement block in else branch
===============================

fun a()
  if b then c else
    val d = e

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (ifexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (qidentifier
                                        (identifier
                                          (varid
                                            (id))))))))))
                          (blockexpr
                            (expr
                              (basicexpr
                                (opexpr
                                  (prefixexpr
                                    (appexpr
                                      (atom
                                        (qidentifier
                                          (identifier
                                            (varid
                                              (id)))))))))))
                          (elifs
                            (blockexpr
                              (expr
                                (block
                                  (statements
                                    (statement
                                      (decl
                                        (apattern
                                          (pattern
                                            (identifier
                                              (varid
                                                (id)))))
                                        (blockexpr
                                          (expr
                                            (basicexpr
                                              (opexpr
                                                (prefixexpr
                                                  (appexpr
                                                    (atom
                                                      (qidentifier
                                                        (identifier
                                                          (varid
                                                            (id)))))))))))))))))))))))))))))))

================
abstract struct
================

abstract struct calendar
  name        : string
  long-name   : string
  month-prefix: string
  show-era    : (date) -> string

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (typedecl
        (typeid
          (varid
            (id)))
        (conparams
          (sconparams
            (parameter
              (paramid
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))
            (parameter
              (paramid
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))
            (parameter
              (paramid
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))
            (parameter
              (paramid
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (tparams
                        (tparam
                          (anntype
                            (type
                              (tarrow
                                (tatomic
                                  (tbasic
                                    (typeapp
                                      (typecon
                                        (varid
                                          (id)))))))))))))
                  (tresult
                    (tatomic
                      (tbasic
                        (typeapp
                          (typecon
                            (varid
                              (id))))))))))))))))

=======
prints
=======

noinline fun prints( s : string ) : console ()
  (unsafe-nostate
    match !redirect
      Nothing -> xprints(s)
      Just(f) -> f(s)
  )()

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (pparameters
            (pparameter
              (pattern
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id))))))))))
          (tresult
            (tatomic
              (tbasic
                (typeapp
                  (typecon
                    (varid
                      (id))))))
            (tbasic))
          (block
            (statements
              (statement
                (basicexpr
                  (opexpr
                    (prefixexpr
                      (appexpr
                        (appexpr
                          (atom
                            (aexprs
                              (aexpr
                                (expr
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (appexpr
                                            (atom
                                              (qidentifier
                                                (identifier
                                                  (varid
                                                    (id))))))
                                          (block
                                            (statements
                                              (statement
                                                (basicexpr
                                                  (matchexpr
                                                    (expr
                                                      (basicexpr
                                                        (opexpr
                                                          (prefixexpr
                                                            (prefixexpr
                                                              (appexpr
                                                                (atom
                                                                  (qidentifier
                                                                    (identifier
                                                                      (varid
                                                                        (id)))))))))))
                                                    (matchrules
                                                      (matchrule
                                                        (patterns
                                                          (pattern
                                                            (qconstructor
                                                              (conid))))
                                                        (blockexpr
                                                          (expr
                                                            (basicexpr
                                                              (opexpr
                                                                (prefixexpr
                                                                  (appexpr
                                                                    (appexpr
                                                                      (atom
                                                                        (qidentifier
                                                                          (identifier
                                                                            (varid
                                                                              (id))))))
                                                                    (arguments
                                                                      (argument
                                                                        (expr
                                                                          (basicexpr
                                                                            (opexpr
                                                                              (prefixexpr
                                                                                (appexpr
                                                                                  (atom
                                                                                    (qidentifier
                                                                                      (identifier
                                                                                        (varid
                                                                                          (id)))))))))))))))))))
                                                      (matchrule
                                                        (patterns
                                                          (pattern
                                                            (qconstructor
                                                              (conid))
                                                            (patargs
                                                              (patarg
                                                                (apattern
                                                                  (pattern
                                                                    (identifier
                                                                      (varid
                                                                        (id)))))))))
                                                        (blockexpr
                                                          (expr
                                                            (basicexpr
                                                              (opexpr
                                                                (prefixexpr
                                                                  (appexpr
                                                                    (appexpr
                                                                      (atom
                                                                        (qidentifier
                                                                          (identifier
                                                                            (varid
                                                                              (id))))))
                                                                    (arguments
                                                                      (argument
                                                                        (expr
                                                                          (basicexpr
                                                                            (opexpr
                                                                              (prefixexpr
                                                                                (appexpr
                                                                                  (atom
                                                                                    (qidentifier
                                                                                      (identifier
                                                                                        (varid
                                                                                          (id))))))))))))))))))))))))))))))))))))))))))))))

==========
trailing1
==========

fun main() {
  val xs = [1,2,3,]
  xs.length
}
---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (decl
                        (apattern
                          (pattern
                            (identifier
                              (varid
                                (id)))))
                        (blockexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (atom
                                      (cexprs
                                        (aexpr
                                          (expr
                                            (basicexpr
                                              (opexpr
                                                (prefixexpr
                                                  (appexpr
                                                    (atom
                                                      (literal
                                                        (int)))))))))
                                        (aexpr
                                          (expr
                                            (basicexpr
                                              (opexpr
                                                (prefixexpr
                                                  (appexpr
                                                    (atom
                                                      (literal
                                                        (int)))))))))
                                        (aexpr
                                          (expr
                                            (basicexpr
                                              (opexpr
                                                (prefixexpr
                                                  (appexpr
                                                    (atom
                                                      (literal
                                                        (int)))))))))))))))))))
                    (statement
                      (basicexpr
                        (opexpr
                          (prefixexpr
                            (appexpr
                              (appexpr
                                (atom
                                  (qidentifier
                                    (identifier
                                      (varid
                                        (id))))))
                              (atom
                                (qidentifier
                                  (identifier
                                    (varid
                                      (id))))))))))))))))))))

==========
trailing2
==========

fun main() {
  val x = (1,2,)
  x.fst
}
; TODO: fix this error ---

(program
  (statements
    (statement
      (decl
        (fundecl
          (funid
            (identifier
              (varid
                (id))))
          (funbody
            (bodyexpr
              (blockexpr
                (expr
                  (block
                    (statements
                      (statement
                        (decl
                          (apattern
                            (pattern
                              (identifier
                                (varid
                                  (id)))))
                          (blockexpr
                            (expr
                              (basicexpr
                                (opexpr
                                  (prefixexpr
                                    (appexpr
                                      (atom
                                        (aexprs
                                          (aexpr
                                            (expr
                                              (basicexpr
                                                (opexpr
                                                  (prefixexpr
                                                    (appexpr
                                                      (atom
                                                        (literal
                                                          (int)))))))))
                                          (aexpr
                                            (expr
                                              (basicexpr
                                                (opexpr
                                                  (prefixexpr
                                                    (appexpr
                                                      (atom
                                                        (literal
                                                          (int))))))))))
                                        (ERROR))))))))))
                      (statement
                        (basicexpr
                          (opexpr
                            (prefixexpr
                              (appexpr
                                (appexpr
                                  (atom
                                    (qidentifier
                                      (identifier
                                        (varid
                                          (id))))))
                                (atom
                                  (qidentifier
                                    (identifier
                                      (varid
                                        (id)))))))))))))))))))))

=========
fip/fbip
=========

tail fun fact( i : int ) : int
  if i <= 1 then
    return 1
  else
    return i * fact(i - 1)

pub fip fun bool( i : int32 ) : bool 
  (i!=zero)

fip(n) fun other()
  foo

fbip(1) fun ins( t : tree, k : int, v : bool ): tree  
  match t
    Leaf -> Node(Red, Leaf, k, v, Leaf)
    Node(Red, l, kx, vx, r)
      -> if k < kx then Node(Red, ins(l, k, v), kx, vx, r)
    Node(Black, l, kx, vx, r)
      -> if k < kx && is-red(l) then balance-left(ins(l,k,v), kx, vx, r)

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (fipmod)
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (pparameters
            (pparameter
              (pattern
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id))))))))))
          (tresult
            (tatomic
              (tbasic
                (typeapp
                  (typecon
                    (varid
                      (id)))))))
          (block
            (statements
              (statement
                (basicexpr
                  (ifexpr
                    (expr
                      (basicexpr
                        (opexpr
                          (prefixexpr
                            (appexpr
                              (atom
                                (qidentifier
                                  (identifier
                                    (varid
                                      (id)))))))
                          (qoperator
                            (op))
                          (prefixexpr
                            (appexpr
                              (atom
                                (literal
                                  (int))))))))
                    (blockexpr
                      (expr
                        (block
                          (statements
                            (statement
                              (returnexpr
                                (expr
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (literal
                                              (int))))))))))))))
                    (elifs
                      (blockexpr
                        (expr
                          (block
                            (statements
                              (statement
                                (returnexpr
                                  (expr
                                    (basicexpr
                                      (opexpr
                                        (prefixexpr
                                          (appexpr
                                            (atom
                                              (qidentifier
                                                (identifier
                                                  (varid
                                                    (id)))))))
                                        (qoperator
                                          (op))
                                        (prefixexpr
                                          (appexpr
                                            (appexpr
                                              (atom
                                                (qidentifier
                                                  (identifier
                                                    (varid
                                                      (id))))))
                                            (arguments
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id)))))))
                                                      (qoperator
                                                        (op))
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (literal
                                                              (int))))))))))))))))))))))))))))))
    (topdecl
      (puredecl
        (fipmod)
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (pparameters
            (pparameter
              (pattern
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id))))))))))
          (tresult
            (tatomic
              (tbasic
                (typeapp
                  (typecon
                    (varid
                      (id)))))))
          (block
            (statements
              (statement
                (basicexpr
                  (opexpr
                    (prefixexpr
                      (appexpr
                        (atom
                          (aexprs
                            (aexpr
                              (expr
                                (basicexpr
                                  (opexpr
                                    (prefixexpr
                                      (appexpr
                                        (atom
                                          (qidentifier
                                            (identifier
                                              (varid
                                                (id)))))))
                                    (qoperator
                                      (op))
                                    (prefixexpr
                                      (appexpr
                                        (atom
                                          (qidentifier
                                            (identifier
                                              (varid
                                                (id)))))))))))))))))))))))
    (topdecl
      (puredecl
        (fipmod
          (fipalloc))
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (opexpr
                          (prefixexpr
                            (appexpr
                              (atom
                                (qidentifier
                                  (identifier
                                    (varid
                                      (id))))))))))))))))))
    (topdecl
      (puredecl
        (fipmod
          (fipalloc
            (int)))
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (pparameters
            (pparameter
              (pattern
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))
            (pparameter
              (pattern
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id)))))))))
            (pparameter
              (pattern
                (identifier
                  (varid
                    (id))))
              (type
                (tarrow
                  (tatomic
                    (tbasic
                      (typeapp
                        (typecon
                          (varid
                            (id))))))))))
          (tresult
            (tatomic
              (tbasic
                (typeapp
                  (typecon
                    (varid
                      (id)))))))
          (block
            (statements
              (statement
                (basicexpr
                  (matchexpr
                    (expr
                      (basicexpr
                        (opexpr
                          (prefixexpr
                            (appexpr
                              (atom
                                (qidentifier
                                  (identifier
                                    (varid
                                      (id))))))))))
                    (matchrules
                      (matchrule
                        (patterns
                          (pattern
                            (qconstructor
                              (conid))))
                        (blockexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (appexpr
                                      (atom
                                        (qconstructor
                                          (conid))))
                                    (arguments
                                      (argument
                                        (expr
                                          (basicexpr
                                            (opexpr
                                              (prefixexpr
                                                (appexpr
                                                  (atom
                                                    (qconstructor
                                                      (conid)))))))))
                                      (argument
                                        (expr
                                          (basicexpr
                                            (opexpr
                                              (prefixexpr
                                                (appexpr
                                                  (atom
                                                    (qconstructor
                                                      (conid)))))))))
                                      (argument
                                        (expr
                                          (basicexpr
                                            (opexpr
                                              (prefixexpr
                                                (appexpr
                                                  (atom
                                                    (qidentifier
                                                      (identifier
                                                        (varid
                                                          (id)))))))))))
                                      (argument
                                        (expr
                                          (basicexpr
                                            (opexpr
                                              (prefixexpr
                                                (appexpr
                                                  (atom
                                                    (qidentifier
                                                      (identifier
                                                        (varid
                                                          (id)))))))))))
                                      (argument
                                        (expr
                                          (basicexpr
                                            (opexpr
                                              (prefixexpr
                                                (appexpr
                                                  (atom
                                                    (qconstructor
                                                      (conid)))))))))))))))))
                      (matchrule
                        (patterns
                          (pattern
                            (qconstructor
                              (conid))
                            (patargs
                              (patarg
                                (apattern
                                  (pattern
                                    (qconstructor
                                      (conid)))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id))))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id))))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id))))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id)))))))))
                        (blockexpr
                          (expr
                            (basicexpr
                              (ifexpr
                                (expr
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id)))))))
                                      (qoperator
                                        (op))
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id))))))))))
                                (blockexpr
                                  (expr
                                    (basicexpr
                                      (opexpr
                                        (prefixexpr
                                          (appexpr
                                            (appexpr
                                              (atom
                                                (qconstructor
                                                  (conid))))
                                            (arguments
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qconstructor
                                                              (conid)))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (appexpr
                                                            (atom
                                                              (qidentifier
                                                                (identifier
                                                                  (varid
                                                                    (id))))))
                                                          (arguments
                                                            (argument
                                                              (expr
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (atom
                                                                          (qidentifier
                                                                            (identifier
                                                                              (varid
                                                                                (id)))))))))))
                                                            (argument
                                                              (expr
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (atom
                                                                          (qidentifier
                                                                            (identifier
                                                                              (varid
                                                                                (id)))))))))))
                                                            (argument
                                                              (expr
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (atom
                                                                          (qidentifier
                                                                            (identifier
                                                                              (varid
                                                                                (id))))))))))))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id)))))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id)))))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id)))))))))))))))))))))))
                      (matchrule
                        (patterns
                          (pattern
                            (qconstructor
                              (conid))
                            (patargs
                              (patarg
                                (apattern
                                  (pattern
                                    (qconstructor
                                      (conid)))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id))))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id))))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id))))))
                              (patarg
                                (apattern
                                  (pattern
                                    (identifier
                                      (varid
                                        (id)))))))))
                        (blockexpr
                          (expr
                            (basicexpr
                              (ifexpr
                                (expr
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id)))))))
                                      (qoperator
                                        (op))
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id)))))))
                                      (qoperator
                                        (op))
                                      (prefixexpr
                                        (appexpr
                                          (appexpr
                                            (atom
                                              (qidentifier
                                                (identifier
                                                  (varid
                                                    (id))))))
                                          (arguments
                                            (argument
                                              (expr
                                                (basicexpr
                                                  (opexpr
                                                    (prefixexpr
                                                      (appexpr
                                                        (atom
                                                          (qidentifier
                                                            (identifier
                                                              (varid
                                                                (id)))))))))))))))))
                                (blockexpr
                                  (expr
                                    (basicexpr
                                      (opexpr
                                        (prefixexpr
                                          (appexpr
                                            (appexpr
                                              (atom
                                                (qidentifier
                                                  (identifier
                                                    (varid
                                                      (id))))))
                                            (arguments
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (appexpr
                                                            (atom
                                                              (qidentifier
                                                                (identifier
                                                                  (varid
                                                                    (id))))))
                                                          (arguments
                                                            (argument
                                                              (expr
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (atom
                                                                          (qidentifier
                                                                            (identifier
                                                                              (varid
                                                                                (id)))))))))))
                                                            (argument
                                                              (expr
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (atom
                                                                          (qidentifier
                                                                            (identifier
                                                                              (varid
                                                                                (id)))))))))))
                                                            (argument
                                                              (expr
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (atom
                                                                          (qidentifier
                                                                            (identifier
                                                                              (varid
                                                                                (id))))))))))))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id)))))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id)))))))))))
                                              (argument
                                                (expr
                                                  (basicexpr
                                                    (opexpr
                                                      (prefixexpr
                                                        (appexpr
                                                          (atom
                                                            (qidentifier
                                                              (identifier
                                                                (varid
                                                                  (id))))))))))))))))))))))))))))))))))

============================
block argument with handler
============================

fun to-pull-stream()
  Stream({
    handle g
      ctl yield(b)
        Just(1)
  })

pub type parse-result
  ParseOk

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (opexpr
                          (prefixexpr
                            (appexpr
                              (appexpr
                                (atom
                                  (qconstructor
                                    (conid))))
                              (arguments
                                (argument
                                  (expr
                                    (block
                                      (statements
                                        (statement
                                          (basicexpr
                                            (handlerexpr
                                              (expr
                                                (basicexpr
                                                  (opexpr
                                                    (prefixexpr
                                                      (appexpr
                                                        (atom
                                                          (qidentifier
                                                            (identifier
                                                              (varid
                                                                (id))))))))))
                                              (opclauses
                                                (opclausex
                                                  (opclause
                                                    (qidentifier
                                                      (identifier
                                                        (varid
                                                          (id))))
                                                    (opparams
                                                      (opparam
                                                        (paramid
                                                          (identifier
                                                            (varid
                                                              (id))))))
                                                    (bodyexpr
                                                      (blockexpr
                                                        (expr
                                                          (block
                                                            (statements
                                                              (statement
                                                                (basicexpr
                                                                  (opexpr
                                                                    (prefixexpr
                                                                      (appexpr
                                                                        (appexpr
                                                                          (atom
                                                                            (qconstructor
                                                                              (conid))))
                                                                        (arguments
                                                                          (argument
                                                                            (expr
                                                                              (basicexpr
                                                                                (opexpr
                                                                                  (prefixexpr
                                                                                    (appexpr
                                                                                      (atom
                                                                                        (literal
                                                                                          (int))))))))))))))))))))))))))))))))))))))))))))
    (topdecl
      (typedecl
        (typeid
          (varid
            (id)))
        (typebody
          (constructors
            (constructor
              (conid))))))))

============
match block
============

fun foo()
  match { bar }
    Baz -> 32

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (matchexpr
                          (expr
                            (block
                              (statements
                                (statement
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (qidentifier
                                              (identifier
                                                (varid
                                                  (id)))))))))))))
                          (matchrules
                            (matchrule
                              (patterns
                                (pattern
                                  (qconstructor
                                    (conid))))
                              (blockexpr
                                (expr
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (literal
                                              (int))))))))))))))))))))))))

=========================
block argument with mask
=========================

fun foo() {
  match mask<bar>
      baz
    Quux -> 32

---

(program
  (moduledecl)
  (modulebody
    (topdecl
      (puredecl
        (funid
          (identifier
            (varid
              (id))))
        (funbody
          (bodyexpr
            (blockexpr
              (expr
                (block
                  (statements
                    (statement
                      (basicexpr
                        (matchexpr
                          (expr
                            (basicexpr
                              (opexpr
                                (prefixexpr
                                  (appexpr
                                    (appexpr
                                      (atom
                                        (mask
                                          (tbasic
                                            (typeapp
                                              (typecon
                                                (varid
                                                  (id))))))))
                                    (block
                                      (statements
                                        (statement
                                          (basicexpr
                                            (opexpr
                                              (prefixexpr
                                                (appexpr
                                                  (atom
                                                    (qidentifier
                                                      (identifier
                                                        (varid
                                                          (id)))))))))))))))))
                          (matchrules
                            (matchrule
                              (patterns
                                (pattern
                                  (qconstructor
                                    (conid))))
                              (blockexpr
                                (expr
                                  (basicexpr
                                    (opexpr
                                      (prefixexpr
                                        (appexpr
                                          (atom
                                            (literal
                                              (int))))))))))))))))))))))))
