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.
EAppid 0.
EBindinglet 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.
EPrimAppMiniAst.primitive.
EForallforall a.exp. Such type variables can be used
as rigid variables in type annotations, as in:
let id = forall a. (\x. x : a -> a)
EExistexists a.exp. Such type variables can be used
as rigid variables in type annotations, as in:
let id = exists a. (\x. x : a -> a)
ETypeConstraintlet id = \x. x : int -> int.
EDConCons 0 Nil is the application
of the data constructor Cons to 0 and Nil.
EDMatchclause'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.
ERecordAccessexpression.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 }.
ERecordUpdateexpression.l <- expression.
EAssertFalseassert 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 |
DAlgebraictype 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 |