aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Marie Pédrot2017-03-16 09:05:04 +0100
committerPierre-Marie Pédrot2017-05-19 15:17:31 +0200
commitc341a00d916c27b75c79c2fdcce13e969772a990 (patch)
treebb7b14457f6e7fce4db9c68a4d8e7d26e1444559
parent735ab0a7d2f7afaed0695e014034f4b2d6e287c8 (diff)
Allow raw terms to contain references to absolute definitions.
-rw-r--r--g_ltac2.ml420
-rw-r--r--tac2entries.ml2
-rw-r--r--tac2env.ml7
-rw-r--r--tac2env.mli4
-rw-r--r--tac2expr.mli20
-rw-r--r--tac2intern.ml62
6 files changed, 71 insertions, 44 deletions
diff --git a/g_ltac2.ml4 b/g_ltac2.ml4
index a149d942c6..30f5399a88 100644
--- a/g_ltac2.ml4
+++ b/g_ltac2.ml4
@@ -32,12 +32,12 @@ GEXTEND Gram
GLOBAL: tac2expr tac2type tac2def_val tac2def_typ tac2def_ext;
tac2pat:
[ "1" LEFTA
- [ id = Prim.qualid; pl = LIST1 tac2pat LEVEL "0" -> CPatRef (!@loc, id, pl)
- | id = Prim.qualid -> CPatRef (!@loc, id, []) ]
+ [ id = Prim.qualid; pl = LIST1 tac2pat LEVEL "0" -> CPatRef (!@loc, RelId id, pl)
+ | id = Prim.qualid -> CPatRef (!@loc, RelId id, []) ]
| "0"
[ "_" -> CPatAny (!@loc)
| "()" -> CPatTup (!@loc, [])
- | id = Prim.qualid -> CPatRef (!@loc, id, [])
+ | id = Prim.qualid -> CPatRef (!@loc, RelId id, [])
| "("; pl = LIST0 tac2pat LEVEL "1" SEP ","; ")" -> CPatTup (!@loc, pl) ]
]
;
@@ -54,8 +54,8 @@ GEXTEND Gram
[ e1 = tac2expr; ";"; e2 = tac2expr -> CTacSeq (!@loc, e1, e2) ]
| "1" LEFTA
[ e = tac2expr; el = LIST1 tac2expr LEVEL "0" -> CTacApp (!@loc, e, el)
- | e = SELF; ".("; qid = Prim.qualid; ")" -> CTacPrj (!@loc, e, qid)
- | e = SELF; ".("; qid = Prim.qualid; ")"; ":="; r = tac2expr LEVEL "1" -> CTacSet (!@loc, e, qid, r)
+ | e = SELF; ".("; qid = Prim.qualid; ")" -> CTacPrj (!@loc, e, RelId qid)
+ | e = SELF; ".("; qid = Prim.qualid; ")"; ":="; r = tac2expr LEVEL "1" -> CTacSet (!@loc, e, RelId qid, r)
| e0 = tac2expr; ","; el = LIST1 tac2expr LEVEL "1" SEP "," -> CTacTup (!@loc, e0 :: el) ]
| "0"
[ "("; a = tac2expr LEVEL "5"; ")" -> a
@@ -86,7 +86,7 @@ GEXTEND Gram
tactic_atom:
[ [ n = Prim.integer -> CTacAtm (!@loc, AtmInt n)
| s = Prim.string -> CTacAtm (!@loc, AtmStr s)
- | id = Prim.qualid -> CTacRef id
+ | id = Prim.qualid -> CTacRef (RelId id)
| IDENT "constr"; ":"; "("; c = Constr.lconstr; ")" -> inj_constr !@loc c
| IDENT "open_constr"; ":"; "("; c = Constr.lconstr; ")" -> inj_open_constr !@loc c
| IDENT "ident"; ":"; "("; c = Prim.ident; ")" -> inj_ident !@loc c
@@ -104,14 +104,14 @@ GEXTEND Gram
| "2"
[ t = tac2type; "*"; tl = LIST1 tac2type SEP "*" -> CTypTuple (!@loc, t :: tl) ]
| "1" LEFTA
- [ t = SELF; qid = Prim.qualid -> CTypRef (!@loc, qid, [t]) ]
+ [ t = SELF; qid = Prim.qualid -> CTypRef (!@loc, RelId qid, [t]) ]
| "0"
[ "("; t = tac2type LEVEL "5"; ")" -> t
| id = typ_param -> CTypVar (!@loc, Name id)
| "_" -> CTypVar (!@loc, Anonymous)
- | qid = Prim.qualid -> CTypRef (!@loc, qid, [])
+ | qid = Prim.qualid -> CTypRef (!@loc, RelId qid, [])
| "("; p = LIST1 tac2type LEVEL "5" SEP ","; ")"; qid = Prim.qualid ->
- CTypRef (!@loc, qid, p) ]
+ CTypRef (!@loc, RelId qid, p) ]
];
locident:
[ [ id = Prim.ident -> (!@loc, id) ] ]
@@ -165,7 +165,7 @@ GEXTEND Gram
| -> [] ] ]
;
tac2rec_fieldexpr:
- [ [ qid = Prim.qualid; ":="; e = tac2expr LEVEL "1" -> qid, e ] ]
+ [ [ qid = Prim.qualid; ":="; e = tac2expr LEVEL "1" -> RelId qid, e ] ]
;
tac2typ_prm:
[ [ -> []
diff --git a/tac2entries.ml b/tac2entries.ml
index c776ad13d4..374a367188 100644
--- a/tac2entries.ml
+++ b/tac2entries.ml
@@ -243,7 +243,7 @@ let register_ltac ?(local = false) isrec tactics =
| Anonymous -> None
| Name id ->
let qid = Libnames.qualid_of_ident id in
- let e = CTacLet (Loc.ghost, true, bindings, CTacRef (loc, qid)) in
+ let e = CTacLet (Loc.ghost, true, bindings, CTacRef (RelId (loc, qid))) in
let (e, t) = intern e in
let e = match e with
| GTacLet (true, _, e) -> assert false
diff --git a/tac2env.ml b/tac2env.ml
index 0fcdba1ca7..a36d022e4d 100644
--- a/tac2env.ml
+++ b/tac2env.ml
@@ -13,11 +13,6 @@ open Names
open Libnames
open Tac2expr
-type ltac_constant = KerName.t
-type ltac_constructor = KerName.t
-type ltac_projection = KerName.t
-type type_constant = KerName.t
-
type constructor_data = {
cdata_prms : int;
cdata_type : type_constant;
@@ -121,7 +116,7 @@ struct
id, (DirPath.repr dir)
end
-type tacref =
+type tacref = Tac2expr.tacref =
| TacConstant of ltac_constant
| TacConstructor of ltac_constructor
diff --git a/tac2env.mli b/tac2env.mli
index 477f4ebec7..c4b8c1e0ca 100644
--- a/tac2env.mli
+++ b/tac2env.mli
@@ -63,10 +63,6 @@ val interp_projection : ltac_projection -> projection_data
(** {5 Name management} *)
-type tacref =
-| TacConstant of ltac_constant
-| TacConstructor of ltac_constructor
-
val push_ltac : visibility -> full_path -> tacref -> unit
val locate_ltac : qualid -> tacref
val locate_extended_all_ltac : qualid -> tacref list
diff --git a/tac2expr.mli b/tac2expr.mli
index 1840b567b4..63207ac78f 100644
--- a/tac2expr.mli
+++ b/tac2expr.mli
@@ -22,6 +22,10 @@ type ltac_constructor = KerName.t
type ltac_projection = KerName.t
type type_constant = KerName.t
+type 'a or_relid =
+| RelId of qualid located
+| AbsKn of 'a
+
(** {5 Misc} *)
type ml_tactic_name = {
@@ -35,7 +39,7 @@ type raw_typexpr =
| CTypVar of Name.t located
| CTypArrow of Loc.t * raw_typexpr * raw_typexpr
| CTypTuple of Loc.t * raw_typexpr list
-| CTypRef of Loc.t * qualid located * raw_typexpr list
+| CTypRef of Loc.t * type_constant or_relid * raw_typexpr list
type raw_typedef =
| CTydDef of raw_typexpr option
@@ -66,15 +70,19 @@ type atom =
| AtmInt of int
| AtmStr of string
+type tacref =
+| TacConstant of ltac_constant
+| TacConstructor of ltac_constructor
+
(** Tactic expressions *)
type raw_patexpr =
| CPatAny of Loc.t
-| CPatRef of Loc.t * qualid located * raw_patexpr list
+| CPatRef of Loc.t * ltac_constructor or_relid * raw_patexpr list
| CPatTup of raw_patexpr list located
type raw_tacexpr =
| CTacAtm of atom located
-| CTacRef of qualid located
+| CTacRef of tacref or_relid
| CTacFun of Loc.t * (Name.t located * raw_typexpr option) list * raw_tacexpr
| CTacApp of Loc.t * raw_tacexpr * raw_tacexpr list
| CTacLet of Loc.t * rec_flag * (Name.t located * raw_typexpr option * raw_tacexpr) list * raw_tacexpr
@@ -85,13 +93,13 @@ type raw_tacexpr =
| CTacSeq of Loc.t * raw_tacexpr * raw_tacexpr
| CTacCse of Loc.t * raw_tacexpr * raw_taccase list
| CTacRec of Loc.t * raw_recexpr
-| CTacPrj of Loc.t * raw_tacexpr * qualid located
-| CTacSet of Loc.t * raw_tacexpr * qualid located * raw_tacexpr
+| CTacPrj of Loc.t * raw_tacexpr * ltac_projection or_relid
+| CTacSet of Loc.t * raw_tacexpr * ltac_projection or_relid * raw_tacexpr
| CTacExt of Loc.t * raw_generic_argument
and raw_taccase = raw_patexpr * raw_tacexpr
-and raw_recexpr = (qualid located * raw_tacexpr) list
+and raw_recexpr = (ltac_projection or_relid * raw_tacexpr) list
type case_info =
| GCaseTuple of int
diff --git a/tac2intern.ml b/tac2intern.ml
index 32d1e07c17..c7e02a7b06 100644
--- a/tac2intern.ml
+++ b/tac2intern.ml
@@ -190,7 +190,8 @@ let push_name id t env = match id with
let loc_of_tacexpr = function
| CTacAtm (loc, _) -> loc
-| CTacRef (loc, _) -> loc
+| CTacRef (RelId (loc, _)) -> loc
+| CTacRef (AbsKn _) -> Loc.ghost
| CTacFun (loc, _, _) -> loc
| CTacApp (loc, _, _) -> loc
| CTacLet (loc, _, _, _) -> loc
@@ -230,9 +231,10 @@ let rec subst_type subst (t : 'a glb_typexpr) = match t with
let rec intern_type env (t : raw_typexpr) : UF.elt glb_typexpr = match t with
| CTypVar (loc, Name id) -> GTypVar (get_alias (loc, id) env)
| CTypVar (_, Anonymous) -> GTypVar (fresh_id env)
-| CTypRef (_, (loc, qid), args) ->
- let (dp, id) = repr_qualid qid in
- let (kn, nparams) =
+| CTypRef (loc, rel, args) ->
+ let (kn, nparams) = match rel with
+ | RelId (loc, qid) ->
+ let (dp, id) = repr_qualid qid in
if DirPath.is_empty dp && Id.Map.mem id env.env_rec then
Id.Map.find id env.env_rec
else
@@ -243,10 +245,17 @@ let rec intern_type env (t : raw_typexpr) : UF.elt glb_typexpr = match t with
in
let (nparams, _) = Tac2env.interp_type kn in
(kn, nparams)
+ | AbsKn kn ->
+ let (nparams, _) = Tac2env.interp_type kn in
+ (kn, nparams)
in
let nargs = List.length args in
let () =
if not (Int.equal nparams nargs) then
+ let loc, qid = match rel with
+ | RelId lid -> lid
+ | AbsKn kn -> loc, shortest_qualid_of_type kn
+ in
user_err ~loc (strbrk "The type constructor " ++ pr_qualid qid ++
strbrk " expects " ++ int nparams ++ strbrk " argument(s), but is here \
applied to " ++ int nargs ++ strbrk "argument(s)")
@@ -467,7 +476,8 @@ let check_redundant_clause = function
| [] -> ()
| (p, _) :: _ -> warn_redundant_clause ~loc:(loc_of_patexpr p) ()
-let get_variable env (loc, qid) =
+let get_variable env var = match var with
+| RelId (loc, qid) ->
let (dp, id) = repr_qualid qid in
if DirPath.is_empty dp && Id.Map.mem id env.env_var then ArgVar (loc, id)
else
@@ -477,10 +487,12 @@ let get_variable env (loc, qid) =
CErrors.user_err ~loc (str "Unbound value " ++ pr_qualid qid)
in
ArgArg kn
+| AbsKn kn -> ArgArg kn
-let get_constructor env (loc, qid) =
+let get_constructor env var = match var with
+| RelId (loc, qid) ->
let c = try Some (Tac2env.locate_ltac qid) with Not_found -> None in
- match c with
+ begin match c with
| Some (TacConstructor knc) ->
let kn = Tac2env.interp_constructor knc in
ArgArg (kn, knc)
@@ -491,12 +503,19 @@ let get_constructor env (loc, qid) =
let (dp, id) = repr_qualid qid in
if DirPath.is_empty dp then ArgVar (loc, id)
else CErrors.user_err ~loc (str "Unbound constructor " ++ pr_qualid qid)
+ end
+| AbsKn knc ->
+ let kn = Tac2env.interp_constructor knc in
+ ArgArg (kn, knc)
-let get_projection (loc, qid) =
+let get_projection var = match var with
+| RelId (loc, qid) ->
let kn = try Tac2env.locate_projection qid with Not_found ->
user_err ~loc (pr_qualid qid ++ str " is not a projection")
in
Tac2env.interp_projection kn
+| AbsKn kn ->
+ Tac2env.interp_projection kn
let intern_atm env = function
| AtmInt n -> (GTacAtm (AtmInt n), GTypRef (t_int, []))
@@ -526,8 +545,8 @@ let rec intern_patexpr env = function
end
| CPatRef (_, qid, pl) ->
begin match get_constructor env qid with
- | ArgVar (loc, _) ->
- user_err ~loc (str "Unbound constructor " ++ pr_qualid (snd qid))
+ | ArgVar (loc, id) ->
+ user_err ~loc (str "Unbound constructor " ++ Nameops.pr_id id)
| ArgArg (_, kn) -> GPatRef (kn, List.map (fun p -> intern_patexpr env p) pl)
end
| CPatTup (_, pl) ->
@@ -565,7 +584,7 @@ let is_constructor env qid = match get_variable env qid with
let rec intern_rec env = function
| CTacAtm (_, atm) -> intern_atm env atm
-| CTacRef qid ->
+| CTacRef qid as e ->
begin match get_variable env qid with
| ArgVar (_, id) ->
let sch = Id.Map.find id env.env_var in
@@ -574,7 +593,8 @@ let rec intern_rec env = function
let (_, _, sch) = Tac2env.interp_global kn in
(GTacRef kn, fresh_type_scheme env sch)
| ArgArg (TacConstructor kn) ->
- intern_constructor env (fst qid) kn []
+ let loc = loc_of_tacexpr e in
+ intern_constructor env loc kn []
end
| CTacFun (loc, bnd, e) ->
let fold (env, bnd, tl) ((_, na), t) =
@@ -590,12 +610,13 @@ let rec intern_rec env = function
let (e, t) = intern_rec env e in
let t = List.fold_left (fun accu t -> GTypArrow (t, accu)) t tl in
(GTacFun (bnd, e), t)
-| CTacApp (loc, CTacRef qid, args) when is_constructor env qid ->
+| CTacApp (loc, CTacRef qid, args) as e when is_constructor env qid ->
let kn = match get_variable env qid with
| ArgArg (TacConstructor kn) -> kn
| _ -> assert false
in
- intern_constructor env (fst qid) kn args
+ let loc = loc_of_tacexpr e in
+ intern_constructor env loc kn args
| CTacApp (loc, f, args) ->
let (f, ft) = intern_rec env f in
let fold arg (args, t) =
@@ -687,7 +708,10 @@ let rec intern_rec env = function
let pinfo = get_projection proj in
let () =
if not pinfo.pdata_mutb then
- let (loc, _) = proj in
+ let loc = match proj with
+ | RelId (loc, _) -> loc
+ | AbsKn _ -> Loc.ghost
+ in
user_err ~loc (str "Field is not mutable")
in
let subst = Array.init pinfo.pdata_prms (fun _ -> fresh_id env) in
@@ -974,8 +998,12 @@ and intern_constructor env loc kn args =
error_nargs_mismatch loc nargs (List.length args)
and intern_record env loc fs =
- let map ((loc, qid), e) =
- let proj = get_projection (loc, qid) in
+ let map (proj, e) =
+ let loc = match proj with
+ | RelId (loc, _) -> loc
+ | AbsKn _ -> Loc.ghost
+ in
+ let proj = get_projection proj in
(loc, proj, e)
in
let fs = List.map map fs in