ocaml/parsing/parsetree.mli

837 lines
24 KiB
OCaml

(***********************************************************************)
(* *)
(* OCaml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. All rights reserved. This file is distributed *)
(* under the terms of the Q Public License version 1.0. *)
(* *)
(***********************************************************************)
(** Abstract syntax tree produced by parsing *)
open Asttypes
(** {2 Extension points} *)
type attribute = string loc * payload
(* [@id ARG]
[@@id ARG]
Metadata containers passed around within the AST.
The compiler ignores unknown attributes.
*)
and extension = string loc * payload
(* [%id ARG]
[%%id ARG]
Sub-language placeholder -- rejected by the typechecker.
*)
and attributes = attribute list
and payload =
| PStr of structure
| PTyp of core_type (* : T *)
| PPat of pattern * expression option (* ? P or ? P when E *)
(** {2 Core language} *)
(* Type expressions *)
and core_type =
{
ptyp_desc: core_type_desc;
ptyp_loc: Location.t;
ptyp_attributes: attributes; (* ... [@id1] [@id2] *)
}
and core_type_desc =
| Ptyp_any
(* _ *)
| Ptyp_var of string
(* 'a *)
| Ptyp_arrow of arg_label * core_type * core_type
(* T1 -> T2 Simple
~l:T1 -> T2 Labelled
?l:T1 -> T2 Otional
*)
| Ptyp_tuple of core_type list
(* T1 * ... * Tn
Invariant: n >= 2
*)
| Ptyp_constr of Longident.t loc * core_type list
(* tconstr
T tconstr
(T1, ..., Tn) tconstr
*)
| Ptyp_object of (string * attributes * core_type) list * closed_flag
(* < l1:T1; ...; ln:Tn > (flag = Closed)
< l1:T1; ...; ln:Tn; .. > (flag = Open)
*)
| Ptyp_class of Longident.t loc * core_type list
(* #tconstr
T #tconstr
(T1, ..., Tn) #tconstr
*)
| Ptyp_alias of core_type * string
(* T as 'a *)
| Ptyp_variant of row_field list * closed_flag * label list option
(* [ `A|`B ] (flag = Closed; labels = None)
[> `A|`B ] (flag = Open; labels = None)
[< `A|`B ] (flag = Closed; labels = Some [])
[< `A|`B > `X `Y ](flag = Closed; labels = Some ["X";"Y"])
*)
| Ptyp_poly of string list * core_type
(* 'a1 ... 'an. T
Can only appear in the following context:
- As the core_type of a Ppat_constraint node corresponding
to a constraint on a let-binding: let x : 'a1 ... 'an. T
= e ...
- Under Cfk_virtual for methods (not values).
- As the core_type of a Pctf_method node.
- As the core_type of a Pexp_poly node.
- As the pld_type field of a label_declaration.
- As a core_type of a Ptyp_object node.
*)
| Ptyp_package of package_type
(* (module S) *)
| Ptyp_extension of extension
(* [%id] *)
and package_type = Longident.t loc * (Longident.t loc * core_type) list
(*
(module S)
(module S with type t1 = T1 and ... and tn = Tn)
*)
and row_field =
| Rtag of label * attributes * bool * core_type list
(* [`A] ( true, [] )
[`A of T] ( false, [T] )
[`A of T1 & .. & Tn] ( false, [T1;...Tn] )
[`A of & T1 & .. & Tn] ( true, [T1;...Tn] )
- The 2nd field is true if the tag contains a
constant (empty) constructor.
- '&' occurs when several types are used for the same constructor
(see 4.2 in the manual)
- TODO: switch to a record representation, and keep location
*)
| Rinherit of core_type
(* [ T ] *)
(* Patterns *)
and pattern =
{
ppat_desc: pattern_desc;
ppat_loc: Location.t;
ppat_attributes: attributes; (* ... [@id1] [@id2] *)
}
and pattern_desc =
| Ppat_any
(* _ *)
| Ppat_var of string loc
(* x *)
| Ppat_alias of pattern * string loc
(* P as 'a *)
| Ppat_constant of constant
(* 1, 'a', "true", 1.0, 1l, 1L, 1n *)
| Ppat_interval of constant * constant
(* 'a'..'z'
Other forms of interval are recognized by the parser
but rejected by the type-checker. *)
| Ppat_tuple of pattern list
(* (P1, ..., Pn)
Invariant: n >= 2
*)
| Ppat_construct of Longident.t loc * pattern option
(* C None
C P Some P
C (P1, ..., Pn) Some (Ppat_tuple [P1; ...; Pn])
*)
| Ppat_variant of label * pattern option
(* `A (None)
`A P (Some P)
*)
| Ppat_record of (Longident.t loc * pattern) list * closed_flag
(* { l1=P1; ...; ln=Pn } (flag = Closed)
{ l1=P1; ...; ln=Pn; _} (flag = Open)
Invariant: n > 0
*)
| Ppat_array of pattern list
(* [| P1; ...; Pn |] *)
| Ppat_or of pattern * pattern
(* P1 | P2 *)
| Ppat_constraint of pattern * core_type
(* (P : T) *)
| Ppat_type of Longident.t loc
(* #tconst *)
| Ppat_lazy of pattern
(* lazy P *)
| Ppat_unpack of string loc
(* (module P)
Note: (module P : S) is represented as
Ppat_constraint(Ppat_unpack, Ptyp_package)
*)
| Ppat_exception of pattern
(* exception P *)
| Ppat_extension of extension
(* [%id] *)
(* Value expressions *)
and expression =
{
pexp_desc: expression_desc;
pexp_loc: Location.t;
pexp_attributes: attributes; (* ... [@id1] [@id2] *)
}
and expression_desc =
| Pexp_ident of Longident.t loc
(* x
M.x
*)
| Pexp_constant of constant
(* 1, 'a', "true", 1.0, 1l, 1L, 1n *)
| Pexp_let of rec_flag * value_binding list * expression
(* let P1 = E1 and ... and Pn = EN in E (flag = Nonrecursive)
let rec P1 = E1 and ... and Pn = EN in E (flag = Recursive)
*)
| Pexp_function of case list
(* function P1 -> E1 | ... | Pn -> En *)
| Pexp_fun of arg_label * expression option * pattern * expression
(* fun P -> E1 (Simple, None)
fun ~l:P -> E1 (Labelled l, None)
fun ?l:P -> E1 (Optional l, None)
fun ?l:(P = E0) -> E1 (Optional l, Some E0)
Notes:
- If E0 is provided, only Optional is allowed.
- "fun P1 P2 .. Pn -> E1" is represented as nested Pexp_fun.
- "let f P = E" is represented using Pexp_fun.
*)
| Pexp_apply of expression * (arg_label * expression) list
(* E0 ~l1:E1 ... ~ln:En
li can be empty (non labeled argument) or start with '?'
(optional argument).
Invariant: n > 0
*)
| Pexp_match of expression * case list
(* match E0 with P1 -> E1 | ... | Pn -> En *)
| Pexp_try of expression * case list
(* try E0 with P1 -> E1 | ... | Pn -> En *)
| Pexp_tuple of expression list
(* (E1, ..., En)
Invariant: n >= 2
*)
| Pexp_construct of Longident.t loc * expression option
(* C None
C E Some E
C (E1, ..., En) Some (Pexp_tuple[E1;...;En])
*)
| Pexp_variant of label * expression option
(* `A (None)
`A E (Some E)
*)
| Pexp_record of (Longident.t loc * expression) list * expression option
(* { l1=P1; ...; ln=Pn } (None)
{ E0 with l1=P1; ...; ln=Pn } (Some E0)
Invariant: n > 0
*)
| Pexp_field of expression * Longident.t loc
(* E.l *)
| Pexp_setfield of expression * Longident.t loc * expression
(* E1.l <- E2 *)
| Pexp_array of expression list
(* [| E1; ...; En |] *)
| Pexp_ifthenelse of expression * expression * expression option
(* if E1 then E2 else E3 *)
| Pexp_sequence of expression * expression
(* E1; E2 *)
| Pexp_while of expression * expression
(* while E1 do E2 done *)
| Pexp_for of
pattern * expression * expression * direction_flag * expression
(* for i = E1 to E2 do E3 done (flag = Upto)
for i = E1 downto E2 do E3 done (flag = Downto)
*)
| Pexp_constraint of expression * core_type
(* (E : T) *)
| Pexp_coerce of expression * core_type option * core_type
(* (E :> T) (None, T)
(E : T0 :> T) (Some T0, T)
*)
| Pexp_send of expression * string
(* E # m *)
| Pexp_new of Longident.t loc
(* new M.c *)
| Pexp_setinstvar of string loc * expression
(* x <- 2 *)
| Pexp_override of (string loc * expression) list
(* {< x1 = E1; ...; Xn = En >} *)
| Pexp_letmodule of string loc * module_expr * expression
(* let module M = ME in E *)
| Pexp_assert of expression
(* assert E
Note: "assert false" is treated in a special way by the
type-checker. *)
| Pexp_lazy of expression
(* lazy E *)
| Pexp_poly of expression * core_type option
(* Used for method bodies.
Can only be used as the expression under Cfk_concrete
for methods (not values). *)
| Pexp_object of class_structure
(* object ... end *)
| Pexp_newtype of string * expression
(* fun (type t) -> E *)
| Pexp_pack of module_expr
(* (module ME)
(module ME : S) is represented as
Pexp_constraint(Pexp_pack, Ptyp_package S) *)
| Pexp_open of override_flag * Longident.t loc * expression
(* let open M in E
let! open M in E
*)
| Pexp_extension of extension
(* [%id] *)
and case = (* (P -> E) or (P when E0 -> E) *)
{
pc_lhs: pattern;
pc_guard: expression option;
pc_rhs: expression;
}
(* Value descriptions *)
and value_description =
{
pval_name: string loc;
pval_type: core_type;
pval_prim: string list;
pval_attributes: attributes; (* ... [@@id1] [@@id2] *)
pval_loc: Location.t;
}
(*
val x: T (prim = [])
external x: T = "s1" ... "sn" (prim = ["s1";..."sn"])
*)
(* Type declarations *)
and type_declaration =
{
ptype_name: string loc;
ptype_params: (core_type * variance) list;
(* ('a1,...'an) t; None represents _*)
ptype_cstrs: (core_type * core_type * Location.t) list;
(* ... constraint T1=T1' ... constraint Tn=Tn' *)
ptype_kind: type_kind;
ptype_private: private_flag; (* = private ... *)
ptype_manifest: core_type option; (* = T *)
ptype_attributes: attributes; (* ... [@@id1] [@@id2] *)
ptype_loc: Location.t;
}
(*
type t (abstract, no manifest)
type t = T0 (abstract, manifest=T0)
type t = C of T | ... (variant, no manifest)
type t = T0 = C of T | ... (variant, manifest=T0)
type t = {l: T; ...} (record, no manifest)
type t = T0 = {l : T; ...} (record, manifest=T0)
type t = .. (open, no manifest)
*)
and type_kind =
| Ptype_abstract
| Ptype_variant of constructor_declaration list
(* Invariant: non-empty list *)
| Ptype_record of label_declaration list
(* Invariant: non-empty list *)
| Ptype_open
and label_declaration =
{
pld_name: string loc;
pld_mutable: mutable_flag;
pld_type: core_type;
pld_loc: Location.t;
pld_attributes: attributes; (* l [@id1] [@id2] : T *)
}
(* { ...; l: T; ... } (mutable=Immutable)
{ ...; mutable l: T; ... } (mutable=Mutable)
Note: T can be a Ptyp_poly.
*)
and constructor_declaration =
{
pcd_name: string loc;
pcd_args: constructor_arguments;
pcd_res: core_type option;
pcd_loc: Location.t;
pcd_attributes: attributes; (* C [@id1] [@id2] of ... *)
}
and constructor_arguments =
| Pcstr_tuple of core_type list
| Pcstr_record of label_declaration list
(*
| C of T1 * ... * Tn (res = None, args = Pcstr_tuple [])
| C: T0 (res = Some T0, args = [])
| C: T1 * ... * Tn -> T0 (res = Some T0, args = Pcstr_tuple)
| C of {...} (res = None, args = Pcstr_record)
| C: {...} -> T0 (res = Some T0, args = Pcstr_record)
| C of {...} as t (res = None, args = Pcstr_record)
*)
and type_extension =
{
ptyext_path: Longident.t loc;
ptyext_params: (core_type * variance) list;
ptyext_constructors: extension_constructor list;
ptyext_private: private_flag;
ptyext_attributes: attributes; (* ... [@@id1] [@@id2] *)
}
(*
type t += ...
*)
and extension_constructor =
{
pext_name: string loc;
pext_kind : extension_constructor_kind;
pext_loc : Location.t;
pext_attributes: attributes; (* C [@id1] [@id2] of ... *)
}
and extension_constructor_kind =
Pext_decl of constructor_arguments * core_type option
(*
| C of T1 * ... * Tn ([T1; ...; Tn], None)
| C: T0 ([], Some T0)
| C: T1 * ... * Tn -> T0 ([T1; ...; Tn], Some T0)
*)
| Pext_rebind of Longident.t loc
(*
| C = D
*)
(** {2 Class language} *)
(* Type expressions for the class language *)
and class_type =
{
pcty_desc: class_type_desc;
pcty_loc: Location.t;
pcty_attributes: attributes; (* ... [@id1] [@id2] *)
}
and class_type_desc =
| Pcty_constr of Longident.t loc * core_type list
(* c
['a1, ..., 'an] c *)
| Pcty_signature of class_signature
(* object ... end *)
| Pcty_arrow of arg_label * core_type * class_type
(* T -> CT Simple
~l:T -> CT Labelled l
?l:T -> CT Optional l
*)
| Pcty_extension of extension
(* [%id] *)
and class_signature =
{
pcsig_self: core_type;
pcsig_fields: class_type_field list;
}
(* object('selfpat) ... end
object ... end (self = Ptyp_any)
*)
and class_type_field =
{
pctf_desc: class_type_field_desc;
pctf_loc: Location.t;
pctf_attributes: attributes; (* ... [@@id1] [@@id2] *)
}
and class_type_field_desc =
| Pctf_inherit of class_type
(* inherit CT *)
| Pctf_val of (string * mutable_flag * virtual_flag * core_type)
(* val x: T *)
| Pctf_method of (string * private_flag * virtual_flag * core_type)
(* method x: T
Note: T can be a Ptyp_poly.
*)
| Pctf_constraint of (core_type * core_type)
(* constraint T1 = T2 *)
| Pctf_attribute of attribute
(* [@@@id] *)
| Pctf_extension of extension
(* [%%id] *)
and 'a class_infos =
{
pci_virt: virtual_flag;
pci_params: (core_type * variance) list;
pci_name: string loc;
pci_expr: 'a;
pci_loc: Location.t;
pci_attributes: attributes; (* ... [@@id1] [@@id2] *)
}
(* class c = ...
class ['a1,...,'an] c = ...
class virtual c = ...
Also used for "class type" declaration.
*)
and class_description = class_type class_infos
and class_type_declaration = class_type class_infos
(* Value expressions for the class language *)
and class_expr =
{
pcl_desc: class_expr_desc;
pcl_loc: Location.t;
pcl_attributes: attributes; (* ... [@id1] [@id2] *)
}
and class_expr_desc =
| Pcl_constr of Longident.t loc * core_type list
(* c
['a1, ..., 'an] c *)
| Pcl_structure of class_structure
(* object ... end *)
| Pcl_fun of arg_label * expression option * pattern * class_expr
(* fun P -> CE (Simple, None)
fun ~l:P -> CE (Labelled l, None)
fun ?l:P -> CE (Optional l, None)
fun ?l:(P = E0) -> CE (Optional l, Some E0)
*)
| Pcl_apply of class_expr * (arg_label * expression) list
(* CE ~l1:E1 ... ~ln:En
li can be empty (non labeled argument) or start with '?'
(optional argument).
Invariant: n > 0
*)
| Pcl_let of rec_flag * value_binding list * class_expr
(* let P1 = E1 and ... and Pn = EN in CE (flag = Nonrecursive)
let rec P1 = E1 and ... and Pn = EN in CE (flag = Recursive)
*)
| Pcl_constraint of class_expr * class_type
(* (CE : CT) *)
| Pcl_extension of extension
(* [%id] *)
and class_structure =
{
pcstr_self: pattern;
pcstr_fields: class_field list;
}
(* object(selfpat) ... end
object ... end (self = Ppat_any)
*)
and class_field =
{
pcf_desc: class_field_desc;
pcf_loc: Location.t;
pcf_attributes: attributes; (* ... [@@id1] [@@id2] *)
}
and class_field_desc =
| Pcf_inherit of override_flag * class_expr * string option
(* inherit CE
inherit CE as x
inherit! CE
inherit! CE as x
*)
| Pcf_val of (string loc * mutable_flag * class_field_kind)
(* val x = E
val virtual x: T
*)
| Pcf_method of (string loc * private_flag * class_field_kind)
(* method x = E (E can be a Pexp_poly)
method virtual x: T (T can be a Ptyp_poly)
*)
| Pcf_constraint of (core_type * core_type)
(* constraint T1 = T2 *)
| Pcf_initializer of expression
(* initializer E *)
| Pcf_attribute of attribute
(* [@@@id] *)
| Pcf_extension of extension
(* [%%id] *)
and class_field_kind =
| Cfk_virtual of core_type
| Cfk_concrete of override_flag * expression
and class_declaration = class_expr class_infos
(** {2 Module language} *)
(* Type expressions for the module language *)
and module_type =
{
pmty_desc: module_type_desc;
pmty_loc: Location.t;
pmty_attributes: attributes; (* ... [@id1] [@id2] *)
}
and module_type_desc =
| Pmty_ident of Longident.t loc
(* S *)
| Pmty_signature of signature
(* sig ... end *)
| Pmty_functor of string loc * module_type option * module_type
(* functor(X : MT1) -> MT2 *)
| Pmty_with of module_type * with_constraint list
(* MT with ... *)
| Pmty_typeof of module_expr
(* module type of ME *)
| Pmty_extension of extension
(* [%id] *)
| Pmty_alias of Longident.t loc
(* (module M) *)
and signature = signature_item list
and signature_item =
{
psig_desc: signature_item_desc;
psig_loc: Location.t;
}
and signature_item_desc =
| Psig_value of value_description
(*
val x: T
external x: T = "s1" ... "sn"
*)
| Psig_type of rec_flag * type_declaration list
(* type t1 = ... and ... and tn = ... *)
| Psig_typext of type_extension
(* type t1 += ... *)
| Psig_exception of extension_constructor
(* exception C of T *)
| Psig_module of module_declaration
(* module X : MT *)
| Psig_recmodule of module_declaration list
(* module rec X1 : MT1 and ... and Xn : MTn *)
| Psig_modtype of module_type_declaration
(* module type S = MT
module type S *)
| Psig_open of open_description
(* open X *)
| Psig_include of include_description
(* include MT *)
| Psig_class of class_description list
(* class c1 : ... and ... and cn : ... *)
| Psig_class_type of class_type_declaration list
(* class type ct1 = ... and ... and ctn = ... *)
| Psig_attribute of attribute
(* [@@@id] *)
| Psig_extension of extension * attributes
(* [%%id] *)
and module_declaration =
{
pmd_name: string loc;
pmd_type: module_type;
pmd_attributes: attributes; (* ... [@@id1] [@@id2] *)
pmd_loc: Location.t;
}
(* S : MT *)
and module_type_declaration =
{
pmtd_name: string loc;
pmtd_type: module_type option;
pmtd_attributes: attributes; (* ... [@@id1] [@@id2] *)
pmtd_loc: Location.t;
}
(* S = MT
S (abstract module type declaration, pmtd_type = None)
*)
and open_description =
{
popen_lid: Longident.t loc;
popen_override: override_flag;
popen_loc: Location.t;
popen_attributes: attributes;
}
(* open! X - popen_override = Override (silences the 'used identifier
shadowing' warning)
open X - popen_override = Fresh
*)
and 'a include_infos =
{
pincl_mod: 'a;
pincl_loc: Location.t;
pincl_attributes: attributes;
}
and include_description = module_type include_infos
(* include MT *)
and include_declaration = module_expr include_infos
(* include ME *)
and with_constraint =
| Pwith_type of Longident.t loc * type_declaration
(* with type X.t = ...
Note: the last component of the longident must match
the name of the type_declaration. *)
| Pwith_module of Longident.t loc * Longident.t loc
(* with module X.Y = Z *)
| Pwith_typesubst of type_declaration
(* with type t := ... *)
| Pwith_modsubst of string loc * Longident.t loc
(* with module X := Z *)
(* Value expressions for the module language *)
and module_expr =
{
pmod_desc: module_expr_desc;
pmod_loc: Location.t;
pmod_attributes: attributes; (* ... [@id1] [@id2] *)
}
and module_expr_desc =
| Pmod_ident of Longident.t loc
(* X *)
| Pmod_structure of structure
(* struct ... end *)
| Pmod_functor of string loc * module_type option * module_expr
(* functor(X : MT1) -> ME *)
| Pmod_apply of module_expr * module_expr
(* ME1(ME2) *)
| Pmod_constraint of module_expr * module_type
(* (ME : MT) *)
| Pmod_unpack of expression
(* (val E) *)
| Pmod_extension of extension
(* [%id] *)
and structure = structure_item list
and structure_item =
{
pstr_desc: structure_item_desc;
pstr_loc: Location.t;
}
and structure_item_desc =
| Pstr_eval of expression * attributes
(* E *)
| Pstr_value of rec_flag * value_binding list
(* let P1 = E1 and ... and Pn = EN (flag = Nonrecursive)
let rec P1 = E1 and ... and Pn = EN (flag = Recursive)
*)
| Pstr_primitive of value_description
(* val x: T
external x: T = "s1" ... "sn" *)
| Pstr_type of rec_flag * type_declaration list
(* type t1 = ... and ... and tn = ... *)
| Pstr_typext of type_extension
(* type t1 += ... *)
| Pstr_exception of extension_constructor
(* exception C of T
exception C = M.X *)
| Pstr_module of module_binding
(* module X = ME *)
| Pstr_recmodule of module_binding list
(* module rec X1 = ME1 and ... and Xn = MEn *)
| Pstr_modtype of module_type_declaration
(* module type S = MT *)
| Pstr_open of open_description
(* open X *)
| Pstr_class of class_declaration list
(* class c1 = ... and ... and cn = ... *)
| Pstr_class_type of class_type_declaration list
(* class type ct1 = ... and ... and ctn = ... *)
| Pstr_include of include_declaration
(* include ME *)
| Pstr_attribute of attribute
(* [@@@id] *)
| Pstr_extension of extension * attributes
(* [%%id] *)
and value_binding =
{
pvb_pat: pattern;
pvb_expr: expression;
pvb_attributes: attributes;
pvb_loc: Location.t;
}
and module_binding =
{
pmb_name: string loc;
pmb_expr: module_expr;
pmb_attributes: attributes;
pmb_loc: Location.t;
}
(* X = ME *)
(** {2 Toplevel} *)
(* Toplevel phrases *)
type toplevel_phrase =
| Ptop_def of structure
| Ptop_dir of string * directive_argument
(* #use, #load ... *)
and directive_argument =
| Pdir_none
| Pdir_string of string
| Pdir_int of int
| Pdir_ident of Longident.t
| Pdir_bool of bool