diff options
-rw-r--r-- | bytecomp/translcore.ml | 4 | ||||
-rw-r--r-- | camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml | 2 | ||||
-rw-r--r-- | camlp4/boot/Camlp4.ml | 2 | ||||
-rw-r--r-- | experimental/frisch/extension_points.txt | 4 | ||||
-rw-r--r-- | parsing/ast_helper.ml | 23 | ||||
-rw-r--r-- | parsing/ast_helper.mli | 18 | ||||
-rw-r--r-- | parsing/ast_mapper.ml | 37 | ||||
-rw-r--r-- | parsing/parser.mly | 2 | ||||
-rw-r--r-- | parsing/parsetree.mli | 8 | ||||
-rw-r--r-- | parsing/pprintast.ml | 3 | ||||
-rw-r--r-- | parsing/printast.ml | 4 | ||||
-rw-r--r-- | tools/depend.ml | 1 | ||||
-rw-r--r-- | tools/ocamlprof.ml | 1 | ||||
-rw-r--r-- | tools/untypeast.ml | 1 | ||||
-rw-r--r-- | typing/printtyped.ml | 1 | ||||
-rw-r--r-- | typing/typeclass.ml | 35 | ||||
-rw-r--r-- | typing/typeclass.mli | 1 | ||||
-rw-r--r-- | typing/typecore.ml | 1 | ||||
-rw-r--r-- | typing/typedtree.ml | 11 | ||||
-rw-r--r-- | typing/typedtree.mli | 11 |
20 files changed, 111 insertions, 59 deletions
diff --git a/bytecomp/translcore.ml b/bytecomp/translcore.ml index 3f541f4a8..d621221f5 100644 --- a/bytecomp/translcore.ml +++ b/bytecomp/translcore.ml @@ -869,7 +869,9 @@ and transl_exp0 e = { cl_desc = Tcl_structure cs; cl_loc = e.exp_loc; cl_type = Cty_signature cty; - cl_env = e.exp_env } + cl_env = e.exp_env; + cl_attributes = []; + } and transl_list expr_list = List.map transl_exp expr_list diff --git a/camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml b/camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml index 12cd57698..459002293 100644 --- a/camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml +++ b/camlp4/Camlp4/Struct/Camlp4Ast2OCamlAst.ml @@ -68,7 +68,7 @@ module Make (Ast : Sig.Camlp4Ast) = struct value mkmod loc d = {pmod_desc = d; pmod_loc = mkloc loc; pmod_attributes = []}; value mkstr loc d = {pstr_desc = d; pstr_loc = mkloc loc}; value mkcty loc d = {pcty_desc = d; pcty_loc = mkloc loc}; - value mkcl loc d = {pcl_desc = d; pcl_loc = mkloc loc}; + value mkcl loc d = {pcl_desc = d; pcl_loc = mkloc loc; pcl_attributes = []}; value mkcf loc d = { pcf_desc = d; pcf_loc = mkloc loc; pcf_attributes = []}; value mkctf loc d = { pctf_desc = d; pctf_loc = mkloc loc; pctf_attributes = []}; diff --git a/camlp4/boot/Camlp4.ml b/camlp4/boot/Camlp4.ml index 4ae04dac8..2ce1832ce 100644 --- a/camlp4/boot/Camlp4.ml +++ b/camlp4/boot/Camlp4.ml @@ -14187,7 +14187,7 @@ module Struct = let mkcty loc d = { pcty_desc = d; pcty_loc = mkloc loc; } - let mkcl loc d = { pcl_desc = d; pcl_loc = mkloc loc; } + let mkcl loc d = { pcl_desc = d; pcl_loc = mkloc loc; pcl_attributes = []} let mkcf loc d = { pcf_desc = d; pcf_loc = mkloc loc; pcf_attributes = [] } diff --git a/experimental/frisch/extension_points.txt b/experimental/frisch/extension_points.txt index 41b5a4cd5..33d904f8e 100644 --- a/experimental/frisch/extension_points.txt +++ b/experimental/frisch/extension_points.txt @@ -13,7 +13,7 @@ a dots (whitespaces are allowed around the dots). In the Parsetree, the identifier is represented as a single string (without spaces). Attributes on expressions, type expressions, module expressions, module type expressions, -patterns (TODO: class expressions, class type expressions): +patterns, class expressions (TODO: class type expressions): ... [@id expr] @@ -84,7 +84,7 @@ expression (written expr below). Two syntaxes exist for extension node: As expressions, type expressions, module expressions, module type expressions, -patterns (TODO: class expressions, class type expressions): +patterns, class expressions (TODO: class type expressions): [%id expr] diff --git a/parsing/ast_helper.ml b/parsing/ast_helper.ml index d87353e13..e5720bbf3 100644 --- a/parsing/ast_helper.ml +++ b/parsing/ast_helper.ml @@ -162,14 +162,21 @@ module Str = struct end module Cl = struct - let mk ?(loc = Location.none) d = {pcl_desc = d; pcl_loc = loc} - - let constr ?loc a b = mk ?loc (Pcl_constr (a, b)) - let structure ?loc a = mk ?loc (Pcl_structure a) - let fun_ ?loc a b c d = mk ?loc (Pcl_fun (a, b, c, d)) - let apply ?loc a b = mk ?loc (Pcl_apply (a, b)) - let let_ ?loc a b c = mk ?loc (Pcl_let (a, b, c)) - let constraint_ ?loc a b = mk ?loc (Pcl_constraint (a, b)) + let mk ?(loc = Location.none) ?(attrs = []) d = + { + pcl_desc = d; + pcl_loc = loc; + pcl_attributes = attrs; + } + let attr d a = {d with pcl_attributes = d.pcl_attributes @ [a]} + + let constr ?loc ?attrs a b = mk ?loc ?attrs (Pcl_constr (a, b)) + let structure ?loc ?attrs a = mk ?loc ?attrs (Pcl_structure a) + let fun_ ?loc ?attrs a b c d = mk ?loc ?attrs (Pcl_fun (a, b, c, d)) + let apply ?loc ?attrs a b = mk ?loc ?attrs (Pcl_apply (a, b)) + let let_ ?loc ?attrs a b c = mk ?loc ?attrs (Pcl_let (a, b, c)) + let constraint_ ?loc ?attrs a b = mk ?loc ?attrs (Pcl_constraint (a, b)) + let extension ?loc ?attrs a = mk ?loc ?attrs (Pcl_extension a) end module Cty = struct diff --git a/parsing/ast_helper.mli b/parsing/ast_helper.mli index 4e134982b..5dc4714f3 100644 --- a/parsing/ast_helper.mli +++ b/parsing/ast_helper.mli @@ -160,14 +160,16 @@ module Str: end module Cl: sig - val mk: ?loc:Location.t -> class_expr_desc -> class_expr - - val constr: ?loc:Location.t -> Longident.t loc -> core_type list -> class_expr - val structure: ?loc:Location.t -> class_structure -> class_expr - val fun_: ?loc:Location.t -> label -> expression option -> pattern -> class_expr -> class_expr - val apply: ?loc:Location.t -> class_expr -> (label * expression) list -> class_expr - val let_: ?loc:Location.t -> rec_flag -> (pattern * expression) list -> class_expr -> class_expr - val constraint_: ?loc:Location.t -> class_expr -> class_type -> class_expr + val mk: ?loc:Location.t -> ?attrs:attribute list -> class_expr_desc -> class_expr + val attr: class_expr -> attribute -> class_expr + + val constr: ?loc:Location.t -> ?attrs:attribute list -> Longident.t loc -> core_type list -> class_expr + val structure: ?loc:Location.t -> ?attrs:attribute list -> class_structure -> class_expr + val fun_: ?loc:Location.t -> ?attrs:attribute list -> label -> expression option -> pattern -> class_expr -> class_expr + val apply: ?loc:Location.t -> ?attrs:attribute list -> class_expr -> (label * expression) list -> class_expr + val let_: ?loc:Location.t -> ?attrs:attribute list -> rec_flag -> (pattern * expression) list -> class_expr -> class_expr + val constraint_: ?loc:Location.t -> ?attrs:attribute list -> class_expr -> class_type -> class_expr + val extension: ?loc:Location.t -> ?attrs:attribute list -> extension -> class_expr end module Cty: sig diff --git a/parsing/ast_mapper.ml b/parsing/ast_mapper.ml index 5656fec9a..36773b802 100644 --- a/parsing/ast_mapper.ml +++ b/parsing/ast_mapper.ml @@ -87,14 +87,14 @@ module CT = struct (sub # typ t) (sub # class_type ct) - let map_field sub {pctf_desc = desc; pctf_loc = loc} = + let map_field sub {pctf_desc = desc; pctf_loc = loc; pctf_attributes = attrs} = let open Ctf in let loc = sub # location loc in match desc with - | Pctf_inherit ct -> inherit_ ~loc (sub # class_type ct) - | Pctf_val (s, m, v, t) -> val_ ~loc s m v (sub # typ t) - | Pctf_method (s, p, v, t) -> method_ ~loc s p v (sub # typ t) - | Pctf_constraint (t1, t2) -> constraint_ ~loc (sub # typ t1) (sub # typ t2) + | Pctf_inherit ct -> inherit_ ~loc ~attrs (sub # class_type ct) + | Pctf_val (s, m, v, t) -> val_ ~loc ~attrs s m v (sub # typ t) + | Pctf_method (s, p, v, t) -> method_ ~loc ~attrs s p v (sub # typ t) + | Pctf_constraint (t1, t2) -> constraint_ ~loc ~attrs (sub # typ t1) (sub # typ t2) let map_signature sub {pcsig_self; pcsig_fields; pcsig_loc} = Csig.mk @@ -257,40 +257,41 @@ end module CE = struct (* Value expressions for the class language *) - let map sub {pcl_loc = loc; pcl_desc = desc} = + let map sub {pcl_loc = loc; pcl_desc = desc; pcl_attributes = attrs} = let open Cl in let loc = sub # location loc in match desc with - | Pcl_constr (lid, tys) -> constr ~loc (map_loc sub lid) (List.map (sub # typ) tys) + | Pcl_constr (lid, tys) -> constr ~loc ~attrs (map_loc sub lid) (List.map (sub # typ) tys) | Pcl_structure s -> - structure ~loc (sub # class_structure s) + structure ~loc ~attrs (sub # class_structure s) | Pcl_fun (lab, e, p, ce) -> - fun_ ~loc lab + fun_ ~loc ~attrs lab (map_opt (sub # expr) e) (sub # pat p) (sub # class_expr ce) | Pcl_apply (ce, l) -> - apply ~loc (sub # class_expr ce) (List.map (map_snd (sub # expr)) l) + apply ~loc ~attrs (sub # class_expr ce) (List.map (map_snd (sub # expr)) l) | Pcl_let (r, pel, ce) -> - let_ ~loc r + let_ ~loc ~attrs r (List.map (map_tuple (sub # pat) (sub # expr)) pel) (sub # class_expr ce) | Pcl_constraint (ce, ct) -> - constraint_ ~loc (sub # class_expr ce) (sub # class_type ct) + constraint_ ~loc ~attrs (sub # class_expr ce) (sub # class_type ct) + | Pcl_extension x -> extension ~loc ~attrs (sub # extension x) let map_kind sub = function | Cfk_concrete (o, e) -> Cfk_concrete (o, sub # expr e) | Cfk_virtual t -> Cfk_virtual (sub # typ t) - let map_field sub {pcf_desc = desc; pcf_loc = loc} = + let map_field sub {pcf_desc = desc; pcf_loc = loc; pcf_attributes = attrs} = let open Cf in let loc = sub # location loc in match desc with - | Pcf_inherit (o, ce, s) -> inherit_ ~loc o (sub # class_expr ce) s - | Pcf_val (s, m, k) -> val_ ~loc (map_loc sub s) m (map_kind sub k) - | Pcf_method (s, p, k) -> method_ ~loc (map_loc sub s) p (map_kind sub k) - | Pcf_constraint (t1, t2) -> constraint_ ~loc (sub # typ t1) (sub # typ t2) - | Pcf_initializer e -> initializer_ ~loc (sub # expr e) + | Pcf_inherit (o, ce, s) -> inherit_ ~loc ~attrs o (sub # class_expr ce) s + | Pcf_val (s, m, k) -> val_ ~loc ~attrs (map_loc sub s) m (map_kind sub k) + | Pcf_method (s, p, k) -> method_ ~loc ~attrs (map_loc sub s) p (map_kind sub k) + | Pcf_constraint (t1, t2) -> constraint_ ~loc ~attrs (sub # typ t1) (sub # typ t2) + | Pcf_initializer e -> initializer_ ~loc ~attrs (sub # expr e) let map_structure sub {pcstr_self; pcstr_fields} = { diff --git a/parsing/parser.mly b/parsing/parser.mly index 7b56d7f2f..ff62117e8 100644 --- a/parsing/parser.mly +++ b/parsing/parser.mly @@ -771,6 +771,8 @@ class_expr: { mkclass(Pcl_apply($1, List.rev $2)) } | LET rec_flag let_bindings IN class_expr { mkclass(Pcl_let ($2, List.rev $3, $5)) } + | class_expr attribute + { Cl.attr $1 $2 } ; class_simple_expr: LBRACKET core_type_comma_list RBRACKET class_longident diff --git a/parsing/parsetree.mli b/parsing/parsetree.mli index 7f6e2c1bb..2abc78dcd 100644 --- a/parsing/parsetree.mli +++ b/parsing/parsetree.mli @@ -209,8 +209,11 @@ 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_desc: class_expr_desc; + pcl_loc: Location.t; + pcl_attributes: attribute list; + } and class_expr_desc = Pcl_constr of Longident.t loc * core_type list @@ -219,6 +222,7 @@ and class_expr_desc = | Pcl_apply of class_expr * (label * expression) list | Pcl_let of rec_flag * (pattern * expression) list * class_expr | Pcl_constraint of class_expr * class_type + | Pcl_extension of extension and class_structure = { pcstr_self: pattern; diff --git a/parsing/pprintast.ml b/parsing/pprintast.ml index aa812542e..b7c2e5cbd 100644 --- a/parsing/pprintast.ml +++ b/parsing/pprintast.ml @@ -818,8 +818,7 @@ class printer ()= object(self:'self) pp f "(%a@ :@ %a)" self#class_expr ce self#class_type ct - - + | Pcl_extension _ -> assert false method module_type f x = match x.pmty_desc with diff --git a/parsing/printast.ml b/parsing/printast.ml index 731fa48d9..87d9ee23d 100644 --- a/parsing/printast.ml +++ b/parsing/printast.ml @@ -463,6 +463,7 @@ and class_type_declaration i ppf x = and class_expr i ppf x = line i ppf "class_expr %a\n" fmt_location x.pcl_loc; + attributes i ppf x.pcl_attributes; let i = i+1 in match x.pcl_desc with | Pcl_constr (li, l) -> @@ -489,6 +490,9 @@ and class_expr i ppf x = line i ppf "Pcl_constraint\n"; class_expr i ppf ce; class_type i ppf ct; + | Pcl_extension (s, arg) -> + line i ppf "Pcl_extension \"%s\"\n" s; + expression i ppf arg and class_structure i ppf { pcstr_self = p; pcstr_fields = l } = line i ppf "class_structure\n"; diff --git a/tools/depend.ml b/tools/depend.ml index 4c5e020c3..aa2c51839 100644 --- a/tools/depend.ml +++ b/tools/depend.ml @@ -318,6 +318,7 @@ and add_class_expr bv ce = let bv = add_bindings rf bv pel in add_class_expr bv ce | Pcl_constraint(ce, ct) -> add_class_expr bv ce; add_class_type bv ct + | Pcl_extension _ -> () and add_class_field bv pcf = match pcf.pcf_desc with diff --git a/tools/ocamlprof.ml b/tools/ocamlprof.ml index d2f169a34..19b9dca38 100644 --- a/tools/ocamlprof.ml +++ b/tools/ocamlprof.ml @@ -347,6 +347,7 @@ and rewrite_class_expr iflag cexpr = rewrite_class_expr iflag cexpr | Pcl_constraint (cexpr, _) -> rewrite_class_expr iflag cexpr + | Pcl_extension _ -> () and rewrite_class_declaration iflag cl = rewrite_class_expr iflag cl.pci_expr diff --git a/tools/untypeast.ml b/tools/untypeast.ml index d6a08c04d..4e92f8de2 100644 --- a/tools/untypeast.ml +++ b/tools/untypeast.ml @@ -444,6 +444,7 @@ and untype_class_expr cexpr = in { pcl_desc = desc; pcl_loc = cexpr.cl_loc; + pcl_attributes = cexpr.cl_attributes; } and untype_class_type ct = diff --git a/typing/printtyped.ml b/typing/printtyped.ml index ec96b8050..c5905bb8f 100644 --- a/typing/printtyped.ml +++ b/typing/printtyped.ml @@ -477,6 +477,7 @@ and class_type_declaration i ppf x = and class_expr i ppf x = line i ppf "class_expr %a\n" fmt_location x.cl_loc; + attributes i ppf x.cl_attributes; let i = i+1 in match x.cl_desc with | Tcl_ident (li, _, l) -> diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 28eae0bd6..ceba5435c 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -45,6 +45,7 @@ type error = | Final_self_clash of (type_expr * type_expr) list | Mutability_mismatch of string * mutable_flag | No_overriding of string * string + | Extension of string exception Error of Location.t * Env.t * error @@ -817,20 +818,26 @@ and class_expr cl_num val_env met_env scl = rc {cl_desc = Tcl_ident (path, lid, tyl); cl_loc = scl.pcl_loc; cl_type = clty'; - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } in let (vals, meths, concrs) = extract_constraints clty in rc {cl_desc = Tcl_constraint (cl, None, vals, meths, concrs); cl_loc = scl.pcl_loc; cl_type = clty'; - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } | Pcl_structure cl_str -> let (desc, ty) = class_structure cl_num false val_env met_env scl.pcl_loc cl_str in rc {cl_desc = Tcl_structure desc; cl_loc = scl.pcl_loc; cl_type = Cty_signature ty; - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } | Pcl_fun (l, Some default, spat, sbody) -> let loc = default.pexp_loc in let open Ast_helper in @@ -909,7 +916,9 @@ and class_expr cl_num val_env met_env scl = cl_loc = scl.pcl_loc; cl_type = Cty_fun (l, Ctype.instance_def pat.pat_type, cl.cl_type); - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } | Pcl_apply (scl', sargs) -> let cl = class_expr cl_num val_env met_env scl' in let rec nonopt_labels ls ty_fun = @@ -1002,7 +1011,9 @@ and class_expr cl_num val_env met_env scl = rc {cl_desc = Tcl_apply (cl, args); cl_loc = scl.pcl_loc; cl_type = cty; - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } | Pcl_let (rec_flag, sdefs, scl') -> let (defs, val_env) = try @@ -1045,7 +1056,9 @@ and class_expr cl_num val_env met_env scl = rc {cl_desc = Tcl_let (rec_flag, defs, vals, cl); cl_loc = scl.pcl_loc; cl_type = cl.cl_type; - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } | Pcl_constraint (scl', scty) -> Ctype.begin_class_def (); let context = Typetexp.narrow () in @@ -1071,7 +1084,11 @@ and class_expr cl_num val_env met_env scl = rc {cl_desc = Tcl_constraint (cl, Some clty, vals, meths, concrs); cl_loc = scl.pcl_loc; cl_type = snd (Ctype.instance_class [] clty.cltyp_type); - cl_env = val_env} + cl_env = val_env; + cl_attributes = scl.pcl_attributes; + } + | Pcl_extension (s, _arg) -> + raise (Error (scl.pcl_loc, val_env, Extension s)) (*******************************) @@ -1727,6 +1744,8 @@ let report_error env ppf = function "instance variable" | No_overriding (kind, name) -> fprintf ppf "@[The %s `%s'@ has no previous definition@]" kind name - + | Extension s -> + fprintf ppf "Uninterpreted extension '%s'." s + let report_error env ppf err = Printtyp.wrap_printing_env env (fun () -> report_error env ppf err) diff --git a/typing/typeclass.mli b/typing/typeclass.mli index c8f28013d..81e56bd1b 100644 --- a/typing/typeclass.mli +++ b/typing/typeclass.mli @@ -103,6 +103,7 @@ type error = | Final_self_clash of (type_expr * type_expr) list | Mutability_mismatch of string * mutable_flag | No_overriding of string * string + | Extension of string exception Error of Location.t * Env.t * error diff --git a/typing/typecore.ml b/typing/typecore.ml index d09d86e7a..18433d26c 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -192,6 +192,7 @@ let iter_expression f e = | Pcl_let (_, pel, ce) -> List.iter (fun (_, e) -> expr e) pel; class_expr ce | Pcl_constraint (ce, _) -> class_expr ce + | Pcl_extension _ -> () and class_field cf = match cf.pcf_desc with diff --git a/typing/typedtree.ml b/typing/typedtree.ml index 5ab71c62f..912f60845 100644 --- a/typing/typedtree.ml +++ b/typing/typedtree.ml @@ -114,10 +114,13 @@ and meth = (* Value expressions for the class language *) and class_expr = - { cl_desc: class_expr_desc; - cl_loc: Location.t; - cl_type: Types.class_type; - cl_env: Env.t } + { + cl_desc: class_expr_desc; + cl_loc: Location.t; + cl_type: Types.class_type; + cl_env: Env.t; + cl_attributes: attribute list; + } and class_expr_desc = Tcl_ident of Path.t * Longident.t loc * core_type list diff --git a/typing/typedtree.mli b/typing/typedtree.mli index 5b79ddbeb..b42967884 100644 --- a/typing/typedtree.mli +++ b/typing/typedtree.mli @@ -113,10 +113,13 @@ and meth = (* Value expressions for the class language *) and class_expr = - { cl_desc: class_expr_desc; - cl_loc: Location.t; - cl_type: Types.class_type; - cl_env: Env.t } + { + cl_desc: class_expr_desc; + cl_loc: Location.t; + cl_type: Types.class_type; + cl_env: Env.t; + cl_attributes: attribute list; + } and class_expr_desc = Tcl_ident of Path.t * Longident.t loc * core_type list |