aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--contrib/interface/xlate.ml2
-rw-r--r--parsing/astterm.ml123
-rw-r--r--parsing/g_basevernac.ml46
-rw-r--r--parsing/symbols.ml72
-rw-r--r--parsing/symbols.mli6
-rw-r--r--toplevel/vernacentries.ml4
-rw-r--r--toplevel/vernacexpr.ml1
7 files changed, 141 insertions, 73 deletions
diff --git a/contrib/interface/xlate.ml b/contrib/interface/xlate.ml
index d8663f09d..5060b17a8 100644
--- a/contrib/interface/xlate.ml
+++ b/contrib/interface/xlate.ml
@@ -1908,6 +1908,8 @@ let xlate_vernac =
coerce_ID_OPT_to_FORMULA_OPT(CT_coerce_NONE_to_ID_OPT(CT_none)))*)
| VernacOpenScope sc -> xlate_error "TODO: open scope"
+ | VernacArgumentsScope _ -> xlate_error "TODO: Arguments Scope"
+
| VernacDelimiters _ -> xlate_error "TODO: Delimiters"
| VernacNotation _ -> xlate_error "TODO: Notation"
diff --git a/parsing/astterm.ml b/parsing/astterm.ml
index 03e652cce..40c2162da 100644
--- a/parsing/astterm.ml
+++ b/parsing/astterm.ml
@@ -30,6 +30,7 @@ open Evarutil
open Ast
open Coqast
open Nametab
+open Symbols
(*Takes a list of variables which must not be globalized*)
let from_list l = List.fold_right Idset.add l Idset.empty
@@ -246,30 +247,22 @@ let maybe_constructor allow_var env = function
| _ -> anomaly "ast_to_pattern: badly-formed ast for Cases pattern"
-let ast_to_global loc c =
- match c with
- | ("CONST", [sp]) ->
- let ref = ConstRef (ast_to_sp sp) in
- let imps = implicits_of_global ref in
- RRef (loc, ref), imps
- | ("SECVAR", [Nvar (_,s)]) ->
- let ref = VarRef s in
- let imps = implicits_of_global ref in
- RRef (loc, ref), imps
- | ("MUTIND", [sp;Num(_,tyi)]) ->
- let ref = IndRef (ast_to_sp sp, tyi) in
- let imps = implicits_of_global ref in
- RRef (loc, ref), imps
- | ("MUTCONSTRUCT", [sp;Num(_,ti);Num(_,n)]) ->
- let ref = ConstructRef ((ast_to_sp sp,ti),n) in
- let imps = implicits_of_global ref in
- RRef (loc, ref), imps
- | ("EVAR", [(Num (_,ev))]) ->
- REvar (loc, ev), []
- | ("SYNCONST", [sp]) ->
- Syntax_def.search_syntactic_definition loc (ast_to_sp sp), []
- | _ -> anomaly_loc (loc,"ast_to_global",
- (str "Bad ast for this global a reference"))
+let ast_to_global loc = function
+ | ("SYNCONST", [sp]) ->
+ Syntax_def.search_syntactic_definition loc (ast_to_sp sp), [], []
+ | ("EVAR", [(Num (_,ev))]) ->
+ REvar (loc, ev), [], []
+ | ast ->
+ let ref = match ast with
+ | ("CONST", [sp]) -> ConstRef (ast_to_sp sp)
+ | ("SECVAR", [Nvar (_,s)]) -> VarRef s
+ | ("MUTIND", [sp;Num(_,tyi)]) -> IndRef (ast_to_sp sp, tyi)
+ | ("MUTCONSTRUCT", [sp;Num(_,ti);Num(_,n)]) ->
+ ConstructRef ((ast_to_sp sp,ti),n)
+ | _ -> anomaly_loc (loc,"ast_to_global",
+ (str "Bad ast for this global a reference"))
+ in
+ RRef (loc, ref), implicits_of_global ref, find_arguments_scope ref
(*
let ref_from_constr c = match kind_of_term c with
@@ -286,29 +279,29 @@ let ref_from_constr c = match kind_of_term c with
abstracted until this point *)
let ast_to_var (env,impls,_) (vars1,vars2) loc id =
- let imps =
+ let imps, subscopes =
if Idset.mem id env or List.mem id vars1
then
- try List.assoc id impls
- with Not_found -> []
+ try List.assoc id impls, []
+ with Not_found -> [], []
else
let _ = lookup_named id vars2 in
(* Car Fixpoint met les fns définies tmporairement comme vars de sect *)
try
let ref = VarRef id in
- implicits_of_global ref
- with _ -> []
- in RVar (loc, id), imps
+ implicits_of_global ref, find_arguments_scope ref
+ with _ -> [], []
+ in RVar (loc, id), imps, subscopes
(**********************************************************************)
let rawconstr_of_var env vars loc id =
try
- ast_to_var env vars loc id
+ let (r,_,_) = ast_to_var env vars loc id in r
with Not_found ->
Pretype_errors.error_var_not_found_loc loc id
-let rawconstr_of_qualid env vars loc qid =
+let rawconstr_of_qualid_gen env vars loc qid =
(* Is it a bound variable? *)
try
match repr_qualid qid with
@@ -319,13 +312,15 @@ let rawconstr_of_qualid env vars loc qid =
try match Nametab.extended_locate qid with
| TrueGlobal ref ->
if !dump then add_glob loc ref;
- let imps = implicits_of_global ref in
- RRef (loc, ref), imps
+ RRef (loc, ref), implicits_of_global ref, find_arguments_scope ref
| SyntacticDef sp ->
- Syntax_def.search_syntactic_definition loc sp, []
+ Syntax_def.search_syntactic_definition loc sp, [], []
with Not_found ->
error_global_not_found_loc loc qid
+let rawconstr_of_qualid env vars loc qid =
+ let (r,_,_) = rawconstr_of_qualid_gen env vars loc qid in r
+
let mkLambdaC (x,a,b) = ope("LAMBDA",[a;slam(Some x,b)])
let mkLambdaCit = List.fold_right (fun (x,a) b -> mkLambdaC(x,a,b))
let mkProdC (x,a,b) = ope("PROD",[a;slam(Some x,b)])
@@ -335,6 +330,11 @@ let destruct_binder = function
| Node(_,"BINDER",c::idl) -> List.map (fun id -> (nvar_of_ast id,c)) idl
| _ -> anomaly "BINDER is expected"
+let apply_scope_env (ids,impls,scopes as env) = function
+ | [] -> env, []
+ | (Some sc)::scl -> (ids,impls,sc::scopes), scl
+ | None::scl -> env, scl
+
(* [merge_aliases] returns the sets of all aliases encountered at this
point and a substitution mapping extra aliases to the first one *)
let merge_aliases (ids,subst as aliases) = function
@@ -442,10 +442,10 @@ let build_expression loc1 loc2 (ref,impls) args =
let ast_to_rawconstr sigma env allow_soapp lvar =
let rec dbrec (ids,impls,scopes as env) = function
| Nvar(loc,s) ->
- fst (rawconstr_of_var env lvar loc s)
+ rawconstr_of_var env lvar loc s
| Node(loc,"QUALID", l) ->
- fst (rawconstr_of_qualid env lvar loc (interp_qualid l))
+ rawconstr_of_qualid env lvar loc (interp_qualid l)
| Node(loc,"FIX", (Nvar (locid,iddef))::ldecl) ->
let (lf,ln,lA,lt) = ast_to_fix ldecl in
@@ -501,21 +501,26 @@ let ast_to_rawconstr sigma env allow_soapp lvar =
dbrec (ids,impls,sc::scopes) e
| Node(loc,"APPLISTEXPL", f::args) ->
- RApp (loc,dbrec env f,ast_to_args env args)
+ let (f,_,subscopes) = match f with
+ | Node(locs,"QUALID",p) ->
+ rawconstr_of_qualid_gen env lvar locs (interp_qualid p)
+ | _ ->
+ (dbrec env f, [], []) in
+ RApp (loc,f,ast_to_args env subscopes args)
| Node(loc,"APPLIST", f::args) ->
- let (c, impargs) =
+ let (c, impargs, subscopes) =
match f with
| Node(locs,"QUALID",p) ->
- rawconstr_of_qualid env lvar locs (interp_qualid p)
+ rawconstr_of_qualid_gen env lvar locs (interp_qualid p)
(* For globalized references (e.g. in Infix) *)
| Node(loc,
("CONST"|"SECVAR"|"EVAR"|"MUTIND"|"MUTCONSTRUCT"|"SYNCONST" as key),
l) ->
ast_to_global loc (key,l)
- | _ -> (dbrec env f, [])
+ | _ -> (dbrec env f, [], [])
in
- RApp (loc, c, ast_to_impargs c env impargs args)
+ RApp (loc, c, ast_to_impargs c env impargs subscopes args)
| Node(loc,"CASES", p:: Node(_,"TOMATCH",tms):: eqns) ->
let po = match p with
@@ -545,7 +550,7 @@ let ast_to_rawconstr sigma env allow_soapp lvar =
(* This case mainly parses things build in a quotation *)
| Node(loc,("CONST"|"SECVAR"|"EVAR"|"MUTIND"|"MUTCONSTRUCT"|"SYNCONST" as key),l) ->
- fst (ast_to_global loc (key,l))
+ let (r,_,_) = ast_to_global loc (key,l) in r
| Node(loc,"CAST", [c1;c2]) ->
RCast (loc,dbrec env c1,dbrec env c2)
@@ -602,14 +607,16 @@ let ast_to_rawconstr sigma env allow_soapp lvar =
| _ -> assert false)
| body -> dbrec env body
- and ast_to_impargs c env l args =
- let rec aux n l args = match (l,args) with
+ and ast_to_impargs c env l subscopes args =
+ let rec aux n l subscopes args =
+ let (enva,subscopes') = apply_scope_env env subscopes in
+ match (l,args) with
| (i::l',Node(loc, "EXPL", [Num(_,j);a])::args') ->
if i=n & j>=i then
- if j=i then
- (dbrec env a)::(aux (n+1) l' args')
+ if j=i then
+ (dbrec enva a)::(aux (n+1) l' subscopes' args')
else
- (RHole (set_hole_implicit i c))::(aux (n+1) l' args)
+ (RHole (set_hole_implicit i c))::(aux (n+1) l' subscopes' args)
else
if i<>n then
error ("Bad explicitation number: found "^
@@ -619,19 +626,21 @@ let ast_to_rawconstr sigma env allow_soapp lvar =
(string_of_int j)^" but was expecting "^(string_of_int i))
| (i::l',a::args') ->
if i=n then
- (RHole (set_hole_implicit i c))::(aux (n+1) l' args)
+ (RHole (set_hole_implicit i c))::(aux (n+1) l' subscopes' args)
else
- (dbrec env a)::(aux (n+1) l args')
- | ([],args) -> ast_to_args env args
+ (dbrec enva a)::(aux (n+1) l subscopes' args')
+ | ([],args) -> ast_to_args env subscopes args
| (_,[]) -> []
in
- aux 1 l args
+ aux 1 l subscopes args
- and ast_to_args env = function
+ and ast_to_args env subscopes = function
| Node(loc, "EXPL", _)::args' ->
(* To deal with errors *)
error_expl_impl_loc loc
- | a::args -> (dbrec env a) :: (ast_to_args env args)
+ | a::args ->
+ let enva, subscopes = apply_scope_env env subscopes in
+ (dbrec enva a) :: (ast_to_args env subscopes args)
| [] -> []
and interp_binding env = function
@@ -643,7 +652,7 @@ let ast_to_rawconstr sigma env allow_soapp lvar =
errorlabstrm "bind_interp"
(str "Not the expected form in binding" ++ print_ast x)
- in
+ in
dbrec env
(**************************************************************************)
@@ -781,7 +790,9 @@ let constrOut = function
(str "Not a Dynamic ast: " ++ print_ast ast)
let interp_global_constr env (loc,qid) =
- let c,_ = rawconstr_of_qualid (Idset.empty,[],Symbols.current_scopes()) ([],env) loc qid in
+ let c =
+ rawconstr_of_qualid (Idset.empty,[],current_scopes()) ([],env) loc qid
+ in
understand Evd.empty env c
let interp_constr sigma env c =
diff --git a/parsing/g_basevernac.ml4 b/parsing/g_basevernac.ml4
index bac489217..4b5c98ba7 100644
--- a/parsing/g_basevernac.ml4
+++ b/parsing/g_basevernac.ml4
@@ -223,6 +223,9 @@ GEXTEND Gram
| IDENT "Delimiters"; left = STRING; sc = IDENT; right = STRING ->
VernacDelimiters (sc,(left,right))
+ | IDENT "Arguments"; IDENT "Scope"; qid = qualid;
+ "["; scl = LIST0 opt_scope; "]" -> VernacArgumentsScope (qid,scl)
+
(* Faudrait une version de qualidarg dans Prim pour respecter l'ordre *)
| IDENT "Infix"; a = entry_prec; n = natural; op = STRING; p = qualid;
sc = OPT [ ":"; sc = IDENT -> sc ] -> VernacInfix (a,n,op,p,sc)
@@ -235,6 +238,9 @@ GEXTEND Gram
to factorize with other "Print"-based vernac entries *)
] ]
;
+ opt_scope:
+ [ [ IDENT "_" -> None | sc = IDENT -> Some sc ] ]
+ ;
(* Syntax entries for Grammar. Only grammar_entry is exported *)
grammar_entry:
[[ nont = located_ident; etyp = set_entry_type; ":=";
diff --git a/parsing/symbols.ml b/parsing/symbols.ml
index e13fd3df4..075cd322d 100644
--- a/parsing/symbols.ml
+++ b/parsing/symbols.ml
@@ -78,13 +78,18 @@ let lookup_numeral_interpreter s =
(* For loading without opening *)
let declare_scope scope =
try let _ = Stringmap.find scope !scope_map in ()
- with Not_found -> scope_map := Stringmap.add scope empty_scope !scope_map
+ with Not_found ->
+(* Options.if_verbose message ("Creating scope "^scope);*)
+ scope_map := Stringmap.add scope empty_scope !scope_map
+
+let find_scope scope =
+ try Stringmap.find scope !scope_map
+ with Not_found -> error ("Scope "^scope^" is not declared")
+
+let check_scope sc = let _ = find_scope sc in ()
let declare_delimiters scope dlm =
- let sc =
- try Stringmap.find scope !scope_map
- with Not_found -> empty_scope
- in
+ let sc = find_scope scope in
if sc.delimiters <> None && Options.is_verbose () then
warning ("Overwriting previous delimiters in "^scope);
let sc = { sc with delimiters = Some dlm } in
@@ -93,10 +98,7 @@ let declare_delimiters scope dlm =
(* The mapping between notations and production *)
let declare_notation nt c scope =
- let sc =
- try Stringmap.find scope !scope_map
- with Not_found -> empty_scope
- in
+ let sc = find_scope scope in
if Stringmap.mem nt sc.notations && Options.is_verbose () then
warning ("Notation "^nt^" is already used in scope "^scope);
let sc = { sc with notations = Stringmap.add nt c sc.notations } in
@@ -110,7 +112,7 @@ let rec subst_meta_rawconstr subst = function
let rec find_interpretation f = function
| scope::scopes ->
- (try f (Stringmap.find scope !scope_map)
+ (try f (find_scope scope)
with Not_found -> find_interpretation f scopes)
| [] -> raise Not_found
@@ -224,10 +226,8 @@ let rec interp_numeral_as_pattern loc n name = function
(* Exportation of scopes *)
let cache_scope (_,sc) =
- if Stringmap.mem sc !scope_map then
- scope_stack := sc :: !scope_stack
- else
- error ("Unknown scope: "^sc)
+ check_scope sc;
+ scope_stack := sc :: !scope_stack
let subst_scope (_,subst,sc) = sc
@@ -243,13 +243,51 @@ let (inScope,outScope) =
let open_scope sc = Lib.add_anonymous_leaf (inScope sc)
+
+(* Special scopes associated to arguments of a global reference *)
+
+open Libnames
+
+module RefOrdered =
+ struct
+ type t = global_reference
+ let compare = Pervasives.compare
+ end
+
+module Refmap = Map.Make(RefOrdered)
+
+let arguments_scope = ref Refmap.empty
+
+let cache_arguments_scope (_,(r,scl)) =
+ List.iter (option_iter check_scope) scl;
+ arguments_scope := Refmap.add r scl !arguments_scope
+
+let subst_arguments_scope (_,subst,(r,scl)) = (subst_global subst r,scl)
+
+let (inArgumentsScope,outArgumentsScope) =
+ declare_object {(default_object "ARGUMENTS-SCOPE") with
+ cache_function = cache_arguments_scope;
+ open_function = (fun i o -> if i=1 then cache_arguments_scope o);
+ subst_function = subst_arguments_scope;
+ classify_function = (fun (_,o) -> Substitute o);
+ export_function = (fun x -> Some x) }
+
+let declare_arguments_scope r scl =
+ Lib.add_anonymous_leaf (inArgumentsScope (r,scl))
+
+let find_arguments_scope r =
+ try Refmap.find r !arguments_scope
+ with Not_found -> []
+
+
(* Synchronisation with reset *)
-let freeze () = (!scope_map, !scope_stack)
+let freeze () = (!scope_map, !scope_stack, !arguments_scope)
-let unfreeze (scm,scs) =
+let unfreeze (scm,scs,asc) =
scope_map := scm;
- scope_stack := scs
+ scope_stack := scs;
+ arguments_scope := asc
let init () = ()
(*
diff --git a/parsing/symbols.mli b/parsing/symbols.mli
index c0d8eea29..d8edb3179 100644
--- a/parsing/symbols.mli
+++ b/parsing/symbols.mli
@@ -46,3 +46,9 @@ val find_notation : scope_name -> notation -> scopes ->
(delimiters option * scopes) option
val exists_notation_in_scope : scope_name -> notation -> bool
val exists_notation : notation -> bool
+
+(* Declare and look for scopes associated to arguments of a global ref *)
+open Libnames
+val declare_arguments_scope: global_reference -> scope_name option list -> unit
+val find_arguments_scope : global_reference -> scope_name option list
+
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index b0f53b839..b3825dd93 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -289,6 +289,9 @@ let vernac_delimiters = Metasyntax.add_delimiters
let vernac_open_scope = Symbols.open_scope
+let vernac_arguments_scope qid scl =
+ Symbols.declare_arguments_scope (global qid) scl
+
let vernac_infix assoc n inf qid sc =
let sp = sp_of_global None (global qid) in
let dir = repr_dirpath (dirpath sp) in
@@ -1032,6 +1035,7 @@ let interp c = match c with
| VernacGrammar (univ,al) -> vernac_grammar univ al
| VernacDelimiters (sc,lr) -> vernac_delimiters sc lr
| VernacOpenScope sc -> vernac_open_scope sc
+ | VernacArgumentsScope (qid,scl) -> vernac_arguments_scope qid scl
| VernacInfix (assoc,n,inf,qid,sc) -> vernac_infix assoc n inf qid sc
| VernacDistfix (assoc,n,inf,qid,sc) -> vernac_distfix assoc n inf qid sc
| VernacNotation (assoc,n,inf,c,sc) -> vernac_notation assoc n inf c sc
diff --git a/toplevel/vernacexpr.ml b/toplevel/vernacexpr.ml
index e0f0dc00e..d2ad10bb6 100644
--- a/toplevel/vernacexpr.ml
+++ b/toplevel/vernacexpr.ml
@@ -186,6 +186,7 @@ type vernac_expr =
| VernacSyntax of string * syntax_entry_ast list
| VernacOpenScope of scope_name
| VernacDelimiters of scope_name * (string * string)
+ | VernacArgumentsScope of qualid located * scope_name option list
| VernacInfix of
grammar_associativity * int * string * qualid located * scope_name option
| VernacDistfix of