diff options
| author | Pierre-Marie Pédrot | 2016-03-31 17:16:38 +0200 |
|---|---|---|
| committer | Pierre-Marie Pédrot | 2016-03-31 17:25:13 +0200 |
| commit | f5e85670b9c106fbde736654c32f4042c6a39d3f (patch) | |
| tree | 0401dc223bd6ef2ee0e60cb02c394a2fb9773139 /ltac | |
| parent | c0aefc5323cb4393297adcaffd2967ab93ab815e (diff) | |
Moving the Tactic Notation entry parser from Pcoq to Tacentries.
Diffstat (limited to 'ltac')
| -rw-r--r-- | ltac/tacentries.ml | 109 |
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 |
