Add lazy patterns.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@8906 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02master
parent
0ccc1f7ff0
commit
6ba024a12e
2
VERSION
2
VERSION
|
@ -1,4 +1,4 @@
|
|||
3.11+dev12 Private_abbrevs+natdynlink (2008-02-29)
|
||||
3.11+dev12 Private_abbrevs+natdynlink+lazy_patterns (2008-07-09)
|
||||
|
||||
# The version string is the first line of this file.
|
||||
# It must be in the format described in stdlib/sys.mli
|
||||
|
|
BIN
boot/ocamlc
BIN
boot/ocamlc
Binary file not shown.
BIN
boot/ocamldep
BIN
boot/ocamldep
Binary file not shown.
BIN
boot/ocamllex
BIN
boot/ocamllex
Binary file not shown.
|
@ -203,6 +203,10 @@ let ctx_matcher p =
|
|||
let l' = all_record_args l' in
|
||||
p, List.fold_right (fun (_,p) r -> p::r) l' rem
|
||||
| _ -> p,List.fold_right (fun (_,p) r -> p::r) l rem)
|
||||
| Tpat_lazy omega ->
|
||||
(fun q rem -> match q.pat_desc with
|
||||
| Tpat_lazy arg -> p, (arg::rem)
|
||||
| _ -> p, (omega::rem))
|
||||
| _ -> fatal_error "Matching.ctx_matcher"
|
||||
|
||||
|
||||
|
@ -616,6 +620,7 @@ let rec extract_vars r p = match p.pat_desc with
|
|||
| Tpat_array pats ->
|
||||
List.fold_left extract_vars r pats
|
||||
| Tpat_variant (_,Some p, _) -> extract_vars r p
|
||||
| Tpat_lazy p -> extract_vars r p
|
||||
| Tpat_or (p,_,_) -> extract_vars r p
|
||||
| Tpat_constant _|Tpat_any|Tpat_variant (_,None,_) -> r
|
||||
|
||||
|
@ -683,6 +688,10 @@ and group_array = function
|
|||
| {pat_desc=Tpat_array _} -> true
|
||||
| _ -> false
|
||||
|
||||
and group_lazy = function
|
||||
| {pat_desc = Tpat_lazy _} -> true
|
||||
| _ -> false
|
||||
|
||||
let get_group p = match p.pat_desc with
|
||||
| Tpat_any -> group_var
|
||||
| Tpat_constant _ -> group_constant
|
||||
|
@ -691,6 +700,7 @@ let get_group p = match p.pat_desc with
|
|||
| Tpat_record _ -> group_record
|
||||
| Tpat_array _ -> group_array
|
||||
| Tpat_variant (_,_,_) -> group_variant
|
||||
| Tpat_lazy _ -> group_lazy
|
||||
| _ -> fatal_error "Matching.get_group"
|
||||
|
||||
|
||||
|
@ -1287,6 +1297,50 @@ let make_var_matching def = function
|
|||
let divide_var ctx pm =
|
||||
divide_line ctx_lshift make_var_matching get_args_var omega ctx pm
|
||||
|
||||
(* Matching and forcing a lazy value *)
|
||||
|
||||
let get_arg_lazy p rem = match p with
|
||||
| {pat_desc = Tpat_any} -> omega :: rem
|
||||
| {pat_desc = Tpat_lazy arg} -> arg :: rem
|
||||
| _ -> assert false
|
||||
|
||||
let matcher_lazy p rem = match p.pat_desc with
|
||||
| Tpat_or (_,_,_) -> raise OrPat
|
||||
| Tpat_lazy arg -> arg :: rem
|
||||
| Tpat_var _ -> get_arg_lazy omega rem
|
||||
| _ -> get_arg_lazy p rem
|
||||
|
||||
|
||||
(* Compute lazily the lambda-code of Lazy.force *)
|
||||
|
||||
let lambda_of_force =
|
||||
lazy (
|
||||
let lazy_mod_ident = Ident.create_persistent "Lazy" in
|
||||
let lazy_env = Env.open_pers_signature "Lazy" Env.initial in
|
||||
let p = try
|
||||
match Env.lookup_value (Longident.Lident "force") lazy_env with
|
||||
| (Path.Pdot(_,_,i), _) -> i
|
||||
| _ -> assert false
|
||||
with Not_found -> assert false
|
||||
in
|
||||
Lprim(Pfield p, [Lprim(Pgetglobal lazy_mod_ident, [])])
|
||||
)
|
||||
|
||||
let make_lazy_matching def = function
|
||||
[] -> fatal_error "Matching.make_lazy_matching"
|
||||
| (arg,mut) :: argl ->
|
||||
{ cases = [];
|
||||
args = (Lapply(Lazy.force lambda_of_force, [arg], Location.none),
|
||||
Strict) :: argl;
|
||||
default = make_default matcher_lazy def }
|
||||
|
||||
let divide_lazy p ctx pm =
|
||||
divide_line
|
||||
(filter_ctx p)
|
||||
make_lazy_matching
|
||||
get_arg_lazy
|
||||
p ctx pm
|
||||
|
||||
(* Matching against a tuple pattern *)
|
||||
|
||||
|
||||
|
@ -2335,6 +2389,10 @@ and do_compile_matching repr partial ctx arg pmh = match pmh with
|
|||
compile_test (compile_match repr partial) partial
|
||||
(divide_array kind) (combine_array arg kind partial)
|
||||
ctx pm
|
||||
| Tpat_lazy _ ->
|
||||
compile_no_test
|
||||
(divide_lazy (normalize_pat pat))
|
||||
ctx_combine repr partial ctx pm
|
||||
| Tpat_variant(lab, _, row) ->
|
||||
compile_test (compile_match repr partial) partial
|
||||
(divide_variant !row)
|
||||
|
@ -2577,4 +2635,3 @@ let for_multiple_match loc paraml pat_act_list partial =
|
|||
end
|
||||
with Unused ->
|
||||
assert false (* ; partial_function loc () *)
|
||||
|
||||
|
|
|
@ -851,7 +851,7 @@ and transl_apply lam sargs loc =
|
|||
and transl_function loc untuplify_fn repr partial pat_expr_list =
|
||||
match pat_expr_list with
|
||||
[pat, ({exp_desc = Texp_function(pl,partial')} as exp)]
|
||||
when Parmatch.irrefutable pat ->
|
||||
when Parmatch.fluid pat ->
|
||||
let param = name_pattern "param" pat_expr_list in
|
||||
let ((_, params), body) =
|
||||
transl_function exp.exp_loc false repr partial' pl in
|
||||
|
|
|
@ -86,7 +86,8 @@
|
|||
| PaTup of loc and patt (* ( p ) *)
|
||||
| PaTyc of loc and patt and ctyp (* (p : t) *)
|
||||
| PaTyp of loc and ident (* #i *)
|
||||
| PaVrn of loc and string (* `s *) ]
|
||||
| PaVrn of loc and string (* `s *)
|
||||
| PaLaz of loc and patt (* lazy p *) ]
|
||||
and expr =
|
||||
[ ExNil of loc
|
||||
| ExId of loc and ident (* i *)
|
||||
|
|
|
@ -589,6 +589,8 @@ module Make (Syntax : Sig.Camlp4Syntax) = struct
|
|||
|
||||
method patt5 f = fun
|
||||
[ <:patt< [$_$ :: $_$] >> as p -> o#simple_patt f p
|
||||
| <:patt< lazy $p$ >> ->
|
||||
pp f "@[<2>lazy %a@]" o#simple_patt p
|
||||
| <:patt< $x$ $y$ >> ->
|
||||
let (a, al) = get_patt_args x [y] in
|
||||
if not (Ast.is_patt_constructor a) then
|
||||
|
@ -637,8 +639,9 @@ module Make (Syntax : Sig.Camlp4Syntax) = struct
|
|||
pp f "@[<2>?%s:@,@[<1>(%a =@ %a)@]@]" s o#patt_tycon p o#expr e
|
||||
| <:patt< $_$ $_$ >> | <:patt< ($_$ as $_$) >> | <:patt< $_$ | $_$ >> |
|
||||
<:patt< $_$ .. $_$ >> | <:patt< $_$, $_$ >> |
|
||||
<:patt< $_$; $_$ >> | <:patt< $_$ = $_$ >> as p ->
|
||||
pp f "@[<1>(%a)@]" o#patt p ];
|
||||
<:patt< $_$; $_$ >> | <:patt< $_$ = $_$ >> | <:patt< lazy $_$ >> as p ->
|
||||
pp f "@[<1>(%a)@]" o#patt p
|
||||
];
|
||||
|
||||
method patt_tycon f =
|
||||
fun
|
||||
|
|
|
@ -500,6 +500,7 @@ module Make (Ast : Sig.Camlp4Ast) = struct
|
|||
| PaTyc loc p t -> mkpat loc (Ppat_constraint (patt p) (ctyp t))
|
||||
| PaTyp loc i -> mkpat loc (Ppat_type (long_type_ident i))
|
||||
| PaVrn loc s -> mkpat loc (Ppat_variant s None)
|
||||
| PaLaz loc p -> mkpat loc (Ppat_lazy (patt p))
|
||||
| PaEq _ _ _ | PaSem _ _ _ | PaCom _ _ _ | PaNil _ as p ->
|
||||
error (loc_of_patt p) "invalid pattern" ]
|
||||
and mklabpat =
|
||||
|
|
|
@ -372,6 +372,7 @@ module Make (Syntax : Sig.Camlp4Syntax) = struct
|
|||
List.fold_left (fun p1 p2 -> <:patt< $p1$ $p2$ >>) p1
|
||||
(Ast.list_of_patt p [])
|
||||
| _ -> <:patt< $p1$ $p2$ >> ]
|
||||
| "lazy"; p = SELF -> <:patt< lazy $p$ >>
|
||||
| `ANTIQUOT (""|"pat"|"anti" as n) s ->
|
||||
<:patt< $anti:mk_anti ~c:"patt" n s$ >>
|
||||
| p = patt_constr -> p ]
|
||||
|
|
|
@ -825,7 +825,8 @@ Very old (no more supported) syntax:
|
|||
| ".." NONA
|
||||
[ p1 = SELF; ".."; p2 = SELF -> <:patt< $p1$ .. $p2$ >> ]
|
||||
| "apply" LEFTA
|
||||
[ p1 = SELF; p2 = SELF -> <:patt< $p1$ $p2$ >> ]
|
||||
[ p1 = SELF; p2 = SELF -> <:patt< $p1$ $p2$ >>
|
||||
| "lazy"; p = SELF -> <:patt< lazy $p$ >> ]
|
||||
| "simple"
|
||||
[ `ANTIQUOT (""|"pat"|"anti" as n) s ->
|
||||
<:patt< $anti:mk_anti ~c:"patt" n s$ >>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1806,7 +1806,15 @@ module Make (Loc : Sig.Loc) : Sig.Camlp4Ast with module Loc = Loc =
|
|||
(meta_loc _loc x0) ]
|
||||
and meta_patt _loc =
|
||||
fun
|
||||
[ Ast.PaVrn x0 x1 ->
|
||||
[ Ast.PaLaz x0 x1 ->
|
||||
Ast.ExApp _loc
|
||||
(Ast.ExApp _loc
|
||||
(Ast.ExId _loc
|
||||
(Ast.IdAcc _loc (Ast.IdUid _loc "Ast")
|
||||
(Ast.IdUid _loc "PaLaz")))
|
||||
(meta_loc _loc x0))
|
||||
(meta_patt _loc x1)
|
||||
| Ast.PaVrn x0 x1 ->
|
||||
Ast.ExApp _loc
|
||||
(Ast.ExApp _loc
|
||||
(Ast.ExId _loc
|
||||
|
@ -3718,7 +3726,15 @@ module Make (Loc : Sig.Loc) : Sig.Camlp4Ast with module Loc = Loc =
|
|||
(meta_loc _loc x0) ]
|
||||
and meta_patt _loc =
|
||||
fun
|
||||
[ Ast.PaVrn x0 x1 ->
|
||||
[ Ast.PaLaz x0 x1 ->
|
||||
Ast.PaApp _loc
|
||||
(Ast.PaApp _loc
|
||||
(Ast.PaId _loc
|
||||
(Ast.IdAcc _loc (Ast.IdUid _loc "Ast")
|
||||
(Ast.IdUid _loc "PaLaz")))
|
||||
(meta_loc _loc x0))
|
||||
(meta_patt _loc x1)
|
||||
| Ast.PaVrn x0 x1 ->
|
||||
Ast.PaApp _loc
|
||||
(Ast.PaApp _loc
|
||||
(Ast.PaId _loc
|
||||
|
@ -4518,7 +4534,9 @@ module Make (Loc : Sig.Loc) : Sig.Camlp4Ast with module Loc = Loc =
|
|||
let _x_i1 = o#ident _x_i1 in PaTyp _x _x_i1
|
||||
| PaVrn _x _x_i1 ->
|
||||
let _x = o#loc _x in
|
||||
let _x_i1 = o#string _x_i1 in PaVrn _x _x_i1 ];
|
||||
let _x_i1 = o#string _x_i1 in PaVrn _x _x_i1
|
||||
| PaLaz _x _x_i1 ->
|
||||
let _x = o#loc _x in let _x_i1 = o#patt _x_i1 in PaLaz _x _x_i1 ];
|
||||
method module_type : module_type -> module_type =
|
||||
fun
|
||||
[ MtNil _x -> let _x = o#loc _x in MtNil _x
|
||||
|
@ -5237,7 +5255,8 @@ module Make (Loc : Sig.Loc) : Sig.Camlp4Ast with module Loc = Loc =
|
|||
let o = o#loc _x in
|
||||
let o = o#patt _x_i1 in let o = o#ctyp _x_i2 in o
|
||||
| PaTyp _x _x_i1 -> let o = o#loc _x in let o = o#ident _x_i1 in o
|
||||
| PaVrn _x _x_i1 -> let o = o#loc _x in let o = o#string _x_i1 in o ];
|
||||
| PaVrn _x _x_i1 -> let o = o#loc _x in let o = o#string _x_i1 in o
|
||||
| PaLaz _x _x_i1 -> let o = o#loc _x in let o = o#patt _x_i1 in o ];
|
||||
method module_type : module_type -> 'self_type =
|
||||
fun
|
||||
[ MtNil _x -> let o = o#loc _x in o
|
||||
|
|
|
@ -21,8 +21,12 @@ module R =
|
|||
* - Nicolas Pouillard: refactoring
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4OCamlRevisedParser"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4OCamlRevisedParser"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4OCamlRevisedParser.ml,v 1.9 2007/12/18 09:02:17 ertai Exp $"
|
||||
|
||||
end
|
||||
|
||||
module Make (Syntax : Sig.Camlp4Syntax) =
|
||||
|
@ -3126,7 +3130,11 @@ Very old (no more supported) syntax:
|
|||
(_loc : Gram.Loc.t) ->
|
||||
(Ast.PaRng (_loc, p1, p2) : 'patt)))) ]);
|
||||
((Some "apply"), (Some Camlp4.Sig.Grammar.LeftA),
|
||||
[ ([ Gram.Sself; Gram.Sself ],
|
||||
[ ([ Gram.Skeyword "lazy"; Gram.Sself ],
|
||||
(Gram.Action.mk
|
||||
(fun (p : 'patt) _ (_loc : Gram.Loc.t) ->
|
||||
(Ast.PaLaz (_loc, p) : 'patt))));
|
||||
([ Gram.Sself; Gram.Sself ],
|
||||
(Gram.Action.mk
|
||||
(fun (p2 : 'patt) (p1 : 'patt)
|
||||
(_loc : Gram.Loc.t) ->
|
||||
|
@ -8348,8 +8356,12 @@ module Camlp4QuotationCommon =
|
|||
* - Nicolas Pouillard: initial version
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4QuotationCommon"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4QuotationCommon"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4QuotationCommon.ml,v 1.5 2008/01/11 16:13:16 doligez Exp $"
|
||||
|
||||
end
|
||||
|
||||
module Make
|
||||
|
@ -9047,8 +9059,12 @@ module Q =
|
|||
* - Nicolas Pouillard: refactoring
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4QuotationExpander"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4QuotationExpander"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4QuotationExpander.ml,v 1.1 2007/02/07 10:09:22 ertai Exp $"
|
||||
|
||||
end
|
||||
|
||||
module Make (Syntax : Sig.Camlp4Syntax) =
|
||||
|
@ -9086,8 +9102,11 @@ module Rp =
|
|||
* - Nicolas Pouillard: refactoring
|
||||
*)
|
||||
module Id : Sig.Id =
|
||||
struct let name = "Camlp4OCamlRevisedParserParser"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4OCamlRevisedParserParser"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4OCamlRevisedParserParser.ml,v 1.4 2008/01/11 16:13:16 doligez Exp $"
|
||||
|
||||
end
|
||||
|
||||
|
@ -10017,8 +10036,12 @@ module G =
|
|||
* - Nicolas Pouillard: refactoring
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4GrammarParser"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4GrammarParser"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4GrammarParser.ml,v 1.5 2008/01/11 16:13:16 doligez Exp $"
|
||||
|
||||
end
|
||||
|
||||
module Make (Syntax : Sig.Camlp4Syntax) =
|
||||
|
@ -12414,8 +12437,12 @@ module M =
|
|||
* - Christopher Conway: extra feature (-D<uident>=)
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4MacroParser"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4MacroParser"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4MacroParser.ml,v 1.3 2007/11/21 17:51:16 ertai Exp $"
|
||||
|
||||
end
|
||||
|
||||
(*
|
||||
|
@ -13313,8 +13340,12 @@ module D =
|
|||
* - Nicolas Pouillard: initial version
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4DebugParser"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4DebugParser"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4DebugParser.ml,v 1.1 2007/02/07 10:09:22 ertai Exp $"
|
||||
|
||||
end
|
||||
|
||||
module Make (Syntax : Sig.Camlp4Syntax) =
|
||||
|
@ -13506,8 +13537,12 @@ module L =
|
|||
* - Nicolas Pouillard: revised syntax version
|
||||
*)
|
||||
module Id =
|
||||
struct let name = "Camlp4ListComprenhsion"
|
||||
let version = "$Id$"
|
||||
struct
|
||||
let name = "Camlp4ListComprenhsion"
|
||||
|
||||
let version =
|
||||
"$Id: Camlp4ListComprehension.ml,v 1.2 2007/11/21 17:51:16 ertai Exp $"
|
||||
|
||||
end
|
||||
|
||||
module Make (Syntax : Sig.Camlp4Syntax) =
|
||||
|
@ -13882,7 +13917,7 @@ module B =
|
|||
* - Daniel de Rauglaudre: initial version
|
||||
* - Nicolas Pouillard: refactoring
|
||||
*)
|
||||
(* $Id$ *)
|
||||
(* $Id: Camlp4Bin.ml,v 1.18 2008/01/11 16:13:16 doligez Exp $ *)
|
||||
open Camlp4
|
||||
|
||||
open PreCast.Syntax
|
||||
|
|
|
@ -1077,6 +1077,8 @@ pattern:
|
|||
false)) }
|
||||
| pattern BAR pattern
|
||||
{ mkpat(Ppat_or($1, $3)) }
|
||||
| LAZY simple_pattern
|
||||
{ mkpat(Ppat_lazy $2) }
|
||||
;
|
||||
simple_pattern:
|
||||
val_ident %prec below_EQUAL
|
||||
|
|
|
@ -75,6 +75,7 @@ and pattern_desc =
|
|||
| Ppat_or of pattern * pattern
|
||||
| Ppat_constraint of pattern * core_type
|
||||
| Ppat_type of Longident.t
|
||||
| Ppat_lazy of pattern
|
||||
|
||||
type expression =
|
||||
{ pexp_desc: expression_desc;
|
||||
|
|
|
@ -186,6 +186,9 @@ and pattern i ppf x =
|
|||
line i ppf "Ppat_or\n";
|
||||
pattern i ppf p1;
|
||||
pattern i ppf p2;
|
||||
| Ppat_lazy p ->
|
||||
line i ppf "Ppat_lazy\n";
|
||||
pattern i ppf p;
|
||||
| Ppat_constraint (p, ct) ->
|
||||
line i ppf "Ppat_constraint";
|
||||
pattern i ppf p;
|
||||
|
|
|
@ -62,6 +62,7 @@ let rec pattern_vars pat =
|
|||
List.concat (List.map l ~f:(fun (_,p) -> pattern_vars p))
|
||||
| Ppat_or (pat1, pat2) ->
|
||||
pattern_vars pat1 @ pattern_vars pat2
|
||||
| Ppat_lazy pat -> pattern_vars pat
|
||||
| Ppat_any | Ppat_constant _ | Ppat_construct _ | Ppat_variant _
|
||||
| Ppat_type _ ->
|
||||
[]
|
||||
|
|
|
@ -112,6 +112,7 @@ let rec add_pattern bv pat =
|
|||
| Ppat_constraint(p, ty) -> add_pattern bv p; add_type bv ty
|
||||
| Ppat_variant(_, op) -> add_opt add_pattern bv op
|
||||
| Ppat_type (li) -> add bv li
|
||||
| Ppat_lazy p -> add_pattern bv p
|
||||
|
||||
let rec add_expr bv exp =
|
||||
match exp.pexp_desc with
|
||||
|
|
|
@ -83,6 +83,7 @@ let rec compat p q =
|
|||
| _,Tpat_or (q1,q2,_) -> compat p q1 || compat p q2
|
||||
| Tpat_constant c1, Tpat_constant c2 -> c1=c2
|
||||
| Tpat_tuple ps, Tpat_tuple qs -> compats ps qs
|
||||
| Tpat_lazy p, Tpat_lazy q -> compat p q
|
||||
| Tpat_construct (c1,ps1), Tpat_construct (c2,ps2) ->
|
||||
c1.cstr_tag = c2.cstr_tag && compats ps1 ps2
|
||||
| Tpat_variant(l1,Some p1, r1), Tpat_variant(l2,Some p2,_) ->
|
||||
|
@ -204,6 +205,8 @@ let rec pretty_val ppf v = match v.pat_desc with
|
|||
| _ -> true) lvs)
|
||||
| Tpat_array vs ->
|
||||
fprintf ppf "@[[| %a |]@]" (pretty_vals " ;") vs
|
||||
| Tpat_lazy v ->
|
||||
fprintf ppf "@[<2>lazy@ %a@]" pretty_arg v
|
||||
| Tpat_alias (v,x) ->
|
||||
fprintf ppf "@[(%a@ as %a)@]" pretty_val v Ident.print x
|
||||
| Tpat_or (v,w,_) ->
|
||||
|
@ -269,6 +272,7 @@ let simple_match p1 p2 =
|
|||
float_of_string s1 = float_of_string s2
|
||||
| Tpat_constant(c1), Tpat_constant(c2) -> c1 = c2
|
||||
| Tpat_tuple _, Tpat_tuple _ -> true
|
||||
| Tpat_lazy _, Tpat_lazy _ -> true
|
||||
| Tpat_record _ , Tpat_record _ -> true
|
||||
| Tpat_array p1s, Tpat_array p2s -> List.length p1s = List.length p2s
|
||||
| _, (Tpat_any | Tpat_var(_)) -> true
|
||||
|
@ -329,6 +333,7 @@ let rec simple_match_args p1 p2 = match p2.pat_desc with
|
|||
| Tpat_tuple(args) -> args
|
||||
| Tpat_record(args) -> extract_fields (record_arg p1) args
|
||||
| Tpat_array(args) -> args
|
||||
| Tpat_lazy arg -> [arg]
|
||||
| (Tpat_any | Tpat_var(_)) ->
|
||||
begin match p1.pat_desc with
|
||||
Tpat_construct(_, args) -> omega_list args
|
||||
|
@ -336,6 +341,7 @@ let rec simple_match_args p1 p2 = match p2.pat_desc with
|
|||
| Tpat_tuple(args) -> omega_list args
|
||||
| Tpat_record(args) -> omega_list args
|
||||
| Tpat_array(args) -> omega_list args
|
||||
| Tpat_lazy _ -> [omega]
|
||||
| _ -> []
|
||||
end
|
||||
| _ -> []
|
||||
|
@ -361,6 +367,8 @@ let rec normalize_pat q = match q.pat_desc with
|
|||
| Tpat_record (largs) ->
|
||||
make_pat (Tpat_record (List.map (fun (lbl,_) -> lbl,omega) largs))
|
||||
q.pat_type q.pat_env
|
||||
| Tpat_lazy _ ->
|
||||
make_pat (Tpat_lazy omega) q.pat_type q.pat_env
|
||||
| Tpat_or _ -> fatal_error "Parmatch.normalize_pat"
|
||||
|
||||
|
||||
|
@ -379,6 +387,7 @@ let discr_pat q pss =
|
|||
| ({pat_desc = (Tpat_any | Tpat_var _)}::_)::pss ->
|
||||
acc_pat acc pss
|
||||
| (({pat_desc = Tpat_tuple _} as p)::_)::_ -> normalize_pat p
|
||||
| (({pat_desc = Tpat_lazy _} as p)::_)::_ -> normalize_pat p
|
||||
| (({pat_desc = Tpat_record largs} as p)::_)::pss ->
|
||||
let new_omegas =
|
||||
List.fold_left
|
||||
|
@ -448,6 +457,12 @@ let do_set_args erase_mutable q r = match q with
|
|||
make_pat
|
||||
(Tpat_variant (l, arg, row)) q.pat_type q.pat_env::
|
||||
rest
|
||||
| {pat_desc = Tpat_lazy omega} ->
|
||||
begin match r with
|
||||
arg::rest ->
|
||||
make_pat (Tpat_lazy arg) q.pat_type q.pat_env::rest
|
||||
| _ -> fatal_error "Parmatch.do_set_args (lazy)"
|
||||
end
|
||||
| {pat_desc = Tpat_array omegas} ->
|
||||
let args,rest = read_args omegas r in
|
||||
make_pat
|
||||
|
@ -541,7 +556,7 @@ let filter_all pat0 pss =
|
|||
filter_omega
|
||||
(filter_rec
|
||||
(match pat0.pat_desc with
|
||||
(Tpat_record(_) | Tpat_tuple(_)) -> [pat0,[]]
|
||||
(Tpat_record(_) | Tpat_tuple(_) | Tpat_lazy(_)) -> [pat0,[]]
|
||||
| _ -> [])
|
||||
pss)
|
||||
pss
|
||||
|
@ -630,6 +645,7 @@ let full_match closing env = match env with
|
|||
| ({pat_desc = Tpat_tuple(_)},_) :: _ -> true
|
||||
| ({pat_desc = Tpat_record(_)},_) :: _ -> true
|
||||
| ({pat_desc = Tpat_array(_)},_) :: _ -> false
|
||||
| ({pat_desc = Tpat_lazy(_)},_) :: _ -> true
|
||||
| _ -> fatal_error "Parmatch.full_match"
|
||||
|
||||
let extendable_match env = match env with
|
||||
|
@ -867,6 +883,7 @@ let rec has_instance p = match p.pat_desc with
|
|||
| Tpat_or (p1,p2,_) -> has_instance p1 || has_instance p2
|
||||
| Tpat_construct (_,ps) | Tpat_tuple ps | Tpat_array ps -> has_instances ps
|
||||
| Tpat_record lps -> has_instances (List.map snd lps)
|
||||
| Tpat_lazy p -> has_instance p
|
||||
|
||||
and has_instances = function
|
||||
| [] -> true
|
||||
|
@ -1299,6 +1316,7 @@ let rec le_pat p q =
|
|||
l1 = l2
|
||||
| Tpat_variant(_,_,_), Tpat_variant(_,_,_) -> false
|
||||
| Tpat_tuple(ps), Tpat_tuple(qs) -> le_pats ps qs
|
||||
| Tpat_lazy p, Tpat_lazy q -> le_pat p q
|
||||
| Tpat_record l1, Tpat_record l2 ->
|
||||
let ps,qs = records_args l1 l2 in
|
||||
le_pats ps qs
|
||||
|
@ -1337,6 +1355,9 @@ let rec lub p q = match p.pat_desc,q.pat_desc with
|
|||
| Tpat_tuple ps, Tpat_tuple qs ->
|
||||
let rs = lubs ps qs in
|
||||
make_pat (Tpat_tuple rs) p.pat_type p.pat_env
|
||||
| Tpat_lazy p, Tpat_lazy q ->
|
||||
let r = lub p q in
|
||||
make_pat (Tpat_lazy r) p.pat_type p.pat_env
|
||||
| Tpat_construct (c1,ps1), Tpat_construct (c2,ps2)
|
||||
when c1.cstr_tag = c2.cstr_tag ->
|
||||
let rs = lubs ps1 ps2 in
|
||||
|
@ -1570,6 +1591,8 @@ let rec collect_paths_from_pat r p = match p.pat_desc with
|
|||
| Tpat_variant (_, Some p, _) | Tpat_alias (p,_) -> collect_paths_from_pat r p
|
||||
| Tpat_or (p1,p2,_) ->
|
||||
collect_paths_from_pat (collect_paths_from_pat r p1) p2
|
||||
| Tpat_lazy p1 ->
|
||||
collect_paths_from_pat r p
|
||||
|
||||
|
||||
(*
|
||||
|
@ -1659,8 +1682,31 @@ let check_unused tdefs casel =
|
|||
|
||||
do_rec [] casel
|
||||
|
||||
(********************************)
|
||||
(* Exported irrefutability test *)
|
||||
(********************************)
|
||||
(*********************************)
|
||||
(* Exported irrefutability tests *)
|
||||
(*********************************)
|
||||
|
||||
let irrefutable pat = le_pat pat omega
|
||||
|
||||
(* An inactive pattern is a pattern whose matching needs only
|
||||
trivial computations (tag/equality tests).
|
||||
Patterns containing (lazy _) subpatterns are active. *)
|
||||
|
||||
let rec inactive pat = match pat with
|
||||
| Tpat_lazy _ ->
|
||||
false
|
||||
| Tpat_any | Tpat_var _ | Tpat_constant _ | Tpat_variant (_, None, _) ->
|
||||
true
|
||||
| Tpat_tuple ps | Tpat_construct (_, ps) | Tpat_array ps ->
|
||||
List.for_all (fun p -> inactive p.pat_desc) ps
|
||||
| Tpat_alias (p,_) | Tpat_variant (_, Some p, _) ->
|
||||
inactive p.pat_desc
|
||||
| Tpat_record ldps ->
|
||||
List.exists (fun (_, p) -> inactive p.pat_desc) ldps
|
||||
| Tpat_or (p,q,_) ->
|
||||
inactive p.pat_desc && inactive q.pat_desc
|
||||
|
||||
|
||||
(* A `fluid' pattern is both irrefutable and inactive *)
|
||||
|
||||
let fluid pat = irrefutable pat && inactive pat.pat_desc
|
||||
|
|
|
@ -54,5 +54,6 @@ val pressure_variants: Env.t -> pattern list -> unit
|
|||
val check_partial: Location.t -> (pattern * expression) list -> partial
|
||||
val check_unused: Env.t -> (pattern * expression) list -> unit
|
||||
|
||||
(* Irrefutability test *)
|
||||
(* Irrefutability tests *)
|
||||
val irrefutable : pattern -> bool
|
||||
val fluid : pattern -> bool
|
||||
|
|
|
@ -294,7 +294,8 @@ let rec build_as_type env p =
|
|||
let row = row_repr row in
|
||||
newty (Tvariant{row with row_closed=false; row_more=newvar()})
|
||||
end
|
||||
| Tpat_any | Tpat_var _ | Tpat_constant _ | Tpat_array _ -> p.pat_type
|
||||
| Tpat_any | Tpat_var _ | Tpat_constant _
|
||||
| Tpat_array _ | Tpat_lazy _ -> p.pat_type
|
||||
|
||||
let build_or_pat env loc lid =
|
||||
let path, decl =
|
||||
|
@ -509,6 +510,13 @@ let rec type_pat env sp =
|
|||
pat_loc = sp.ppat_loc;
|
||||
pat_type = p1.pat_type;
|
||||
pat_env = env }
|
||||
| Ppat_lazy sp1 ->
|
||||
let p1 = type_pat env sp1 in
|
||||
rp {
|
||||
pat_desc = Tpat_lazy p1;
|
||||
pat_loc = sp.ppat_loc;
|
||||
pat_type = instance (Predef.type_lazy_t p1.pat_type);
|
||||
pat_env = env }
|
||||
| Ppat_constraint(sp, sty) ->
|
||||
let p = type_pat env sp in
|
||||
let ty, force = Typetexp.transl_simple_type_delayed env sty in
|
||||
|
@ -1466,7 +1474,7 @@ let rec type_exp env sexp =
|
|||
exp_type = newvar ();
|
||||
exp_env = env;
|
||||
}
|
||||
| Pexp_lazy (e) ->
|
||||
| Pexp_lazy e ->
|
||||
let arg = type_exp env e in
|
||||
re {
|
||||
exp_desc = Texp_lazy arg;
|
||||
|
|
|
@ -37,6 +37,7 @@ and pattern_desc =
|
|||
| Tpat_record of (label_description * pattern) list
|
||||
| Tpat_array of pattern list
|
||||
| Tpat_or of pattern * pattern * row_desc option
|
||||
| Tpat_lazy of pattern
|
||||
|
||||
type partial = Partial | Total
|
||||
type optional = Required | Optional
|
||||
|
@ -162,6 +163,7 @@ let iter_pattern_desc f = function
|
|||
List.iter (fun (lbl, pat) -> f pat) lbl_pat_list
|
||||
| Tpat_array patl -> List.iter f patl
|
||||
| Tpat_or(p1, p2, _) -> f p1; f p2
|
||||
| Tpat_lazy p -> f p
|
||||
| Tpat_any
|
||||
| Tpat_var _
|
||||
| Tpat_constant _ -> ()
|
||||
|
@ -178,6 +180,7 @@ let map_pattern_desc f d =
|
|||
Tpat_construct (c, List.map f pats)
|
||||
| Tpat_array pats ->
|
||||
Tpat_array (List.map f pats)
|
||||
| Tpat_lazy p1 -> Tpat_lazy (f p1)
|
||||
| Tpat_variant (x1, Some p1, x2) ->
|
||||
Tpat_variant (x1, Some (f p1), x2)
|
||||
| Tpat_or (p1,p2,path) ->
|
||||
|
|
|
@ -36,6 +36,7 @@ and pattern_desc =
|
|||
| Tpat_record of (label_description * pattern) list
|
||||
| Tpat_array of pattern list
|
||||
| Tpat_or of pattern * pattern * row_desc option
|
||||
| Tpat_lazy of pattern
|
||||
|
||||
type partial = Partial | Total
|
||||
type optional = Required | Optional
|
||||
|
|
|
@ -73,6 +73,7 @@ let rec get_vars ((vacc, asacc) as acc) p =
|
|||
List.fold_left (fun a (_, p) -> get_vars a p) acc ipl
|
||||
| Ppat_array pl -> List.fold_left get_vars acc pl
|
||||
| Ppat_or (p1, _p2) -> get_vars acc p1
|
||||
| Ppat_lazy p -> get_vars acc p
|
||||
| Ppat_constraint (pp, _) -> get_vars acc pp
|
||||
| Ppat_type _ -> acc
|
||||
|
||||
|
|
Loading…
Reference in New Issue