module MiniAst:sig
..end
Abstract syntax trees are generated by the parser defined in
MiniSyntacticAnalysis
.
typeprogram =
binding list
program
in the Mini language is a sequence of toplevel bindings.type
binding =
| |
BindValue of |
| |
BindRecValue of |
| |
TypeDec of |
binding
is
MiniAst.value_definition
):
let v1 = exp1 and v2 = exp2 and ... and vn = expn v
let rec v1 = exp1 and v2 = exp2 and ... and vn = expn v
MiniAst.type_definition
).type
expression =
| |
EVar of |
| |
ELambda of |
| |
EApp of |
| |
EBinding of |
| |
EPrimApp of |
| |
EForall of |
| |
EExists of |
| |
ETypeConstraint of |
| |
EDCon of |
| |
EMatch of |
| |
ERecordEmpty of |
| |
ERecordAccess of |
| |
ERecordExtend of |
| |
ERecordUpdate of |
| |
EAssertFalse of |
expression
in Mini. Here is a description of the abstract
syntax tree's nodes with their denotation in the concrete
syntax:
EVar
ELambda
\pattern. exp
. For
example, \x. x + 1
is the successor function.
EApp
id 0
.
EBinding
let id = \x.x in id 0
. There is a syntactic
sugar that expands: let identifier pat1 ... patn = exp
into
let identifier = \pat1. ... \patn. exp
. Furthermore, a
set of rigid universally quantified type variables can be
introduced in the typing scope using the syntax:
let forall a1 ... an. id = exp
.
The user can refer to a1 ... an
in exp
and id
.
EPrimApp
MiniAst.primitive
.
EForall
forall a.exp
. Such type variables can be used
as rigid variables in type annotations, as in:
let id = forall a. (\x. x : a -> a)
EExist
exists a.exp
. Such type variables can be used
as rigid variables in type annotations, as in:
let id = exists a. (\x. x : a -> a)
ETypeConstraint
let id = \x. x : int -> int
.
EDCon
Cons 0 Nil
is the application
of the data constructor Cons
to 0
and Nil
.
EDMatch
clause
's patterns. The syntax of matching in Mini is
match exp with clause_1 | clause_2 | ... | clause_n end
For instance, the following function computes the length of a list:
let rec len l =
match exp with
Nil => 0
| Cons x xs => 1 + len xs
end
ERecordEmpty
{}
defines an empty record.
ERecordAccess
expression.l
is an access the label l
of the
record expression.
ERecordExtend
{ l_1 = exp_1 and l_2 = exp_2 and ... and l_n = exp_n }
.
ERecordUpdate
expression.l <- expression
.
EAssertFalse
assert false
to express
assumed dead code branches.typename =
Constraint.sname
=
| |
SName of |
typetname =
MultiEquation.tname
type
dname =
| |
DName of |
typelname =
CoreAlgebra.lname
type
primitive =
| |
PIntegerConstant of |
(* | Integer constant. | *) |
| |
PCharConstant of |
(* | Character constant. | *) |
| |
PUnit |
(* | Unit constant. | *) |
typeclause =
Positions.position * pattern * expression
typerecord_binding =
lname * expression
typetype_declaration =
Positions.position * kind * tname * type_definition
type
type_definition =
| |
DAlgebraic of |
DAlgebraic
type id : kind =
forall a1 ... an.
K1 : typ
| ...
| KN : typ
For example, here is the definition of polymorphic lists:
type list : * -> * = forall a.
Nil : list a
| Cons : a -> list a -> list a
typevalue_definition =
Positions.position * tname list * pattern *
expression
type
pattern =
| |
PVar of |
| |
PWildcard of |
| |
PAlias of |
| |
PTypeConstraint of |
| |
PPrimitive of |
| |
PData of |
| |
PAnd of |
| |
POr of |
type
kind =
| |
KStar |
| |
KTimes of |
| |
KArrow of |
| |
KEmptyRow |
type
typ =
| |
TypVar of |
| |
TypApp of |
| |
TypRowCons of |
| |
TypRowUniform of |