aboutsummaryrefslogtreecommitdiff
path: root/ltac
diff options
context:
space:
mode:
authorPierre-Marie Pédrot2016-03-31 17:16:38 +0200
committerPierre-Marie Pédrot2016-03-31 17:25:13 +0200
commitf5e85670b9c106fbde736654c32f4042c6a39d3f (patch)
tree0401dc223bd6ef2ee0e60cb02c394a2fb9773139 /ltac
parentc0aefc5323cb4393297adcaffd2967ab93ab815e (diff)
Moving the Tactic Notation entry parser from Pcoq to Tacentries.
Diffstat (limited to 'ltac')
-rw-r--r--ltac/tacentries.ml109
1 files changed, 109 insertions, 0 deletions
diff --git a/ltac/tacentries.ml b/ltac/tacentries.ml
index 711cd8d9d0..e247a138dd 100644
--- a/ltac/tacentries.ml
+++ b/ltac/tacentries.ml
@@ -11,6 +11,7 @@ open Errors
open Util
open Names
open Libobject
+open Genarg
open Pcoq
open Egramml
open Egramcoq
@@ -19,6 +20,114 @@ open Libnames
open Nameops
(**********************************************************************)
+(* Interpret entry names of the form "ne_constr_list" as entry keys *)
+
+let coincide s pat off =
+ let len = String.length pat in
+ let break = ref true in
+ let i = ref 0 in
+ while !break && !i < len do
+ let c = Char.code s.[off + !i] in
+ let d = Char.code pat.[!i] in
+ break := Int.equal c d;
+ incr i
+ done;
+ !break
+
+let atactic n =
+ let open Extend in
+ if n = 5 then Aentry (name_of_entry Tactic.binder_tactic)
+ else Aentryl (name_of_entry Tactic.tactic_expr, n)
+
+type entry_name = EntryName :
+ 'a raw_abstract_argument_type * (Tacexpr.raw_tactic_expr, 'a) Extend.symbol -> entry_name
+
+let try_get_entry u s =
+ let open Extend in
+ (** Order the effects: get_entry can raise Not_found *)
+ let TypedEntry (typ, e) = get_entry u s in
+ EntryName (typ, Aentry (name_of_entry e))
+
+(** Quite ad-hoc *)
+let get_tacentry n m =
+ let open Extend in
+ let check_lvl n =
+ Int.equal m n
+ && not (Int.equal m 5) (* Because tactic5 is at binder_tactic *)
+ && not (Int.equal m 0) (* Because tactic0 is at simple_tactic *)
+ in
+ if check_lvl n then EntryName (rawwit Constrarg.wit_tactic, Aself)
+ else if check_lvl (n + 1) then EntryName (rawwit Constrarg.wit_tactic, Anext)
+ else EntryName (rawwit Constrarg.wit_tactic, atactic n)
+
+let rec parse_user_entry s sep =
+ let open Extend in
+ let l = String.length s in
+ if l > 8 && coincide s "ne_" 0 && coincide s "_list" (l - 5) then
+ let entry = parse_user_entry (String.sub s 3 (l-8)) "" in
+ Ulist1 entry
+ else if l > 12 && coincide s "ne_" 0 &&
+ coincide s "_list_sep" (l-9) then
+ let entry = parse_user_entry (String.sub s 3 (l-12)) "" in
+ Ulist1sep (entry, sep)
+ else if l > 5 && coincide s "_list" (l-5) then
+ let entry = parse_user_entry (String.sub s 0 (l-5)) "" in
+ Ulist0 entry
+ else if l > 9 && coincide s "_list_sep" (l-9) then
+ let entry = parse_user_entry (String.sub s 0 (l-9)) "" in
+ Ulist0sep (entry, sep)
+ else if l > 4 && coincide s "_opt" (l-4) then
+ let entry = parse_user_entry (String.sub s 0 (l-4)) "" in
+ Uopt entry
+ else if l > 5 && coincide s "_mods" (l-5) then
+ let entry = parse_user_entry (String.sub s 0 (l-1)) "" in
+ Umodifiers entry
+ else if Int.equal l 7 && coincide s "tactic" 0 && '5' >= s.[6] && s.[6] >= '0' then
+ let n = Char.code s.[6] - 48 in
+ Uentryl ("tactic", n)
+ else
+ let s = match s with "hyp" -> "var" | _ -> s in
+ Uentry s
+
+let arg_list = function Rawwit t -> Rawwit (ListArg t)
+let arg_opt = function Rawwit t -> Rawwit (OptArg t)
+
+let interp_entry_name up_level s sep =
+ let open Extend in
+ let rec eval = function
+ | Ulist1 e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist1 g)
+ | Ulist1sep (e, sep) ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist1sep (g, sep))
+ | Ulist0 e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist0 g)
+ | Ulist0sep (e, sep) ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist0sep (g, sep))
+ | Uopt e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_opt t, Aopt g)
+ | Umodifiers e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Amodifiers g)
+ | Uentry s ->
+ begin
+ try try_get_entry uprim s with Not_found ->
+ try try_get_entry uconstr s with Not_found ->
+ try try_get_entry utactic s with Not_found ->
+ error ("Unknown entry "^s^".")
+ end
+ | Uentryl (s, n) ->
+ (** FIXME: do better someday *)
+ assert (String.equal s "tactic");
+ get_tacentry n up_level
+ in
+ eval (parse_user_entry s sep)
+
+(**********************************************************************)
(* Tactic Notation *)
let interp_prod_item lev = function