aboutsummaryrefslogtreecommitdiffhomepage
path: root/toplevel
diff options
context:
space:
mode:
Diffstat (limited to 'toplevel')
-rw-r--r--toplevel/metasyntax.ml207
1 files changed, 134 insertions, 73 deletions
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index d406bf8d9..a67400788 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -62,24 +62,26 @@ let rec make_tags = function
| GramNonTerminal (loc, etyp, _, po) :: l -> etyp :: make_tags l
| [] -> []
-let cache_tactic_notation (_,(local,pa,pp)) =
- Egramcoq.extend_grammar (Egramcoq.TacticGrammar pa);
- Pptactic.declare_extra_tactic_pprule pp
+type tactic_grammar_obj = {
+ tacobj_local : locality_flag;
+ tacobj_tacgram : tactic_grammar;
+ tacobj_tacpp : Pptactic.pp_tactic;
+}
-let subst_tactic_parule subst (key,n,p,(d,tac)) =
- (key,n,p,(d,Tacinterp.subst_tactic subst tac))
+let cache_tactic_notation (_, tobj) =
+ Egramcoq.extend_grammar (Egramcoq.TacticGrammar tobj.tacobj_tacgram);
+ Pptactic.declare_extra_tactic_pprule tobj.tacobj_tacpp
-let subst_tactic_notation (subst,(local,pa,pp)) =
- (local,subst_tactic_parule subst pa,pp)
+let subst_tactic_parule subst tg =
+ let dir, tac = tg.tacgram_tactic in
+ { tg with tacgram_tactic = (dir, Tacinterp.subst_tactic subst tac); }
-let classify_tactic_notation (local,_,_ as o) =
- if local then Dispose else Substitute o
+let subst_tactic_notation (subst, tobj) =
+ { tobj with
+ tacobj_tacgram = subst_tactic_parule subst tobj.tacobj_tacgram; }
-type tactic_grammar_obj =
- locality_flag
- * (string * int * grammar_prod_item list *
- (dir_path * Tacexpr.glob_tactic_expr))
- * (string * Genarg.argument_type list * (int * Pptactic.grammar_terminals))
+let classify_tactic_notation tacobj =
+ if tacobj.tacobj_local then Dispose else Substitute tacobj
let inTacticGrammar : tactic_grammar_obj -> obj =
declare_object {(default_object "TacticGrammar") with
@@ -105,11 +107,25 @@ let add_tactic_notation (local,n,prods,e) =
let prods = List.map (interp_prod_item n) prods in
let tags = make_tags prods in
let key = next_key_away (tactic_notation_key prods) tags in
- let pprule = (key,tags,(n,List.map make_terminal_status prods)) in
+ let pprule = {
+ Pptactic.pptac_key = key;
+ pptac_args = tags;
+ pptac_prods = (n, List.map make_terminal_status prods);
+ } in
let ids = List.fold_left cons_production_parameter [] prods in
let tac = Tacinterp.glob_tactic_env ids (Global.env()) e in
- let parule = (key,n,prods,(Lib.cwd(),tac)) in
- Lib.add_anonymous_leaf (inTacticGrammar (local,parule,pprule))
+ let parule = {
+ tacgram_key = key;
+ tacgram_level = n;
+ tacgram_prods = prods;
+ tacgram_tactic = (Lib.cwd (), tac);
+ } in
+ let tacobj = {
+ tacobj_local = local;
+ tacobj_tacgram = parule;
+ tacobj_tacpp = pprule;
+ } in
+ Lib.add_anonymous_leaf (inTacticGrammar tacobj)
(**********************************************************************)
(* Printing grammar entries *)
@@ -702,7 +718,19 @@ let error_incompatible_level ntn oldprec prec =
spc() ++ str "while it is now required to be" ++ spc() ++
pr_level ntn prec ++ str ".")
-let cache_one_syntax_extension (typs,prec,ntn,gr,pp) =
+type syntax_extension = {
+ synext_intern : notation_var_internalization_type list;
+ synext_level : Notation.level;
+ synext_notation : notation;
+ synext_notgram : notation_grammar;
+ synext_unparsing : unparsing list;
+}
+
+type syntax_extension_obj = locality_flag * syntax_extension list
+
+let cache_one_syntax_extension se =
+ let ntn = se.synext_notation in
+ let prec = se.synext_level in
try
let oldprec = Notation.level_of_notation ntn in
if prec <> oldprec then error_incompatible_level ntn oldprec prec
@@ -710,34 +738,30 @@ let cache_one_syntax_extension (typs,prec,ntn,gr,pp) =
(* Reserve the notation level *)
Notation.declare_notation_level ntn prec;
(* Declare the parsing rule *)
- Egramcoq.extend_grammar (Egramcoq.Notation (prec,typs,gr));
+ Egramcoq.extend_grammar (Egramcoq.Notation (prec, se.synext_intern, se.synext_notgram));
(* Declare the printing rule *)
- Notation.declare_notation_printing_rule ntn (pp,fst prec)
+ Notation.declare_notation_printing_rule ntn (se.synext_unparsing, fst prec)
-let cache_syntax_extension (_,(_,sy_rules)) =
- List.iter cache_one_syntax_extension sy_rules
+let cache_syntax_extension (_, (_, sy)) =
+ List.iter cache_one_syntax_extension sy
let subst_parsing_rule subst x = x
let subst_printing_rule subst x = x
-let subst_syntax_extension (subst,(local,sy)) =
- (local, List.map (fun (typs,prec,ntn,gr,pp) ->
- (typs,prec,ntn,subst_parsing_rule subst gr,subst_printing_rule subst pp))
- sy)
+let subst_syntax_extension (subst, (local, sy)) =
+ let map sy = { sy with
+ synext_notgram = subst_parsing_rule subst sy.synext_notgram;
+ synext_unparsing = subst_printing_rule subst sy.synext_unparsing;
+ } in
+ (local, List.map map sy)
-let classify_syntax_definition (local,_ as o) =
+let classify_syntax_definition (local, _ as o) =
if local then Dispose else Substitute o
-type syntax_extension_obj =
- locality_flag *
- (notation_var_internalization_type list * Notation.level *
- notation * notation_grammar * unparsing list)
- list
-
let inSyntaxExtension : syntax_extension_obj -> obj =
declare_object {(default_object "SYNTAX-EXTENSION") with
- open_function = (fun i o -> if i=1 then cache_syntax_extension o);
+ open_function = (fun i o -> if i = 1 then cache_syntax_extension o);
cache_function = cache_syntax_extension;
subst_function = subst_syntax_extension;
classify_function = classify_syntax_definition}
@@ -928,7 +952,7 @@ let remove_curly_brackets l =
| x :: l -> x :: aux false l
in aux true l
-let compute_syntax_data (df,modifiers) =
+let compute_syntax_data df modifiers =
let (assoc,n,etyps,onlyparse,fmt) = interp_modifiers modifiers in
let assoc = match assoc with None -> (* default *) Some NonA | a -> a in
let toks = split_notation_string df in
@@ -958,8 +982,8 @@ let compute_syntax_data (df,modifiers) =
(* Return relevant data for interpretation and for parsing/printing *)
(msgs,i_data,i_typs,sy_fulldata)
-let compute_pure_syntax_data (df,mods) =
- let (msgs,(onlyparse,_,_,_),_,sy_data) = compute_syntax_data (df,mods) in
+let compute_pure_syntax_data df mods =
+ let (msgs,(onlyparse,_,_,_),_,sy_data) = compute_syntax_data df mods in
let msgs =
if onlyparse then
(msg_warning,
@@ -970,31 +994,38 @@ let compute_pure_syntax_data (df,mods) =
(**********************************************************************)
(* Registration of notations interpretation *)
-let load_notation _ (_,(_,scope,pat,onlyparse,_)) =
- Option.iter Notation.declare_scope scope
-
-let open_notation i (_,(_,scope,pat,onlyparse,(ntn,df))) =
- if i=1 & not (Notation.exists_notation_in_scope scope ntn pat) then begin
+type notation_obj = {
+ notobj_local : bool;
+ notobj_scope : scope_name option;
+ notobj_interp : interpretation;
+ notobj_onlyparse : bool;
+ notobj_notation : notation * notation_location;
+}
+
+let load_notation _ (_, nobj) =
+ Option.iter Notation.declare_scope nobj.notobj_scope
+
+let open_notation i (_, nobj) =
+ let scope = nobj.notobj_scope in
+ let (ntn, df) = nobj.notobj_notation in
+ let pat = nobj.notobj_interp in
+ if i = 1 & not (Notation.exists_notation_in_scope scope ntn pat) then begin
(* Declare the interpretation *)
Notation.declare_notation_interpretation ntn scope pat df;
(* Declare the uninterpretation *)
- if not onlyparse then
- Notation.declare_uninterpretation (NotationRule (scope,ntn)) pat
+ if not nobj.notobj_onlyparse then
+ Notation.declare_uninterpretation (NotationRule (scope, ntn)) pat
end
let cache_notation o =
load_notation 1 o;
open_notation 1 o
-let subst_notation (subst,(lc,scope,pat,b,ndf)) =
- (lc,scope,subst_interpretation subst pat,b,ndf)
-
-let classify_notation (local,_,_,_,_ as o) =
- if local then Dispose else Substitute o
+let subst_notation (subst, nobj) =
+ { nobj with notobj_interp = subst_interpretation subst nobj.notobj_interp; }
-type notation_obj =
- bool * scope_name option * interpretation * bool *
- (notation * notation_location)
+let classify_notation nobj =
+ if nobj.notobj_local then Dispose else Substitute nobj
let inNotation : notation_obj -> obj =
declare_object {(default_object "NOTATION") with
@@ -1038,18 +1069,25 @@ let recover_syntax ntn =
try
let prec = Notation.level_of_notation ntn in
let pp_rule,_ = Notation.find_notation_printing_rule ntn in
- let typs,pa_rule = Egramcoq.recover_notation_grammar ntn prec in
- (typs,prec,ntn,pa_rule,pp_rule)
+ let typs, pa_rule = Egramcoq.recover_notation_grammar ntn prec in
+ { synext_intern = typs;
+ synext_level = prec;
+ synext_notation = ntn;
+ synext_notgram = pa_rule;
+ synext_unparsing = pp_rule; }
with Not_found ->
raise NoSyntaxRule
-let recover_squash_syntax () = recover_syntax "{ _ }"
+let recover_squash_syntax sy =
+ let sq = recover_syntax "{ _ }" in
+ [sy; sq]
let recover_notation_syntax rawntn =
let ntn = contract_notation rawntn in
- let (typs,_,_,_,_ as sy_rule) = recover_syntax ntn in
- let need_squash = ntn<>rawntn in
- typs,if need_squash then [sy_rule; recover_squash_syntax ()] else [sy_rule]
+ let sy = recover_syntax ntn in
+ let need_squash = ntn <> rawntn in
+ let rules = if need_squash then recover_squash_syntax sy else [sy] in
+ sy.synext_intern, rules
(**********************************************************************)
(* Main entry point for building parsing and printing rules *)
@@ -1057,39 +1095,55 @@ let recover_notation_syntax rawntn =
let make_pa_rule (n,typs,symbols,_) ntn =
let assoc = recompute_assoc typs in
let prod = make_production typs symbols in
- (n,assoc,ntn,prod)
+ { notgram_level = n;
+ notgram_assoc = assoc;
+ notgram_notation = ntn;
+ notgram_prods = prod; }
let make_pp_rule (n,typs,symbols,fmt) =
match fmt with
| None -> [UnpBox (PpHOVB 0, make_hunks typs symbols n)]
- | Some fmt -> hunks_of_format (n,List.split typs) (symbols,parse_format fmt)
+ | Some fmt -> hunks_of_format (n, List.split typs) (symbols, parse_format fmt)
let make_syntax_rules (i_typs,ntn,prec,need_squash,sy_data) =
let pa_rule = make_pa_rule sy_data ntn in
let pp_rule = make_pp_rule sy_data in
- let sy_rule = (i_typs,prec,ntn,pa_rule,pp_rule) in
+ let sy = {
+ synext_intern = i_typs;
+ synext_level = prec;
+ synext_notation = ntn;
+ synext_notgram = pa_rule;
+ synext_unparsing = pp_rule;
+ } in
(* By construction, the rule for "{ _ }" is declared, but we need to
redeclare it because the file where it is declared needs not be open
when the current file opens (especially in presence of -nois) *)
- if need_squash then [sy_rule; recover_squash_syntax ()] else [sy_rule]
+ if need_squash then recover_squash_syntax sy else [sy]
(**********************************************************************)
(* Main functions about notations *)
let add_notation_in_scope local df c mods scope =
- let (msgs,i_data,i_typs,sy_data) = compute_syntax_data (df,mods) in
+ let (msgs,i_data,i_typs,sy_data) = compute_syntax_data df mods in
(* Prepare the parsing and printing rules *)
let sy_rules = make_syntax_rules sy_data in
(* Prepare the interpretation *)
- let (onlyparse,recvars,mainvars,df') = i_data in
+ let (onlyparse, recvars,mainvars, df') = i_data in
let i_vars = make_internalization_vars recvars mainvars i_typs in
- let (acvars,ac) = interp_notation_constr i_vars recvars c in
- let a = (make_interpretation_vars recvars acvars,ac) in
- let onlyparse = onlyparse or is_not_printable ac in
+ let (acvars, ac) = interp_notation_constr i_vars recvars c in
+ let interp = make_interpretation_vars recvars acvars in
+ let onlyparse = onlyparse || is_not_printable ac in
+ let notation = {
+ notobj_local = local;
+ notobj_scope = scope;
+ notobj_interp = (interp, ac);
+ notobj_onlyparse = onlyparse;
+ notobj_notation = df';
+ } in
(* Ready to change the global state *)
Flags.if_verbose (List.iter (fun (f,x) -> f x)) msgs;
- Lib.add_anonymous_leaf (inSyntaxExtension(local,sy_rules));
- Lib.add_anonymous_leaf (inNotation (local,scope,a,onlyparse,df'));
+ Lib.add_anonymous_leaf (inSyntaxExtension (local, sy_rules));
+ Lib.add_anonymous_leaf (inNotation notation);
df'
let add_notation_interpretation_core local df ?(impls=empty_internalization_env) c scope onlyparse =
@@ -1105,15 +1159,22 @@ let add_notation_interpretation_core local df ?(impls=empty_internalization_env)
let df' = (make_notation_key symbs,(path,df)) in
let i_vars = make_internalization_vars recvars mainvars i_typs in
let (acvars,ac) = interp_notation_constr ~impls i_vars recvars c in
- let a = (make_interpretation_vars recvars acvars,ac) in
- let onlyparse = onlyparse or is_not_printable ac in
- Lib.add_anonymous_leaf (inNotation (local,scope,a,onlyparse,df'));
+ let interp = make_interpretation_vars recvars acvars in
+ let onlyparse = onlyparse || is_not_printable ac in
+ let notation = {
+ notobj_local = local;
+ notobj_scope = scope;
+ notobj_interp = (interp, ac);
+ notobj_onlyparse = onlyparse;
+ notobj_notation = df';
+ } in
+ Lib.add_anonymous_leaf (inNotation notation);
df'
(* Notations without interpretation (Reserved Notation) *)
let add_syntax_extension local ((loc,df),mods) =
- let msgs,sy_data = compute_pure_syntax_data (df,mods) in
+ let msgs, sy_data = compute_pure_syntax_data df mods in
let sy_rules = make_syntax_rules sy_data in
Flags.if_verbose (List.iter (fun (f,x) -> f x)) msgs;
Lib.add_anonymous_leaf (inSyntaxExtension(local,sy_rules))