Skip to content

Commit 89ad33f

Browse files
committed
Separate interpretation and syntax declaration in tactic notations
This is a step towards #15409.
1 parent 6ee8252 commit 89ad33f

File tree

13 files changed

+221
-94
lines changed

13 files changed

+221
-94
lines changed

doc/tools/docgram/common.edit_mlg

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,8 +2115,6 @@ ltac2_occs_nums: [
21152115
ltac2_entry: [
21162116
| REPLACE tac2def_typ (* Ltac2 plugin *)
21172117
| WITH "Ltac2" tac2def_typ
2118-
| REPLACE tac2def_syn (* Ltac2 plugin *)
2119-
| WITH "Ltac2" tac2def_syn
21202118
| REPLACE tac2def_mut (* Ltac2 plugin *)
21212119
| WITH "Ltac2" tac2def_mut
21222120
| REPLACE tac2def_val (* Ltac2 plugin *)
@@ -2145,6 +2143,7 @@ SPLICE: [
21452143
| tac2def_typ
21462144
| tac2def_ext
21472145
| tac2def_syn
2146+
| ltac2def_syn
21482147
| tac2def_mut
21492148
| rec_flag
21502149
| locident

doc/tools/docgram/fullGrammar

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ command: [
697697
| "Number" "Notation" reference reference reference OPT number_options ":" preident
698698
| "String" "Notation" reference reference reference OPT string_option ":" preident
699699
| "Ltac2" ltac2_entry (* ltac2 plugin *)
700+
| "Ltac2" "Notation" ltac2def_syn (* ltac2 plugin *)
700701
| "Ltac2" "Eval" ltac2_expr6 (* ltac2 plugin *)
701702
| "Print" "Ltac2" reference (* ltac2 plugin *)
702703
| "Locate" "Ltac2" reference (* ltac2 plugin *)
@@ -3561,7 +3562,7 @@ syn_level: [
35613562
]
35623563

35633564
tac2def_syn: [
3564-
| "Notation" LIST1 ltac2_scope syn_level ":=" ltac2_expr6 (* ltac2 plugin *)
3565+
| LIST1 ltac2_scope syn_level ":=" ltac2_expr6 (* ltac2 plugin *)
35653566
]
35663567

35673568
lident: [
@@ -3938,10 +3939,13 @@ ltac2_entry: [
39383939
| tac2def_val (* ltac2 plugin *)
39393940
| tac2def_typ (* ltac2 plugin *)
39403941
| tac2def_ext (* ltac2 plugin *)
3941-
| tac2def_syn (* ltac2 plugin *)
39423942
| tac2def_mut (* ltac2 plugin *)
39433943
]
39443944

3945+
ltac2def_syn: [
3946+
| tac2def_syn (* ltac2 plugin *)
3947+
]
3948+
39453949
ltac2_expr: [
39463950
| _ltac2_expr (* ltac2 plugin *)
39473951
]

doc/tools/docgram/orderedGrammar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ command: [
11181118
| "Ltac2" OPT "mutable" OPT "rec" tac2def_body LIST0 ( "with" tac2def_body )
11191119
| "Ltac2" "Type" OPT "rec" tac2typ_def LIST0 ( "with" tac2typ_def )
11201120
| "Ltac2" "@" "external" ident ":" ltac2_type ":=" string string
1121-
| "Ltac2" "Notation" LIST1 ltac2_scope OPT ( ":" natural ) ":=" ltac2_expr
1121+
| "Ltac2" "Notation" LIST1 ltac2_scope OPT ( ":" natural ) ":=" ltac2_expr (* ltac2 plugin *)
11221122
| "Ltac2" "Set" qualid OPT [ "as" ident ] ":=" ltac2_expr
11231123
| "Ltac2" "Notation" [ string | lident ] ":=" ltac2_expr (* Ltac2 plugin *)
11241124
| "Ltac2" "Eval" ltac2_expr (* ltac2 plugin *)

plugins/ltac/g_ltac.mlg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,9 @@ VERNAC COMMAND EXTEND VernacTacticNotation
467467
{ VtSideff ([], VtNow) } ->
468468
{
469469
let n = Option.default 0 n in
470-
Tacentries.add_tactic_notation (Locality.make_module_locality locality) n ?deprecation r e;
470+
let local = Locality.make_module_locality locality in
471+
let tacobj = Tacentries.add_tactic_notation_syntax local n ?deprecation r in
472+
Tacentries.add_tactic_notation ?deprecation tacobj e
471473
}
472474
END
473475

plugins/ltac/tacentries.ml

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,6 @@ type tactic_grammar_obj = {
251251
tacobj_key : KerName.t;
252252
tacobj_local : locality_flag;
253253
tacobj_tacgram : tactic_grammar;
254-
tacobj_body : Tacenv.alias_tactic;
255254
tacobj_forml : bool;
256255
}
257256

@@ -265,71 +264,103 @@ let check_key key =
265264
user_err Pp.(str "Conflicting tactic notations keys. This can happen when including \
266265
twice the same module.")
267266

268-
let cache_tactic_notation tobj =
267+
let cache_tactic_notation (tobj, body) =
269268
let key = tobj.tacobj_key in
270269
let () = check_key key in
271-
Tacenv.register_alias key tobj.tacobj_body;
272-
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram;
273-
Pptactic.declare_notation_tactic_pprule key (pprule tobj.tacobj_tacgram)
270+
Tacenv.register_alias key body
274271

275-
let open_tactic_notation i tobj =
276-
let key = tobj.tacobj_key in
277-
if Int.equal i 1 && not tobj.tacobj_local then
278-
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
272+
let open_tactic_notation i _ = ()
279273

280-
let load_tactic_notation i tobj =
274+
let load_tactic_notation i (tobj, body) =
281275
let key = tobj.tacobj_key in
282276
let () = check_key key in
283277
(* Only add the printing and interpretation rules. *)
284-
Tacenv.register_alias key tobj.tacobj_body;
285-
Pptactic.declare_notation_tactic_pprule key (pprule tobj.tacobj_tacgram);
286-
if Int.equal i 1 && not tobj.tacobj_local then
287-
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
278+
Tacenv.register_alias key body
288279

289-
let subst_tactic_notation (subst, tobj) =
280+
let subst_tactic_notation (subst, (tobj, body)) =
290281
let open Tacenv in
291-
let alias = tobj.tacobj_body in
292282
{ tobj with
293-
tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key;
294-
tacobj_body = { alias with alias_body = Tacsubst.subst_tactic subst alias.alias_body };
295-
}
283+
tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key
284+
},
285+
{ body with alias_body = Tacsubst.subst_tactic subst body.alias_body }
296286

297287
let classify_tactic_notation tacobj = Substitute
298288

299289
let ltac_notation_cat = Libobject.create_category "ltac.notations"
300290

301-
let inTacticGrammar : tactic_grammar_obj -> obj =
291+
let inTacticGrammar : tactic_grammar_obj * Tacenv.alias_tactic -> obj =
302292
declare_object {(default_object "TacticGrammar") with
303293
open_function = simple_open ~cat:ltac_notation_cat open_tactic_notation;
304294
load_function = load_tactic_notation;
305295
cache_function = cache_tactic_notation;
306296
subst_function = subst_tactic_notation;
307297
classify_function = classify_tactic_notation}
308298

299+
let cache_tactic_syntax tobj =
300+
let key = tobj.tacobj_key in
301+
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram;
302+
Pptactic.declare_notation_tactic_pprule key (pprule tobj.tacobj_tacgram)
303+
304+
let open_tactic_syntax i tobj =
305+
let key = tobj.tacobj_key in
306+
if Int.equal i 1 && not tobj.tacobj_local then
307+
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
308+
309+
let load_tactic_syntax i tobj =
310+
let key = tobj.tacobj_key in
311+
(* Only add the printing and interpretation rules. *)
312+
Pptactic.declare_notation_tactic_pprule key (pprule tobj.tacobj_tacgram);
313+
if Int.equal i 1 && not tobj.tacobj_local then
314+
extend_tactic_grammar key tobj.tacobj_forml tobj.tacobj_tacgram
315+
316+
let subst_tactic_syntax (subst, tobj) =
317+
{ tobj with
318+
tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key
319+
}
320+
321+
let classify_tactic_syntax tacobj = Substitute
322+
323+
let inTacticSyntax : tactic_grammar_obj -> obj =
324+
declare_object {(default_object "TacticSyntax") with
325+
object_stage = Summary.Stage.Synterp;
326+
open_function = simple_open ~cat:ltac_notation_cat open_tactic_syntax;
327+
load_function = load_tactic_syntax;
328+
cache_function = cache_tactic_syntax;
329+
subst_function = subst_tactic_syntax;
330+
classify_function = classify_tactic_syntax}
331+
309332
let cons_production_parameter = function
310333
| TacTerm _ -> None
311334
| TacNonTerm (_, (_, ido)) -> ido
312335

313-
let add_glob_tactic_notation local ~level ?deprecation prods forml ids tac =
336+
let add_glob_tactic_notation ?deprecation tacobj ids tac =
337+
let open Tacenv in
338+
let body =
339+
{ alias_args = ids; alias_body = tac; alias_deprecation = deprecation } in
340+
Lib.add_leaf (inTacticGrammar (tacobj, body))
341+
342+
let add_glob_tactic_notation_syntax local ~level ?deprecation prods forml =
314343
let parule = {
315344
tacgram_level = level;
316345
tacgram_prods = prods;
317346
} in
318-
let open Tacenv in
319347
let tacobj = {
320348
tacobj_key = make_fresh_key prods;
321349
tacobj_local = local;
322350
tacobj_tacgram = parule;
323-
tacobj_body = { alias_args = ids; alias_body = tac; alias_deprecation = deprecation };
324351
tacobj_forml = forml;
325352
} in
326-
Lib.add_leaf (inTacticGrammar tacobj)
353+
Lib.add_leaf (inTacticSyntax tacobj);
354+
tacobj
327355

328-
let add_tactic_notation local n ?deprecation prods e =
329-
let ids = List.map_filter cons_production_parameter prods in
330-
let prods = List.map interp_prod_item prods in
356+
let add_tactic_notation ?deprecation tacobj e =
357+
let ids = List.map_filter cons_production_parameter tacobj.tacobj_tacgram.tacgram_prods in
331358
let tac = Tacintern.glob_tactic_env ids (Global.env()) e in
332-
add_glob_tactic_notation local ~level:n ?deprecation prods false ids tac
359+
add_glob_tactic_notation ?deprecation tacobj ids tac
360+
361+
let add_tactic_notation_syntax local n ?deprecation prods =
362+
let prods = List.map interp_prod_item prods in
363+
add_glob_tactic_notation_syntax local ~level:n ?deprecation prods false
333364

334365
(**********************************************************************)
335366
(* ML Tactic entries *)
@@ -381,7 +412,8 @@ let add_ml_tactic_notation name ~level ?deprecation prods =
381412
let entry = { mltac_name = name; mltac_index = len - i - 1 } in
382413
let map id = Reference (Locus.ArgVar (CAst.make id)) in
383414
let tac = CAst.make (TacML (entry, List.map map ids)) in
384-
add_glob_tactic_notation false ~level ?deprecation prods true ids tac
415+
let tacobj = add_glob_tactic_notation_syntax false ~level ?deprecation prods true in
416+
add_glob_tactic_notation ?deprecation tacobj ids tac
385417
in
386418
List.iteri iter (List.rev prods);
387419
(* We call [extend_atomic_tactic] only for "basic tactics" (the ones

plugins/ltac/tacentries.mli

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type 'a grammar_tactic_prod_item_expr = 'a Pptactic.grammar_tactic_prod_item_exp
2525
| TacTerm of string
2626
| TacNonTerm of ('a * Names.Id.t option) Loc.located
2727

28+
type tactic_grammar_obj
29+
2830
type raw_argument = string * string option
2931
(** An argument type as provided in Tactic notations, i.e. a string like
3032
"ne_foo_list_opt" together with a separator that only makes sense in the
@@ -35,12 +37,17 @@ type argument = Genarg.ArgT.any Extend.user_symbol
3537
leaves. *)
3638

3739
val add_tactic_notation :
38-
locality_flag -> int -> ?deprecation:Deprecation.t -> raw_argument
39-
grammar_tactic_prod_item_expr list -> raw_tactic_expr -> unit
40+
?deprecation:Deprecation.t -> tactic_grammar_obj ->
41+
raw_tactic_expr -> unit
4042
(** [add_tactic_notation local level prods expr] adds a tactic notation in the
4143
environment at level [level] with locality [local] made of the grammar
4244
productions [prods] and returning the body [expr] *)
4345

46+
val add_tactic_notation_syntax :
47+
locality_flag -> int -> ?deprecation:Deprecation.t -> raw_argument
48+
grammar_tactic_prod_item_expr list ->
49+
tactic_grammar_obj
50+
4451
val register_tactic_notation_entry : string -> ('a, 'b, 'c) Genarg.genarg_type -> unit
4552
(** Register an argument under a given entry name for tactic notations. When
4653
translating [raw_argument] into [argument], atomic names will be first

plugins/ltac2/g_ltac2.mlg

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,9 @@ GRAMMAR EXTEND Gram
437437
] ]
438438
;
439439
tac2def_syn:
440-
[ [ "Notation"; toks = LIST1 ltac2_scope; n = syn_level; ":=";
440+
[ [ toks = LIST1 ltac2_scope; n = syn_level; ":=";
441441
e = ltac2_expr ->
442-
{ StrSyn (toks, n, e) }
442+
{ (toks, n, e) }
443443
] ]
444444
;
445445
lident:
@@ -960,27 +960,29 @@ PRINTED BY { pr_ltac2entry }
960960
| [ tac2def_val(v) ] -> { v }
961961
| [ tac2def_typ(t) ] -> { t }
962962
| [ tac2def_ext(e) ] -> { e }
963-
| [ tac2def_syn(e) ] -> { e }
964963
| [ tac2def_mut(e) ] -> { e }
965964
END
966965

966+
VERNAC ARGUMENT EXTEND ltac2def_syn
967+
PRINTED BY { pr_ltac2entry }
968+
| [ tac2def_syn(e) ] -> { e }
969+
END
970+
967971
VERNAC ARGUMENT EXTEND ltac2_expr
968972
PRINTED BY { pr_ltac2expr }
969973
| [ _ltac2_expr(e) ] -> { e }
970974
END
971975

972-
{
973-
974-
let classify_ltac2 = function
975-
| StrSyn _ -> Vernacextend.(VtSideff ([], VtNow))
976-
| StrMut _ | StrVal _ | StrPrm _ | StrTyp _ -> Vernacextend.classify_as_sideeff
977-
978-
}
979-
980976
VERNAC COMMAND EXTEND VernacDeclareTactic2Definition
981-
| #[ raw_attributes ] [ "Ltac2" ltac2_entry(e) ] => { classify_ltac2 e } -> {
977+
| #[ raw_attributes ] [ "Ltac2" ltac2_entry(e) ] => { Vernacextend.classify_as_sideeff } -> {
982978
Tac2entries.register_struct raw_attributes e
983979
}
980+
| #[ raw_attributes ] [ "Ltac2" "Notation" ltac2def_syn(e) ] => { Vernacextend.(VtSideff ([], VtNow)) } ->
981+
{
982+
let (toks, n, body) = e in
983+
let synterpv = Tac2entries.register_notation raw_attributes toks n body in
984+
Tac2entries.register_notation_interpretation synterpv
985+
}
984986
| ![proof_opt_query] [ "Ltac2" "Eval" ltac2_expr(e) ] => { Vernacextend.classify_as_query } -> {
985987
fun ~pstate -> Tac2entries.perform_eval ~pstate e
986988
}

0 commit comments

Comments
 (0)