aboutsummaryrefslogtreecommitdiffhomepage
path: root/parsing
diff options
context:
space:
mode:
authorGravatar barras <barras@85f007b7-540e-0410-9357-904b9bb8a0f7>2003-03-12 17:49:21 +0000
committerGravatar barras <barras@85f007b7-540e-0410-9357-904b9bb8a0f7>2003-03-12 17:49:21 +0000
commitcb1ae314411d78952062e5092804b85d981ad6e1 (patch)
tree52b9a4058c89b5849d875a4c1129951f35e9c1b1 /parsing
parent7cb6a61133b6e3c2cd5601282a1f472ff0104c1f (diff)
*** empty log message ***
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@3761 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'parsing')
-rw-r--r--parsing/argextend.ml427
-rwxr-xr-xparsing/ast.ml20
-rw-r--r--parsing/egrammar.ml52
-rw-r--r--parsing/egrammar.mli6
-rw-r--r--parsing/extend.ml3
-rw-r--r--parsing/g_basevernac.ml463
-rw-r--r--parsing/g_cases.ml46
-rw-r--r--parsing/g_constr.ml468
-rw-r--r--parsing/g_constrnew.ml4256
-rw-r--r--parsing/g_ltac.ml48
-rw-r--r--parsing/g_ltacnew.ml4209
-rw-r--r--parsing/g_natsyntaxnew.ml195
-rw-r--r--parsing/g_natsyntaxnew.mli11
-rw-r--r--parsing/g_prim.ml42
-rw-r--r--parsing/g_primnew.ml4143
-rw-r--r--parsing/g_proofs.ml42
-rw-r--r--parsing/g_proofsnew.ml4126
-rw-r--r--parsing/g_rsyntax.ml8
-rw-r--r--parsing/g_rsyntaxnew.ml113
-rw-r--r--parsing/g_tactic.ml410
-rw-r--r--parsing/g_tacticnew.ml4355
-rw-r--r--parsing/g_vernac.ml417
-rw-r--r--parsing/g_vernacnew.ml4817
-rw-r--r--parsing/g_zsyntax.ml10
-rw-r--r--parsing/g_zsyntaxnew.ml168
-rw-r--r--parsing/g_zsyntaxnew.mli11
-rw-r--r--parsing/lexer.ml458
-rw-r--r--parsing/pcoq.ml493
-rw-r--r--parsing/pcoq.mli6
-rw-r--r--parsing/ppconstr.ml85
-rw-r--r--parsing/ppconstr.mli6
-rw-r--r--parsing/pptactic.ml116
-rw-r--r--parsing/pptactic.mli23
-rw-r--r--parsing/prettyp.ml6
-rw-r--r--parsing/printer.ml154
-rw-r--r--parsing/printer.mli10
-rw-r--r--parsing/q_coqast.ml45
-rw-r--r--parsing/search.ml2
-rw-r--r--parsing/tacextend.ml456
39 files changed, 2970 insertions, 356 deletions
diff --git a/parsing/argextend.ml4 b/parsing/argextend.ml4
index 576c57a53..4d6edda0e 100644
--- a/parsing/argextend.ml4
+++ b/parsing/argextend.ml4
@@ -78,7 +78,7 @@ let make_rule loc (prods,act) =
let (symbs,pil) = List.split prods in
<:expr< ($mlexpr_of_list (fun x -> x) symbs$,$make_act loc act pil$) >>
-let declare_tactic_argument loc s typ pr f rawtyppr cl =
+let declare_tactic_argument for_v8 loc s typ pr f rawtyppr cl =
let interp = match f with
| None -> <:expr< Tacinterp.genarg_interp >>
| Some f -> <:expr< $lid:f$>> in
@@ -103,12 +103,13 @@ let declare_tactic_argument loc s typ pr f rawtyppr cl =
Pcoq.Gram.extend ($lid:s$ : Pcoq.Gram.Entry.e 'a) None
[(None, None, $rules$)];
Pptactic.declare_extra_genarg_pprule
+ $mlexpr_of_bool for_v8$
($rawwit$, $lid:rawpr$)
($wit$, $lid:pr$);
end
>>
-let declare_vernac_argument loc s cl =
+let declare_vernac_argument for_v8 loc s cl =
let se = mlexpr_of_string s in
let typ = ExtraArgType s in
let wit = <:expr< $lid:"wit_"^s$ >> in
@@ -173,13 +174,31 @@ EXTEND
"END" ->
if String.capitalize s = s then
failwith "Argument entry names must be lowercase";
- declare_tactic_argument loc s typ pr f rawtyppr l
+ declare_tactic_argument true loc s typ pr f rawtyppr l
| "VERNAC"; "ARGUMENT"; "EXTEND"; s = [ UIDENT | LIDENT ];
OPT "|"; l = LIST1 argrule SEP "|";
"END" ->
if String.capitalize s = s then
failwith "Argument entry names must be lowercase";
- declare_vernac_argument loc s l ] ]
+ declare_vernac_argument true loc s l
+ | "V7"; "ARGUMENT"; "EXTEND"; s = [ UIDENT | LIDENT ];
+ "TYPED"; "AS"; typ = argtype;
+ "PRINTED"; "BY"; pr = LIDENT;
+ f = OPT [ "INTERPRETED"; "BY"; f = LIDENT -> f ];
+ rawtyppr =
+ OPT [ "RAW"; "TYPED"; "AS"; t = argtype;
+ "RAW"; "PRINTED"; "BY"; pr = LIDENT -> (t,pr) ];
+ OPT "|"; l = LIST1 argrule SEP "|";
+ "END" ->
+ if String.capitalize s = s then
+ failwith "Argument entry names must be lowercase";
+ declare_tactic_argument false loc s typ pr f rawtyppr l
+ | "V7"; "VERNAC"; "ARGUMENT"; "EXTEND"; s = [ UIDENT | LIDENT ];
+ OPT "|"; l = LIST1 argrule SEP "|";
+ "END" ->
+ if String.capitalize s = s then
+ failwith "Argument entry names must be lowercase";
+ declare_vernac_argument false loc s l ] ]
;
argtype:
[ [ e = LIDENT -> fst (interp_entry_name loc e) ] ]
diff --git a/parsing/ast.ml b/parsing/ast.ml
index 13989bcbb..1b68f69bf 100755
--- a/parsing/ast.ml
+++ b/parsing/ast.ml
@@ -122,21 +122,35 @@ type grammar_action =
type env = (string * typed_ast) list
+let string_of_dirpath = function
+ | [] -> "<empty>"
+ | sl ->
+ String.concat "." (List.map string_of_id (List.rev sl))
+
+let pr_id id = str (string_of_id id)
+
+let print_kn kn =
+ let (mp,dp,l) = repr_kn kn in
+ let dpl = repr_dirpath dp in
+ str (string_of_mp mp) ++ str "." ++
+ prlist_with_sep (fun _ -> str".") pr_id dpl ++
+ str (string_of_label l)
+
(* Pretty-printing *)
let rec print_ast ast =
match ast with
| Num(_,n) -> int n
| Str(_,s) -> qs s
- | Path(_,sl) -> str (string_of_kn sl)
+ | Path(_,sl) -> print_kn sl
| Id (_,s) -> str "{" ++ str s ++ str "}"
- | Nvar(_,s) -> str (string_of_id s)
+ | Nvar(_,s) -> pr_id s
| Nmeta(_,s) -> str s
| Node(_,op,l) ->
hov 3 (str "(" ++ str op ++ spc () ++ print_astl l ++ str ")")
| Slam(_,None,ast) -> hov 1 (str "[<>]" ++ print_ast ast)
| Slam(_,Some x,ast) ->
hov 1
- (str "[" ++ str (string_of_id x) ++ str "]" ++ cut () ++
+ (str "[" ++ pr_id x ++ str "]" ++ cut () ++
print_ast ast)
| Smetalam(_,id,ast) -> hov 1 (str id ++ print_ast ast)
| Dynamic(_,d) ->
diff --git a/parsing/egrammar.ml b/parsing/egrammar.ml
index 192f84d6b..77ac447c9 100644
--- a/parsing/egrammar.ml
+++ b/parsing/egrammar.ml
@@ -42,11 +42,26 @@ let assoc_level = function
| _ -> ""
let constr_level = function
- | 8,assoc -> assert (assoc <> Gramext.LeftA); "top"
| n,assoc -> (string_of_int n)^(assoc_level assoc)
-let default_levels = [8,Gramext.RightA; 1,Gramext.RightA; 0,Gramext.RightA]
-let level_stack = ref [default_levels]
+let default_levels_v7 =
+ [10,Gramext.RightA;
+ 9,Gramext.RightA;
+ 8,Gramext.RightA;
+ 1,Gramext.RightA;
+ 0,Gramext.RightA]
+
+let default_levels_v8 =
+ [200,Gramext.RightA;
+ 100,Gramext.RightA;
+ 80,Gramext.RightA;
+ 40,Gramext.LeftA;
+ 10,Gramext.LeftA;
+ 9,Gramext.RightA;
+ 1,Gramext.LeftA;
+ 0,Gramext.RightA]
+
+let level_stack = ref [default_levels_v7]
(* At a same level, LeftA takes precedence over RightA and NoneA *)
(* In case, several associativity exists for a level, we make two levels, *)
@@ -65,15 +80,17 @@ let create_assoc = function
| Some a -> a
let find_position other assoc lev =
+ let default =
+ if !Options.v7 then (10,Gramext.RightA) else (200,Gramext.RightA) in
let current = List.hd !level_stack in
match lev with
| None ->
level_stack := current :: !level_stack;
None, (if other then assoc else None), None
| Some n ->
- if n = 8 & assoc = Some Gramext.LeftA then
+ if !Options.v7 & n = 8 & assoc = Some Gramext.LeftA then
error "Left associativity not allowed at level 8";
- let after = ref (8,Gramext.RightA) in
+ let after = ref default in
let rec add_level q = function
| (p,_ as pa)::l when p > n -> pa :: add_level pa l
| (p,a as pa)::l as l' when p = n ->
@@ -92,7 +109,7 @@ let find_position other assoc lev =
try
(* Create the entry *)
let current = List.hd !level_stack in
- level_stack := add_level (8,Gramext.RightA) current :: !level_stack;
+ level_stack := add_level default current :: !level_stack;
let assoc = create_assoc assoc in
Some (Gramext.After (constr_level !after)),
Some assoc, Some (constr_level (n,assoc))
@@ -347,7 +364,7 @@ let extend_constr_notation (n,assoc,ntn,rule) =
let extend_constr_delimiters (sc,rule,pat_rule) =
let mkact loc env = CDelimiters (loc,sc,snd (List.hd env)) in
- extend_constr Constr.constr (ETConstr(0,()),Some 0,Some Gramext.NonA,false)
+ extend_constr Constr.operconstr (ETConstr(0,()),Some 0,Some Gramext.NonA,false)
(make_act mkact) rule;
let mkact loc env = CPatDelimiters (loc,sc,snd (List.hd env)) in
extend_constr Constr.pattern (ETPattern,None,None,false)
@@ -361,13 +378,21 @@ let make_rule univ f g (s,pt) =
let act = make_gen_act f ntl in
(symbs, act)
+let tac_exts = ref []
+let get_extend_tactic_grammars () = !tac_exts
+
let extend_tactic_grammar s gl =
+ tac_exts := (s,gl) :: !tac_exts;
let univ = get_univ "tactic" in
let make_act loc l = Tacexpr.TacExtend (loc,s,List.map snd l) in
let rules = List.map (make_rule univ make_act make_prod_item) gl in
Gram.extend Tactic.simple_tactic None [(None, None, List.rev rules)]
+let vernac_exts = ref []
+let get_extend_vernac_grammars () = !vernac_exts
+
let extend_vernac_command_grammar s gl =
+ vernac_exts := (s,gl) :: !vernac_exts;
let univ = get_univ "vernac" in
let make_act loc l = Vernacexpr.VernacExtend (s,List.map snd l) in
let rules = List.map (make_rule univ make_act make_prod_item) gl in
@@ -418,6 +443,15 @@ let extend_grammar gram =
| TacticGrammar l -> add_tactic_entries l);
grammar_state := gram :: !grammar_state
+let reset_extend_grammars_v8 () =
+ let te = List.rev !tac_exts in
+ let tv = List.rev !vernac_exts in
+ tac_exts := [];
+ vernac_exts := [];
+ List.iter (fun (s,gl) -> extend_tactic_grammar s gl) te;
+ List.iter (fun (s,gl) -> extend_vernac_command_grammar s gl) tv;
+ level_stack := [default_levels_v8]
+
(* Summary functions: the state of the lexer is included in that of the parser.
Because the grammar affects the set of keywords when adding or removing
@@ -448,12 +482,10 @@ let unfreeze (grams, lex) =
grammar_state := common;
Lexer.unfreeze lex;
List.iter extend_grammar (List.rev redo)
-
+
let init_grammar () =
remove_grammars (number_of_entries !grammar_state);
grammar_state := []
-let _ = Lexer.init ()
-
let init () =
init_grammar ()
diff --git a/parsing/egrammar.mli b/parsing/egrammar.mli
index d24264abc..091f98424 100644
--- a/parsing/egrammar.mli
+++ b/parsing/egrammar.mli
@@ -42,5 +42,11 @@ val extend_tactic_grammar :
val extend_vernac_command_grammar :
string -> (string * grammar_tactic_production list) list -> unit
+val get_extend_tactic_grammars :
+ unit -> (string * (string * grammar_tactic_production list) list) list
+val get_extend_vernac_grammars :
+ unit -> (string * (string * grammar_tactic_production list) list) list
+val reset_extend_grammars_v8 : unit -> unit
+
val subst_all_grammar_command :
Names.substitution -> all_grammar_command -> all_grammar_command
diff --git a/parsing/extend.ml b/parsing/extend.ml
index 14a33a656..076f7f026 100644
--- a/parsing/extend.ml
+++ b/parsing/extend.ml
@@ -175,7 +175,8 @@ let explicitize_prod_entry pos univ nt =
| "constr5" -> ETConstr (5,pos)
| "constr6" -> ETConstr (6,pos)
| "constr7" -> ETConstr (7,pos)
- | "constr8" | "constr" -> ETConstr (8,pos)
+ | "constr8" -> ETConstr (8,pos)
+ | "constr" when !Options.v7 -> ETConstr (8,pos)
| "constr9" -> ETConstr (9,pos)
| "constr10" | "lconstr" -> ETConstr (10,pos)
| "pattern" -> ETPattern
diff --git a/parsing/g_basevernac.ml4 b/parsing/g_basevernac.ml4
index 683b2ae54..a1208f48c 100644
--- a/parsing/g_basevernac.ml4
+++ b/parsing/g_basevernac.ml4
@@ -18,6 +18,15 @@ open Goptions
open Constr
open Prim
+let vernac_kw =
+ [ "Quit"; "Load"; "Compile"; "Fixpoint"; "CoFixpoint";
+ "Definition"; "Inductive"; "CoInductive";
+ "Theorem"; "Variable"; "Axiom"; "Parameter"; "Hypothesis";
+ "."; ">->" ]
+let _ = List.iter (fun s -> Lexer.add_token ("",s)) vernac_kw
+
+let class_rawexpr = Gram.Entry.create "vernac:class_rawexpr"
+
GEXTEND Gram
GLOBAL: class_rawexpr;
@@ -155,7 +164,7 @@ GEXTEND Gram
[ [ IDENT "Term"; qid = global -> PrintName qid
| IDENT "All" -> PrintFullContext
| IDENT "Section"; s = global -> PrintSectionContext s
- | "Grammar"; uni = IDENT; ent = IDENT ->
+ | IDENT "Grammar"; uni = IDENT; ent = IDENT ->
(* This should be in "syntax" section but is here for factorization*)
PrintGrammar (uni, ent)
| IDENT "LoadPath" -> PrintLoadPath
@@ -213,19 +222,19 @@ GEXTEND Gram
[ [ IDENT "Token"; s = STRING ->
Pp.warning "Token declarations are now useless"; VernacNop
- | "Grammar"; IDENT "tactic"; IDENT "simple_tactic";
+ | IDENT "Grammar"; IDENT "tactic"; IDENT "simple_tactic";
OPT [ ":"; IDENT "tactic" ]; ":=";
OPT "|"; tl = LIST0 grammar_tactic_rule SEP "|" ->
VernacTacticGrammar tl
- | "Grammar"; u = univ;
+ | IDENT "Grammar"; u = univ;
tl = LIST1 grammar_entry SEP "with" ->
VernacGrammar (rename_command_entry u,tl)
- | "Syntax"; u = univ; el = LIST1 syntax_entry SEP ";" ->
+ | IDENT "Syntax"; u = univ; el = LIST1 syntax_entry SEP ";" ->
VernacSyntax (u,el)
- | "Uninterpreted"; IDENT "Notation"; s = STRING;
+ | IDENT "Uninterpreted"; IDENT "Notation"; s = STRING;
l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]
-> VernacSyntaxExtension (s,l)
@@ -237,19 +246,46 @@ GEXTEND Gram
| IDENT "Arguments"; IDENT "Scope"; qid = global;
"["; scl = LIST0 opt_scope; "]" -> VernacArgumentsScope (qid,scl)
- | IDENT "Infix"; a = entry_prec; n = OPT natural; op = STRING;
+ | IDENT "Infix"; a = entry_prec; n = OPT natural;
+ op = STRING;
p = global;
modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] ->
- let (a,n,b) = Metasyntax.interp_infix_modifiers a n modl in
- VernacInfix (a,n,op,p,b,sc)
+ sc = OPT [ ":"; sc = IDENT -> sc];
+ v8 = OPT[IDENT "V8only";
+ op8=OPT STRING;
+ n8=OPT natural;
+ mv8=OPT["("; l = LIST1 syntax_modifier SEP ","; ")" -> l] ->
+ (op8,n8,mv8) ] ->
+ let (ai,ni,b) = Metasyntax.interp_infix_modifiers a n modl in
+ let v8 =
+ let (op8,nv8,mv8) =
+ match v8 with
+ Some (op8,nv8,mv8) ->
+ let op8 = match op8 with Some s -> s | _ -> op in
+ let nv8 = match nv8 with Some n -> Some n
+ | _ -> Util.option_app (( * ) 10) n in
+ let mv8 = match mv8 with Some m -> m | _ -> modl in
+ (op8,nv8,mv8)
+ | None -> (op,Util.option_app(( * ) 10) n, modl) in
+ let (a8,n8,_) =
+ Metasyntax.interp_infix_modifiers a nv8 mv8 in
+ Some(a8,n8,op8) in
+ VernacInfix (ai,ni,op,p,b,v8,sc)
| IDENT "Distfix"; a = entry_prec; n = natural; s = STRING; p = global;
sc = OPT [ ":"; sc = IDENT -> sc ] -> VernacDistfix (a,n,s,p,sc)
| IDENT "Notation"; s = IDENT; ":="; c = constr ->
- VernacNotation ("'"^s^"'",c,[],None)
+ VernacNotation ("'"^s^"'",c,[],None,None)
| IDENT "Notation"; s = STRING; ":="; c = constr;
modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] -> VernacNotation (s,c,modl,sc)
+ sc = OPT [ ":"; sc = IDENT -> sc ];
+ v8 = OPT[IDENT "V8only";
+ s8=OPT STRING;
+ mv8=["(";mv8=LIST1 syntax_modifier SEP ","; ")" -> mv8
+ | ->[] ] -> (s8,mv8) ] ->
+ let v8 = Util.option_app (fun (s8,mv8) ->
+ let s8 = match s8 with Some s -> s | _ -> s in
+ (s8,mv8)) v8 in
+ VernacNotation (s,c,modl,v8,sc)
(* "Print" "Grammar" should be here but is in "command" entry in order
to factorize with other "Print"-based vernac entries *)
@@ -269,9 +305,8 @@ GEXTEND Gram
;
syntax_extension_type:
[ [ IDENT "ident" -> ETIdent | IDENT "global" -> ETReference
- | IDENT "annot" ->
- if !Options.v7 <> true then Util.error "annot not allowed in new syntax";
- ETOther ("constr","annot")
+ | IDENT "bigint" -> ETBigint
+ | i=IDENT -> ETOther ("constr",i)
] ]
;
opt_scope:
diff --git a/parsing/g_cases.ml4 b/parsing/g_cases.ml4
index 62ee20cad..679d174c2 100644
--- a/parsing/g_cases.ml4
+++ b/parsing/g_cases.ml4
@@ -20,7 +20,7 @@ let pair loc =
Qualid (loc, Libnames.qualid_of_string "Coq.Init.Datatypes.pair")
GEXTEND Gram
- GLOBAL: constr pattern;
+ GLOBAL: operconstr pattern;
pattern:
[ [ r = Prim.reference -> CPatAtom (loc,Some r)
@@ -47,12 +47,12 @@ GEXTEND Gram
| p = pattern -> p ] ]
;
equation:
- [ [ lhs = LIST1 pattern; "=>"; rhs = constr9 -> (loc,lhs,rhs) ] ]
+ [ [ lhs = LIST1 pattern; "=>"; rhs = operconstr LEVEL "9" -> (loc,lhs,rhs) ] ]
;
ne_eqn_list:
[ [ leqn = LIST1 equation SEP "|" -> leqn ] ]
;
- constr: LEVEL "1"
+ operconstr: LEVEL "1"
[ [ "<"; p = annot; ">"; "Cases"; lc = LIST1 constr; "of";
OPT "|"; eqs = ne_eqn_list; "end" ->
CCases (loc, Some p, lc, eqs)
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index eac6ce12f..cea564953 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -17,6 +17,19 @@ open Libnames
open Prim
open Topconstr
+(* Initialize the lexer *)
+let constr_kw =
+ [ "Cases"; "of"; "with"; "end"; "as"; "in"; "Prop"; "Set"; "Type";
+ ":"; "("; ")"; "["; "]"; "{"; "}"; ","; ";"; "->"; "="; ":="; "!";
+ "::"; "<:"; ":<"; "=>"; "<"; ">"; "|"; "?"; "/";
+ "<->"; "\\/"; "/\\"; "`"; "``"; "&"; "*"; "+"; "@"; "^"; "#"; "-";
+ "~"; "'"; "<<"; ">>"; "<>";
+ ]
+let _ = List.iter (fun s -> Lexer.add_token ("",s)) constr_kw
+(* "let" is not a keyword because #Core#let.cci would not parse.
+ Is it still accurate ? *)
+
+
let coerce_to_var = function
| CRef (Ident (_,id)) -> id
| ast -> Util.user_err_loc
@@ -78,8 +91,9 @@ let test_ident_colon =
end
| _ -> raise Stream.Failure)
+
GEXTEND Gram
- GLOBAL: constr9 lconstr constr sort global constr_pattern Constr.ident annot
+ GLOBAL: operconstr lconstr constr sort global constr_pattern Constr.ident annot
(*ne_name_comma_list*);
Constr.ident:
[ [ id = Prim.ident -> id
@@ -105,8 +119,24 @@ GEXTEND Gram
| "Type" -> RType None ] ]
;
constr:
- [ "top" RIGHTA
- [ c1 = constr; "->"; c2 = constr -> CArrow (loc, c1, c2) ]
+ [ [ c = operconstr LEVEL "8" -> c ] ]
+ ;
+ lconstr:
+ [ [ c = operconstr LEVEL "10" -> c ] ]
+ ;
+ operconstr:
+ [ "10" RIGHTA
+ [ "!"; f = global; args = LIST0 (operconstr LEVEL "9") ->
+ CAppExpl (loc, f, args)
+(*
+ | "!"; f = global; "with"; b = binding_list ->
+ <:ast< (APPLISTWITH $f $b) >>
+*)
+ | f = operconstr; args = LIST1 constr91 -> CApp (loc, f, args) ]
+ | "9" RIGHTA
+ [ c1 = operconstr; "::"; c2 = operconstr -> CCast (loc, c1, c2) ]
+ | "8" RIGHTA
+ [ c1 = operconstr; "->"; c2 = operconstr -> CArrow (loc, c1, c2) ]
| "1" RIGHTA
[ "<"; p = annot; ">"; IDENT "Match"; c = constr; "with";
cl = LIST0 constr; "end" ->
@@ -119,32 +149,32 @@ GEXTEND Gram
| IDENT "Match"; c = constr; "with"; cl = LIST1 constr; "end" ->
COrderedCase (loc, MatchStyle, None, c, cl)
| IDENT "let"; "("; b = ne_name_comma_list; ")"; "=";
- c = constr; "in"; c1 = constr LEVEL "top"->
+ c = constr; "in"; c1 = constr ->
(* TODO: right loc *)
COrderedCase
(loc, LetStyle, None, c, [CLambdaN (loc, [b, CHole loc], c1)])
| IDENT "let"; na = name; "="; c = opt_casted_constr;
- "in"; c1 = constr LEVEL "top" ->
+ "in"; c1 = constr ->
CLetIn (loc, na, c, c1)
| IDENT "if"; c1 = constr;
IDENT "then"; c2 = constr;
- IDENT "else"; c3 = constr LEVEL "top" ->
+ IDENT "else"; c3 = constr ->
COrderedCase (loc, IfStyle, None, c1, [c2; c3])
| "<"; p = annot; ">";
IDENT "let"; "("; b = ne_name_comma_list; ")"; "="; c = constr;
- "in"; c1 = constr LEVEL "top" ->
+ "in"; c1 = constr ->
(* TODO: right loc *)
COrderedCase (loc, LetStyle, Some p, c,
[CLambdaN (loc, [b, CHole loc], c1)])
| "<"; p = annot; ">";
IDENT "if"; c1 = constr;
IDENT "then"; c2 = constr;
- IDENT "else"; c3 = constr LEVEL "top" ->
+ IDENT "else"; c3 = constr ->
COrderedCase (loc, IfStyle, Some p, c1, [c2; c3]) ]
| "0" RIGHTA
[ "?" -> CHole loc
| "?"; n = Prim.natural -> CMeta (loc, n)
- | bll = binders; c = constr LEVEL "top" -> abstract_constr loc c bll
+ | bll = binders; c = constr -> abstract_constr loc c bll
(* Hack to parse syntax "(n)" as a natural number *)
| "("; test_int_rparen; n = bigint; ")" ->
CDelimiters (loc,"N",CNumeral (loc,n))
@@ -182,24 +212,10 @@ GEXTEND Gram
| "'"; test_ident_colon; key = IDENT; ":"; c = constr; "'" ->
CDelimiters (loc,key,c) ] ]
;
- lconstr:
- [ "10" RIGHTA
- [ "!"; f = global; args = LIST0 constr9 -> CAppExpl (loc, f, args)
-(*
- | "!"; f = global; "with"; b = binding_list ->
- <:ast< (APPLISTWITH $f $b) >>
-*)
- | f = constr9; args = LIST1 constr91 -> CApp (loc, f, args)
- | f = constr9 -> f ] ]
- ;
constr91:
- [ [ test_int_bang; n = INT; "!"; c = constr9 ->
+ [ [ test_int_bang; n = INT; "!"; c = operconstr LEVEL "9" ->
(c, Some (int_of_string n))
- | c = constr9 -> (c, None) ] ]
- ;
- constr9:
- [ RIGHTA [ c1 = constr -> c1
- | c1 = constr; "::"; c2 = constr -> CCast (loc, c1, c2) ] ]
+ | c = operconstr LEVEL "9" -> (c, None) ] ]
;
(* annot and product_annot_tail are hacks to forbid concrete syntax *)
(* ">" (e.g. for gt, Zgt, ...) in annotations *)
@@ -232,7 +248,7 @@ GEXTEND Gram
[ c1 = SELF; "=="; c2 = NEXT -> CNotation (loc, "_ == _", [c1;c2]) ]
| RIGHTA
[ c1 = SELF; "="; c2 = NEXT -> CNotation (loc, "_ = _", [c1;c2]) ]
- | [ c = constr LEVEL "4L" -> c ] ]
+ | [ c = operconstr LEVEL "4L" -> c ] ]
;
product_annot_tail:
[ [ ";"; idl = ne_name_comma_list; ":"; c = constr;
diff --git a/parsing/g_constrnew.ml4 b/parsing/g_constrnew.ml4
new file mode 100644
index 000000000..ba8be907c
--- /dev/null
+++ b/parsing/g_constrnew.ml4
@@ -0,0 +1,256 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Pcoq
+open Constr
+open Prim
+open Rawterm
+open Term
+open Names
+open Libnames
+open Topconstr
+
+open Util
+
+let constr_kw =
+ [ "fun"; "match"; "fix"; "cofix"; "with"; "in"; "for"; "end"; "as";
+ "let"; "if"; "then"; "else"; "struct"; "Prop"; "Set"; "Type" ]
+let _ = List.iter (fun s -> Lexer.add_token("",s)) constr_kw
+let _ = Options.v7 := false
+
+let pair loc =
+ Qualid (loc, Libnames.qualid_of_string "Coq.Init.Datatypes.pair")
+
+let mk_cast = function
+ (c,(_,None)) -> c
+ | (c,(_,Some ty)) -> CCast(join_loc (constr_loc c) (constr_loc ty), c, ty)
+
+let mk_lam = function
+ ([],c) -> c
+ | (bl,c) -> CLambdaN(constr_loc c, bl,c)
+
+let coerce_to_id c =
+ match c with
+ CRef(Ident(loc,id)) -> (loc,Name id)
+ | CHole loc -> (loc,Anonymous)
+ | _ -> error "ill-formed match type annotation"
+
+let match_bind_of_pat loc (oid,ty) =
+ let l2 =
+ match oid with
+ None -> []
+ | Some x -> [([x],CHole loc)] in
+ let l1 =
+ match ty with
+ None -> [] (* No: should lookup inductive arity! *)
+ | Some (CApp(_,_,args)) -> (* parameters do not appear *)
+ List.map (fun (c,_) -> ([coerce_to_id c],CHole loc)) args
+ | _ -> error "ill-formed match type annotation" in
+ l1@l2
+
+let mk_match (loc,cil,rty,br) =
+ let (lc,pargs) = List.split cil in
+ let pr =
+ match rty with
+ None -> None
+ | Some ty ->
+ let idargs = (* TODO: not forget the list lengths for PP! *)
+ List.flatten (List.map (match_bind_of_pat loc) pargs) in
+ Some (CLambdaN(loc,idargs,ty)) in
+ CCases(loc,pr,lc,br)
+
+let mk_fixb (loc,id,bl,ann,body,(tloc,tyc)) =
+ let n =
+ match bl,ann with
+ [([_],_)], None -> 0
+ | _, Some x ->
+ let ids = List.map snd (List.flatten (List.map fst bl)) in
+ (try list_index (snd x) ids - 1
+ with Not_found -> error "no such fix variable")
+ | _ -> error "cannot find decreasing arg of fix" in
+ let ty = match tyc with
+ None -> CHole tloc
+ | Some t -> CProdN(loc,bl,t) in
+ (snd id,n,ty,CLambdaN(loc,bl,body))
+
+let mk_cofixb (loc,id,bl,ann,body,(tloc,tyc)) =
+ let _ = option_app (fun (aloc,_) ->
+ Util.user_err_loc
+ (aloc,"Constr:mk_cofixb",
+ Pp.str"Annotation forbidden in cofix expression")) ann in
+ let ty = match tyc with
+ None -> CHole tloc
+ | Some t -> CProdN(loc,bl,t) in
+ (snd id,ty,CLambdaN(loc,bl,body))
+
+let mk_fix(loc,kw,id,dcls) =
+ if kw then
+ let fb = List.map mk_fixb dcls in
+ CFix(loc,id,fb)
+ else
+ let fb = List.map mk_cofixb dcls in
+ CCoFix(loc,id,fb)
+
+let binder_constr =
+ create_constr_entry (get_univ "constr") "binder_constr"
+
+GEXTEND Gram
+ GLOBAL: binder_constr lconstr constr operconstr sort global
+ constr_pattern Constr.ident;
+ Constr.ident:
+ [ [ id = Prim.ident -> id
+
+ (* This is used in quotations and Syntax *)
+ | id = METAIDENT -> id_of_string id ] ]
+ ;
+ global:
+ [ [ r = Prim.reference -> r
+
+ (* This is used in quotations *)
+ | id = METAIDENT -> Ident (loc,id_of_string id) ] ]
+ ;
+ constr_pattern:
+ [ [ c = constr -> c ] ]
+ ;
+ sort:
+ [ [ "Set" -> RProp Pos
+ | "Prop" -> RProp Null
+ | "Type" -> RType None ] ]
+ ;
+ lconstr:
+ [ [ c = operconstr -> c ] ]
+ ;
+ constr:
+ [ [ c = operconstr LEVEL "9" -> c ] ]
+ ;
+ operconstr:
+ [ "200" RIGHTA
+ [ c = binder_constr -> c ]
+ | "100" RIGHTA
+ [ c1 = operconstr; ":"; c2 = binder_constr -> CCast(loc,c1,c2)
+ | c1 = operconstr; ":"; c2 = operconstr -> CCast(loc,c1,c2) ]
+ | "80" RIGHTA
+ [ c1 = operconstr; "->"; c2 = binder_constr -> CArrow(loc,c1,c2)
+ | c1 = operconstr; "->"; c2 = operconstr -> CArrow(loc,c1,c2) ]
+ | "40L" LEFTA
+ [ "-"; c = operconstr -> CNotation(loc,"- _",[c]) ]
+ | "10L" LEFTA
+ [ f=operconstr; args=LIST1 appl_arg -> CApp(loc,f,args)
+ | "@"; f=global; args=LIST0 NEXT -> CAppExpl(loc,f,args) ]
+ | "9" [ ]
+ | "1L" LEFTA
+ [ c=operconstr; "%"; key=IDENT -> CDelimiters (loc,key,c) ]
+ | "0"
+ [ c=atomic_constr -> c
+ | c=match_constr -> c
+ | "("; c=operconstr; ")" -> c ] ]
+ ;
+ binder_constr:
+ [ [ "!"; bl = LIST1 binder; "."; c = operconstr LEVEL "200" ->
+ CProdN(loc,bl,c)
+ | "fun"; bl = LIST1 binder; ty = type_cstr; "=>";
+ c = operconstr LEVEL "200" ->
+ CLambdaN(loc,bl,mk_cast(c,ty))
+ | "let"; id=name; bl = LIST0 binder; ty = type_cstr; ":=";
+ c1 = operconstr; "in"; c2 = operconstr LEVEL "200" ->
+ CLetIn(loc,id,mk_lam(bl,mk_cast(c1,ty)),c2)
+ | "let"; "("; lb = LIST1 name SEP ","; ")"; ":=";
+ c1 = operconstr; "in"; c2 = operconstr LEVEL "200" ->
+ COrderedCase (loc, LetStyle, None, c1,
+ [CLambdaN (loc, [lb, CHole loc], c2)])
+ | "if"; c1=operconstr; "then"; c2=operconstr LEVEL "200";
+ "else"; c3=operconstr LEVEL "200" ->
+ COrderedCase (loc, IfStyle, None, c1, [c2; c3])
+ | c=fix_constr -> c ] ]
+ ;
+ appl_arg:
+ [ [ "@"; n=INT; ":="; c=operconstr LEVEL "9" -> (c,Some(int_of_string n))
+ | c=operconstr LEVEL "9" -> (c,None) ] ]
+ ;
+ atomic_constr:
+ [ [ g=global -> CRef g
+ | s=sort -> CSort(loc,s)
+ | n=INT -> CNumeral (loc,Bignat.POS (Bignat.of_string n))
+ | IDENT "_" -> CHole loc
+ | "?"; n=Prim.natural -> CMeta(loc,n) ] ]
+ ;
+ fix_constr:
+ [ [ kw=fix_kw; dcl=fix_decl ->
+ let (_,n,_,_,_,_) = dcl in mk_fix(loc,kw,n,[dcl])
+ | kw=fix_kw; dcl1=fix_decl; "with"; dcls=LIST1 fix_decl SEP "with";
+ "for"; id=identref ->
+ mk_fix(loc,kw,id,dcl1::dcls)
+ ] ]
+ ;
+ fix_kw:
+ [ [ "fix" -> true
+ | "cofix" -> false ] ]
+ ;
+ fix_decl:
+ [ [ id=identref; bl=LIST0 binder; ann=fixannot; ty=type_cstr; ":=";
+ c=operconstr LEVEL "200" -> (loc,id,bl,ann,c,ty) ] ]
+ ;
+ fixannot:
+ [ [ "{"; "struct"; id=name; "}" -> Some id
+ | -> None ] ]
+ ;
+ match_constr:
+ [ [ "match"; ci=LIST1 case_item SEP ","; ty=case_type; "with";
+ br=branches; "end" -> mk_match (loc,ci,ty,br) ] ]
+ ;
+ case_item:
+ [ [ c=operconstr LEVEL "80"; p=pred_pattern -> (c,p) ] ]
+ ;
+ pred_pattern:
+ [ [ oid = OPT ["as"; id=name -> id];
+ (_,ty) = type_cstr -> (oid,ty) ] ]
+ ;
+ case_type:
+ [ [ ty = OPT [ "=>"; c = lconstr -> c ] -> ty ] ]
+ ;
+ branches:
+ [ [ OPT"|"; br=LIST0 eqn SEP "|" -> br ] ]
+ ;
+ eqn:
+ [ [ pl = LIST1 pattern SEP ","; "=>"; rhs = lconstr -> (loc,pl,rhs) ] ]
+ ;
+ simple_pattern:
+ [ [ r = Prim.reference -> CPatAtom (loc,Some r)
+ | IDENT "_" -> CPatAtom (loc,None)
+ | "("; p = lpattern; ")" -> p
+ | n = bigint -> CPatNumeral (loc,n)
+ ] ]
+ ;
+ pattern:
+ [ [ p = pattern ; lp = LIST1 simple_pattern ->
+ (match p with
+ | CPatAtom (_, Some r) -> CPatCstr (loc, r, lp)
+ | _ -> Util.user_err_loc
+ (loc, "compound_pattern", Pp.str "Constructor expected"))
+ | p = pattern; "as"; id = base_ident ->
+ CPatAlias (loc, p, id)
+ | c = pattern; "%"; key=IDENT ->
+ CPatDelimiters (loc,key,c)
+ | p = simple_pattern -> p ] ]
+ ;
+ lpattern:
+ [ [ c = pattern -> c
+ | p1=pattern; ","; p2=lpattern -> CPatCstr (loc, pair loc, [p1;p2]) ] ]
+ ;
+ binder:
+ [ [ id=name -> ([id],CHole loc)
+ | "("; id=name; ")" -> ([id],CHole loc)
+ | "("; id=name; ":"; c=lconstr; ")" -> ([id],c)
+ | id=name; ":"; c=constr -> ([id],c) ] ] (* tolerance *)
+ ;
+ type_cstr:
+ [ [ c=OPT [":"; c=lconstr -> c] -> (loc,c) ] ]
+ ;
+END;;
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 7d82fa715..1cc0c0297 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -60,6 +60,10 @@ end
open Prelude
+let arg_of_expr = function
+ TacArg a -> a
+ | e -> Tacexp e
+
(* Tactics grammar rules *)
GEXTEND Gram
@@ -220,8 +224,8 @@ GEXTEND Gram
| ta = tactic_arg0 -> ta ] ]
;
tactic_arg0:
- [ [ "("; a = tactic_expr; ")" -> Tacexp a
- | "()" -> TacVoid
+ [ [ "("; a = tactic_expr; ")" -> arg_of_expr a
+ | "()" -> Integer 0
| r = reference -> Reference r
| n = integer -> Integer n
| id = METAIDENT -> MetaIdArg (loc,id)
diff --git a/parsing/g_ltacnew.ml4 b/parsing/g_ltacnew.ml4
new file mode 100644
index 000000000..fe7c17ad1
--- /dev/null
+++ b/parsing/g_ltacnew.ml4
@@ -0,0 +1,209 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Pp
+open Util
+open Ast
+open Topconstr
+open Rawterm
+open Tacexpr
+open Vernacexpr
+open Ast
+
+ifdef Quotify then
+open Qast
+else
+open Pcoq
+
+open Prim
+open Tactic
+
+ifdef Quotify then
+open Q
+
+type let_clause_kind =
+ | LETTOPCLAUSE of Names.identifier * constr_expr
+ | LETCLAUSE of
+ (Names.identifier Util.located * constr_expr may_eval option * raw_tactic_arg)
+
+ifdef Quotify then
+module Prelude = struct
+let fail_default_value = Qast.Int "0"
+
+let out_letin_clause loc = function
+ | Qast.Node ("LETTOPCLAUSE", _) -> user_err_loc (loc, "", (str "Syntax Error"))
+ | Qast.Node ("LETCLAUSE", [id;c;d]) ->
+ Qast.Tuple [id;c;d]
+ | _ -> anomaly "out_letin_clause"
+
+let make_letin_clause _ = function
+ | Qast.List l -> Qast.List (List.map (out_letin_clause dummy_loc) l)
+ | _ -> anomaly "make_letin_clause"
+end
+else
+module Prelude = struct
+let fail_default_value = 0
+
+let out_letin_clause loc = function
+ | LETTOPCLAUSE _ -> user_err_loc (loc, "", (str "Syntax Error"))
+ | LETCLAUSE (id,c,d) -> (id,c,d)
+
+let make_letin_clause loc = List.map (out_letin_clause loc)
+end
+
+let arg_of_expr = function
+ TacArg a -> a
+ | e -> Tacexp e
+
+open Prelude
+
+(* Tactics grammar rules *)
+
+let tactic_expr = Gram.Entry.create "tactic:tactic_expr"
+
+GEXTEND Gram
+ GLOBAL: tactic Vernac_.command tactic_expr tactic_arg;
+
+ tactic_expr:
+ [ "5" LEFTA
+ [ ta0 = tactic_expr; "&"; ta1 = tactic_expr -> TacThen (ta0, ta1)
+ | ta = tactic_expr; "&"; "["; lta = LIST0 tactic_expr SEP "|"; "]" ->
+ TacThens (ta, lta) ]
+ | "4"
+ [ ]
+ | "3" RIGHTA
+ [ IDENT "try"; ta = tactic_expr -> TacTry ta
+ | IDENT "do"; n = natural; ta = tactic_expr -> TacDo (n,ta)
+ | IDENT "repeat"; ta = tactic_expr -> TacRepeat ta
+ | IDENT "progress"; ta = tactic_expr -> TacProgress ta
+ | IDENT "info"; tc = tactic_expr -> TacInfo tc ]
+ | "2" RIGHTA
+ [ ta0 = tactic_expr; "||"; ta1 = tactic_expr -> TacOrelse (ta0,ta1) ]
+ | "1" RIGHTA
+ [ "fun"; it = LIST1 input_fun ; "=>"; body = tactic_expr ->
+ TacFun (it,body)
+ | IDENT "rec"; rcl = LIST1 rec_clause SEP "with"; "in";
+ body = tactic_expr -> TacLetRecIn (rcl,body)
+ | "let"; llc = LIST1 let_clause SEP "with"; "in";
+ u = tactic_expr -> TacLetIn (make_letin_clause loc llc,u)
+ | "match"; IDENT "context"; "with"; mrl = match_context_list; "end" ->
+ TacMatchContext (false,mrl)
+ | "match"; IDENT "reverse"; IDENT "context"; "with";
+ mrl = match_context_list; "end" ->
+ TacMatchContext (true,mrl)
+ | "match"; c = constrarg; "with"; mrl = match_list; "end" ->
+ TacMatch (c,mrl)
+(*To do: put Abstract in Refiner*)
+ | IDENT "abstract"; tc = tactic_expr -> TacAbstract (tc,None)
+ | IDENT "abstract"; tc = tactic_expr; "using"; s = base_ident ->
+ TacAbstract (tc,Some s)
+(*End of To do*)
+ | IDENT "first" ; "["; l = LIST0 tactic_expr SEP "|"; "]" ->
+ TacFirst l
+ | IDENT "solve" ; "["; l = LIST0 tactic_expr SEP "|"; "]" ->
+ TacSolve l
+ | IDENT "idtac" -> TacId
+ | IDENT "fail" -> TacFail fail_default_value
+ | IDENT "fail"; n = natural -> TacFail n
+ | st = simple_tactic -> TacAtom (loc,st)
+ | IDENT "eval"; rtc = red_expr; "in"; c = Constr.lconstr ->
+ TacArg(ConstrMayEval (ConstrEval (rtc,c)))
+ | IDENT "inst"; id = identref; "["; c = Constr.lconstr; "]" ->
+ TacArg(ConstrMayEval (ConstrContext (id,c)))
+ | IDENT "check"; c = Constr.lconstr ->
+ TacArg(ConstrMayEval (ConstrTypeOf c))
+ | "'"; c = Constr.constr -> TacArg(ConstrMayEval(ConstrTerm c))
+ | r = reference; la = LIST1 tactic_arg ->
+ TacArg(TacCall (loc,r,la))
+ | r = reference -> TacArg (Reference r) ]
+ | "0"
+ [ "("; a = tactic_expr; ")" -> a
+ | a = tactic_atom -> TacArg a ] ]
+ ;
+ (* Tactic arguments *)
+ tactic_arg:
+ [ [ "'"; a = tactic_expr LEVEL "0" -> arg_of_expr a
+ | a = tactic_atom -> a
+ | c = Constr.constr -> ConstrMayEval (ConstrTerm c) ] ]
+ ;
+ tactic_atom:
+ [ [ id = METAIDENT -> MetaIdArg (loc,id)
+ | r = reference -> Reference r
+ | "?"; n = natural -> MetaNumArg (loc,n)
+ | "()" -> TacVoid ] ]
+ ;
+ input_fun:
+ [ [ IDENT "_" -> None
+ | l = base_ident -> Some l ] ]
+ ;
+ let_clause:
+ [ [ id = identref; ":="; te = tactic_expr ->
+ LETCLAUSE (id, None, arg_of_expr te)
+ | (_,id) = identref; ":"; c = Constr.constr; ":="; IDENT "proof" ->
+ LETTOPCLAUSE (id, c)
+ | id = identref; ":"; c = constrarg; ":="; te = tactic_expr ->
+ LETCLAUSE (id, Some c, arg_of_expr te)
+ | (_,id) = identref; ":"; c = Constr.lconstr ->
+ LETTOPCLAUSE (id, c) ] ]
+ ;
+ rec_clause:
+ [ [ name = identref; it = LIST1 input_fun; "=>"; body = tactic_expr ->
+ (name,(it,body)) ] ]
+ ;
+ match_pattern:
+ [ [ id = Constr.constr_pattern; "["; pc = Constr.constr_pattern; "]" ->
+ let s = coerce_to_id id in Subterm (Some s, pc)
+ | "["; pc = Constr.constr_pattern; "]" -> Subterm (None,pc)
+ | pc = Constr.constr_pattern -> Term pc ] ]
+ ;
+ match_hyps:
+ [ [ id = identref; ":"; mp = match_pattern -> Hyp (id, mp)
+ | IDENT "_"; ":"; mp = match_pattern -> NoHypId mp ] ]
+ ;
+ match_context_rule:
+ [ [ "["; largs = LIST0 match_hyps SEP ","; "|-"; mp = match_pattern; "]";
+ "=>"; te = tactic_expr -> Pat (largs, mp, te)
+ | IDENT "_"; "=>"; te = tactic_expr -> All te ] ]
+ ;
+ match_context_list:
+ [ [ mrl = LIST1 match_context_rule SEP "|" -> mrl
+ | "|"; mrl = LIST1 match_context_rule SEP "|" -> mrl ] ]
+ ;
+ match_rule:
+ [ [ "["; mp = match_pattern; "]"; "=>"; te = tactic_expr -> Pat ([],mp,te)
+ | IDENT "_"; "=>"; te = tactic_expr -> All te ] ]
+ ;
+ match_list:
+ [ [ mrl = LIST1 match_rule SEP "|" -> mrl
+ | "|"; mrl = LIST1 match_rule SEP "|" -> mrl ] ]
+ ;
+
+ (* Definitions for tactics *)
+ deftok:
+ [ [ IDENT "Meta"
+ | IDENT "Tactic" ] ]
+ ;
+ tacdef_body:
+ [ [ name = identref; it=LIST1 input_fun; ":="; body = tactic_expr ->
+ (name, TacFun (it, body))
+ | name = identref; ":="; body = tactic_expr ->
+ (name, body) ] ]
+ ;
+ tactic:
+ [ [ tac = tactic_expr -> tac ] ]
+ ;
+ Vernac_.command:
+ [ [ deftok; IDENT "Definition"; b = tacdef_body ->
+ VernacDeclareTacticDefinition (false, [b])
+ | IDENT "Recursive"; deftok; IDENT "Definition";
+ l = LIST1 tacdef_body SEP "with" ->
+ VernacDeclareTacticDefinition (true, l) ] ]
+ ;
+ END
diff --git a/parsing/g_natsyntaxnew.ml b/parsing/g_natsyntaxnew.ml
new file mode 100644
index 000000000..b124c4ec0
--- /dev/null
+++ b/parsing/g_natsyntaxnew.ml
@@ -0,0 +1,195 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* This file to allow writing (3) for (S (S (S O)))
+ and still write (S y) for (S y) *)
+
+open Pcoq
+open Pp
+open Util
+open Names
+open Coqast
+open Ast
+open Coqlib
+open Termast
+open Extend
+(*
+let ast_O = ast_of_ref glob_O
+let ast_S = ast_of_ref glob_S
+
+(* For example, (nat_of_string "3") is <<(S (S (S O)))>> *)
+let nat_of_int n dloc =
+ let ast_O = set_loc dloc ast_O in
+ let ast_S = set_loc dloc ast_S in
+ let rec mk_nat n =
+ if n <= 0 then
+ ast_O
+ else
+ Node(dloc,"APPLIST", [ast_S; mk_nat (n-1)])
+ in
+ mk_nat n
+
+let pat_nat_of_int n dloc =
+ let ast_O = set_loc dloc ast_O in
+ let ast_S = set_loc dloc ast_S in
+ let rec mk_nat n =
+ if n <= 0 then
+ ast_O
+ else
+ Node(dloc,"PATTCONSTRUCT", [ast_S; mk_nat (n-1)])
+ in
+ mk_nat n
+
+let nat_of_string s dloc =
+ nat_of_int (int_of_string s) dloc
+
+let pat_nat_of_string s dloc =
+ pat_nat_of_int (int_of_string s) dloc
+
+exception Non_closed_number
+
+let rec int_of_nat_rec astS astO p =
+ match p with
+ | Node (_,"APPLIST", [b; a]) when alpha_eq(b,astS) ->
+ (int_of_nat_rec astS astO a)+1
+ | a when alpha_eq(a,astO) -> 1
+ (***** YES, 1, non 0 ... to print the successor of p *)
+ | _ -> raise Non_closed_number
+
+let int_of_nat p =
+ try
+ Some (int_of_nat_rec ast_S ast_O p)
+ with
+ Non_closed_number -> None
+
+let pr_S a = hov 0 (str "S" ++ brk (1,1) ++ a)
+
+let rec pr_external_S std_pr = function
+ | Node (l,"APPLIST", [b; a]) when alpha_eq (b,ast_S) ->
+ str"(" ++ pr_S (pr_external_S std_pr a) ++ str")"
+ | p -> std_pr p
+
+(* Declare the primitive printer *)
+
+(* Prints not p, but the SUCCESSOR of p !!!!! *)
+let nat_printer std_pr p =
+ match (int_of_nat p) with
+ | Some i -> str "(" ++ str (string_of_int i) ++ str ")"
+ | None -> str "(" ++ pr_S (pr_external_S std_pr p) ++ str ")"
+
+let _ = Esyntax.Ppprim.add ("nat_printer", nat_printer)
+*)
+(*
+(* Declare the primitive parser *)
+
+let unat = create_univ_if_new "nat"
+
+let number = create_constr_entry unat "number"
+let pat_number = create_constr_entry unat "pat_number"
+
+let _ =
+ Gram.extend number None
+ [None, None,
+ [[Gramext.Stoken ("INT", "")],
+ Gramext.action nat_of_string]]
+
+let _ =
+ Gram.extend pat_number None
+ [None, None,
+ [[Gramext.Stoken ("INT", "")],
+ Gramext.action pat_nat_of_string]]
+*)
+
+(*i*)
+open Rawterm
+open Libnames
+open Bignat
+open Coqlib
+open Symbols
+open Pp
+open Util
+open Names
+(*i*)
+
+(**********************************************************************)
+(* Parsing via scopes *)
+(* For example, (nat_of_string "3") is <<(S (S (S O)))>> *)
+
+let nat_of_int dloc n =
+ match n with
+ | POS n ->
+ if less_than (of_string "5000") n & Options.is_verbose () then begin
+ warning ("You may experiment stack overflow and segmentation fault\
+ \nwhile parsing numbers in nat greater than 5000");
+ flush_all ()
+ end;
+ let ref_O = RRef (dloc, glob_O) in
+ let ref_S = RRef (dloc, glob_S) in
+ let rec mk_nat acc n =
+ if is_nonzero n then
+ mk_nat (RApp (dloc,ref_S, [acc])) (sub_1 n)
+ else
+ acc
+ in
+ mk_nat ref_O n
+ | NEG n ->
+ user_err_loc (dloc, "nat_of_int",
+ str "Cannot interpret a negative number as a natural number")
+
+let pat_nat_of_int dloc n name =
+ match n with
+ | POS n ->
+ let rec mk_nat n name =
+ if is_nonzero n then
+ PatCstr (dloc,path_of_S,[mk_nat (sub_1 n) Anonymous],name)
+ else
+ PatCstr (dloc,path_of_O,[],name)
+ in
+ mk_nat n name
+ | NEG n ->
+ user_err_loc (dloc, "pat_nat_of_int",
+ str "Cannot interpret a negative number as a natural number")
+
+(***********************************************************************)
+(* Printing via scopes *)
+
+exception Non_closed_number
+
+let rec int_of_nat = function
+ | RApp (_,RRef (_,s),[a]) when s = glob_S -> add_1 (int_of_nat a)
+ | RRef (_,z) when z = glob_O -> zero
+ | _ -> raise Non_closed_number
+
+let uninterp_nat p =
+ try
+ Some (POS (int_of_nat p))
+ with
+ Non_closed_number -> None
+
+let rec int_of_nat_pattern = function
+ | PatCstr (_,s,[a],_) when ConstructRef s = glob_S ->
+ add_1 (int_of_nat_pattern a)
+ | PatCstr (_,z,[],_) when ConstructRef z = glob_O -> zero
+ | _ -> raise Non_closed_number
+
+let uninterp_nat_pattern p =
+ try
+ Some (POS (int_of_nat_pattern p))
+ with
+ Non_closed_number -> None
+
+(***********************************************************************)
+(* Declare the primitive parsers and printers *)
+
+let _ =
+ Symbols.declare_numeral_interpreter "nat_scope"
+ ["Coq";"Init";"Peano"]
+ (nat_of_int,Some pat_nat_of_int)
+ ([RRef (dummy_loc,glob_S); RRef (dummy_loc,glob_O)], uninterp_nat, None)
diff --git a/parsing/g_natsyntaxnew.mli b/parsing/g_natsyntaxnew.mli
new file mode 100644
index 000000000..91596ef5c
--- /dev/null
+++ b/parsing/g_natsyntaxnew.mli
@@ -0,0 +1,11 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+(* Nice syntax for naturals. *)
diff --git a/parsing/g_prim.ml4 b/parsing/g_prim.ml4
index 9dd073cfd..39a7687f1 100644
--- a/parsing/g_prim.ml4
+++ b/parsing/g_prim.ml4
@@ -19,6 +19,8 @@ open Qast
open Prim
+let _ = reset_all_grammars()
+
(* camlp4o pa_extend.cmo pa_extend_m.cmo pr_o.cmo q_prim.ml *)
ifdef Quotify then
diff --git a/parsing/g_primnew.ml4 b/parsing/g_primnew.ml4
new file mode 100644
index 000000000..de18ab764
--- /dev/null
+++ b/parsing/g_primnew.ml4
@@ -0,0 +1,143 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open Coqast
+open Pcoq
+open Names
+open Libnames
+open Topconstr
+
+let _ = Pcoq.reset_all_grammars()
+let _ =
+ let f = Gram.Unsafe.clear_entry in
+ f Prim.bigint;
+ f Prim.qualid;
+ f Prim.ast;
+ f Prim.reference
+
+let prim_kw = ["{"; "}"; "["; "]"; "("; ")"; "<>"; "<<"; ">>"; "'";"."]
+let _ = List.iter (fun s -> Lexer.add_token("",s)) prim_kw
+
+ifdef Quotify then
+open Qast
+
+open Prim
+
+ifdef Quotify then
+module Prelude = struct
+let local_id_of_string s = Apply ("Names","id_of_string", [s])
+let local_make_dirpath l = Qast.Apply ("Names","make_dirpath",[l])
+let local_make_posint s = s
+let local_make_negint s = Apply ("Pervasives","~-", [s])
+let local_make_qualid l id' =
+ Qast.Apply ("Nametab","make_qualid", [local_make_dirpath l;id'])
+let local_make_short_qualid id =
+ Qast.Apply ("Nametab","make_short_qualid",[id])
+let local_make_path l id' =
+ Qast.Apply ("Libnames","encode_kn", [local_make_dirpath l;id'])
+let local_make_binding loc a b =
+ match a with
+ | Qast.Node ("Nvar", [_;id]) ->
+ Qast.Node ("Slam", [Qast.Loc; Qast.Option (Some id); b])
+ | Qast.Node ("Nmeta", [_;s]) ->
+ Qast.Node ("Smetalam", [Qast.Loc;s;b])
+ | _ ->
+ Qast.Apply ("Pervasives", "failwith", [Qast.Str "Slam expects a var or a metavar"])
+let local_append l id = Qast.Apply ("List","append", [l; Qast.List [id]])
+end
+
+else
+
+module Prelude = struct
+open Nametab
+let local_id_of_string = id_of_string
+let local_make_dirpath = make_dirpath
+let local_make_qualid l id' = make_qualid (local_make_dirpath l) id'
+let local_make_short_qualid id = make_short_qualid id
+let local_make_posint = int_of_string
+let local_make_negint n = - int_of_string n
+let local_make_path l a = encode_kn (local_make_dirpath l) a
+let local_make_binding loc a b =
+ match a with
+ | Nvar (_,id) -> Slam(loc,Some id,b)
+ | Nmeta (_,s) -> Smetalam(loc,s,b)
+ | _ -> failwith "Slam expects a var or a metavar"
+let local_append l id = l@[id]
+end
+
+open Prelude
+
+ifdef Quotify then
+open Q
+
+GEXTEND Gram
+ GLOBAL: ast bigint qualid reference;
+ metaident:
+ [ [ s = METAIDENT -> Nmeta (loc,s) ] ]
+ ;
+ field:
+ [ [ "."; s = IDENT -> local_id_of_string s ] ]
+ ;
+ fields:
+ [ [ id = field; (l,id') = fields -> (local_append l id,id')
+ | id = field -> ([],id)
+ ] ]
+ ;
+ astpath:
+ [ [ id = base_ident; (l,a) = fields ->
+ Path(loc, local_make_path (local_append l id) a)
+ | id = base_ident -> Nvar(loc, id)
+ ] ]
+ ;
+ basequalid:
+ [ [ id = base_ident; (l,id')=fields ->
+ local_make_qualid (local_append l id) id'
+ | id = base_ident -> local_make_short_qualid id
+ ] ]
+ ;
+ reference:
+ [ [ id = base_ident; (l,id') = fields ->
+ Qualid (loc, local_make_qualid (local_append l id) id')
+ | id = base_ident -> Ident (loc,id)
+ ] ]
+ ;
+ qualid:
+ [ [ qid = basequalid -> loc, qid ] ]
+ ;
+ ast:
+ [ [ id = metaident -> id
+ | p = astpath -> p
+ | s = INT -> Num(loc, local_make_posint s)
+ | s = STRING -> Str(loc, s)
+ | "{"; s = METAIDENT; "}" -> Id(loc,s)
+ | "("; nname = IDENT; l = LIST0 ast; ")" -> Node(loc,nname,l)
+ | "("; METAIDENT "$LIST"; id = metaident; ")" -> Node(loc,"$LIST",[id])
+ | "("; METAIDENT "$STR"; id = metaident; ")" -> Node(loc,"$STR",[id])
+ | "("; METAIDENT "$VAR"; id = metaident; ")" -> Node(loc,"$VAR",[id])
+ | "("; METAIDENT "$ID"; id = metaident; ")" -> Node(loc,"$ID",[id])
+ | "("; METAIDENT "$ABSTRACT"; l = LIST0 ast;")"->Node(loc,"$ABSTRACT",l)
+ | "("; METAIDENT "$PATH"; id = metaident; ")" -> Node(loc,"$PATH",[id])
+ | "("; METAIDENT "$NUM"; id = metaident; ")" -> Node(loc,"$NUM",[id])
+ | "["; "<>"; "]"; b = ast -> Slam(loc,None,b)
+ | "["; a = ast; "]"; b = ast -> local_make_binding loc a b
+ | "'"; a = ast -> Node(loc,"$QUOTE",[a]) ] ]
+ ;
+ bigint: (* Negative numbers are dealt with specially *)
+ [ [ i = INT -> Bignat.POS (Bignat.of_string i) ] ]
+ ;
+END
+
+let constr_to_ast a =
+ Termast.ast_of_rawconstr
+ (Constrintern.interp_rawconstr Evd.empty (Global.env()) a)
+
+let constr_parser_with_glob = Pcoq.map_entry constr_to_ast Constr.constr
+
+let _ = define_ast_quotation true "constr" constr_parser_with_glob
diff --git a/parsing/g_proofs.ml4 b/parsing/g_proofs.ml4
index 879ce98ae..f6801bf31 100644
--- a/parsing/g_proofs.ml4
+++ b/parsing/g_proofs.ml4
@@ -18,6 +18,8 @@ open Vernacexpr
open Prim
open Constr
+let thm_token = Gram.Entry.create "vernac:thm_token"
+
(* Proof commands *)
GEXTEND Gram
GLOBAL: command;
diff --git a/parsing/g_proofsnew.ml4 b/parsing/g_proofsnew.ml4
new file mode 100644
index 000000000..db8da7101
--- /dev/null
+++ b/parsing/g_proofsnew.ml4
@@ -0,0 +1,126 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Pcoq
+open Pp
+open Tactic
+open Util
+open Vernac_
+open Topconstr
+open Vernacexpr
+open Prim
+open Constr
+
+let thm_token = G_vernacnew.thm_token
+
+(* Proof commands *)
+GEXTEND Gram
+ GLOBAL: command;
+
+ destruct_location :
+ [ [ IDENT "Conclusion" -> Tacexpr.ConclLocation ()
+ | discard = [ IDENT "Discardable" -> true | -> false ]; IDENT "Hypothesis"
+ -> Tacexpr.HypLocation discard ] ]
+ ;
+ opt_hintbases:
+ [ [ -> []
+ | ":"; l = LIST1 IDENT -> l ] ]
+ ;
+ command:
+ [ [ IDENT "Goal"; c = Constr.lconstr -> VernacGoal c
+ | IDENT "Proof" -> VernacNop
+ | IDENT "Proof"; "with"; ta = tactic -> VernacProof ta
+ | IDENT "Abort" -> VernacAbort None
+ | IDENT "Abort"; IDENT "All" -> VernacAbortAll
+ | IDENT "Abort"; id = identref -> VernacAbort (Some id)
+ | IDENT "Existential"; n = natural; c = constr_body ->
+ VernacSolveExistential (n,c)
+ | IDENT "Qed" -> VernacEndProof (true,None)
+ | IDENT "Save" -> VernacEndProof (true,None)
+ | IDENT "Save"; tok = thm_token; id = base_ident ->
+ VernacEndProof (true,Some (id,Some tok))
+ | IDENT "Save"; id = base_ident -> VernacEndProof (true,Some (id,None))
+ | IDENT "Defined" -> VernacEndProof (false,None)
+ | IDENT "Defined"; id=base_ident -> VernacEndProof (false,Some (id,None))
+ | IDENT "Suspend" -> VernacSuspend
+ | IDENT "Resume" -> VernacResume None
+ | IDENT "Resume"; id = identref -> VernacResume (Some id)
+ | IDENT "Restart" -> VernacRestart
+ | IDENT "Proof"; c = Constr.lconstr -> VernacExactProof c
+ | IDENT "Undo" -> VernacUndo 1
+ | IDENT "Undo"; n = natural -> VernacUndo n
+ | IDENT "Focus" -> VernacFocus None
+ | IDENT "Focus"; n = natural -> VernacFocus (Some n)
+ | IDENT "Unfocus" -> VernacUnfocus
+ | IDENT "Show" -> VernacShow (ShowGoal None)
+ | IDENT "Show"; n = natural -> VernacShow (ShowGoal (Some n))
+ | IDENT "Show"; IDENT "Implicits"; n = natural ->
+ VernacShow (ShowGoalImplicitly (Some n))
+ | IDENT "Show"; IDENT "Implicits" -> VernacShow (ShowGoalImplicitly None)
+ | IDENT "Show"; IDENT "Node" -> VernacShow ShowNode
+ | IDENT "Show"; IDENT "Script" -> VernacShow ShowScript
+ | IDENT "Show"; IDENT "Existentials" -> VernacShow ShowExistentials
+ | IDENT "Show"; IDENT "Tree" -> VernacShow ShowTree
+ | IDENT "Show"; IDENT "Conjectures" -> VernacShow ShowProofNames
+ | IDENT "Show"; IDENT "Proof" -> VernacShow ShowProof
+ | IDENT "Show"; IDENT "Intro" -> VernacShow (ShowIntros false)
+ | IDENT "Show"; IDENT "Intros" -> VernacShow (ShowIntros true)
+ | IDENT "Explain"; IDENT "Proof"; l = LIST0 integer ->
+ VernacShow (ExplainProof l)
+ | IDENT "Explain"; IDENT "Proof"; IDENT "Tree"; l = LIST0 integer ->
+ VernacShow (ExplainTree l)
+ | IDENT "Go"; n = natural -> VernacGo (GoTo n)
+ | IDENT "Go"; IDENT "top" -> VernacGo GoTop
+ | IDENT "Go"; IDENT "prev" -> VernacGo GoPrev
+ | IDENT "Go"; IDENT "next" -> VernacGo GoNext
+ | IDENT "Guarded" -> VernacCheckGuard
+(* Hints for Auto and EAuto *)
+
+ | IDENT "HintDestruct";
+ dloc = destruct_location;
+ id = base_ident;
+ hyptyp = Constr.constr_pattern;
+ pri = natural;
+ "["; tac = tactic; "]" ->
+ VernacHintDestruct (id,dloc,hyptyp,pri,tac)
+
+ | IDENT "Hint"; hintname = base_ident; dbnames = opt_hintbases; ":="; h = hint
+ -> VernacHints (dbnames, h hintname)
+
+ | IDENT "Hints"; (dbnames,h) = hints -> VernacHints (dbnames, h)
+
+
+(*This entry is not commented, only for debug*)
+ | IDENT "PrintConstr"; c = Constr.constr ->
+ VernacExtend ("PrintConstr",
+ [Genarg.in_gen Genarg.rawwit_constr c])
+ ] ];
+
+ hint:
+ [ [ IDENT "Resolve"; c = Constr.constr -> fun name -> HintsResolve [Some name, c]
+ | IDENT "Immediate"; c = Constr.constr -> fun name -> HintsImmediate [Some name, c]
+ | IDENT "Unfold"; qid = global -> fun name -> HintsUnfold [Some name,qid]
+ | IDENT "Constructors"; c = global -> fun n -> HintsConstructors (n,c)
+ | IDENT "Extern"; n = natural; c = Constr.constr ; tac = tactic ->
+ fun name -> HintsExtern (name,n,c,tac) ] ]
+ ;
+ hints:
+ [ [ IDENT "Resolve"; l = LIST1 global; dbnames = opt_hintbases ->
+ (dbnames, HintsResolve (List.map (fun qid -> (None, CRef qid)) l))
+ | IDENT "Immediate"; l = LIST1 global; dbnames = opt_hintbases ->
+ (dbnames, HintsImmediate (List.map (fun qid -> (None, CRef qid)) l))
+ | IDENT "Unfold"; l = LIST1 global; dbnames = opt_hintbases ->
+ (dbnames, HintsUnfold (List.map (fun qid -> (None,qid)) l)) ] ]
+ ;
+ constr_body:
+ [ [ ":="; c = lconstr -> c
+ | ":"; t = lconstr; ":="; c = lconstr -> CCast(loc,c,t) ] ]
+ ;
+END
diff --git a/parsing/g_rsyntax.ml b/parsing/g_rsyntax.ml
index 6edbf7c55..13eb76334 100644
--- a/parsing/g_rsyntax.ml
+++ b/parsing/g_rsyntax.ml
@@ -66,7 +66,13 @@ let r_of_int n dloc =
let r_of_string s dloc =
r_of_int (int_of_string s) dloc
-let rnumber = create_constr_entry (get_univ "rnatural") "rnumber"
+let rsyntax_create name =
+ let e =
+ Pcoq.create_constr_entry (Pcoq.get_univ "rnatural") name in
+ Pcoq.Gram.Unsafe.clear_entry e;
+ e
+
+let rnumber = rsyntax_create "rnumber"
let _ =
Gram.extend rnumber None
diff --git a/parsing/g_rsyntaxnew.ml b/parsing/g_rsyntaxnew.ml
new file mode 100644
index 000000000..081762ae3
--- /dev/null
+++ b/parsing/g_rsyntaxnew.ml
@@ -0,0 +1,113 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+open Coqast
+open Ast
+open Pp
+open Util
+open Names
+open Pcoq
+open Extend
+open Topconstr
+open Libnames
+
+(**********************************************************************)
+(* Parsing R via scopes *)
+(**********************************************************************)
+
+open Libnames
+open Rawterm
+open Bignat
+
+let make_dir l = make_dirpath (List.map id_of_string (List.rev l))
+let rdefinitions = make_dir ["Coq";"Reals";"Rdefinitions"]
+
+(* TODO: temporary hack *)
+let make_path dir id = Libnames.encode_kn dir (id_of_string id)
+
+let glob_R1 = ConstRef (make_path rdefinitions "R1")
+let glob_R0 = ConstRef (make_path rdefinitions "R0")
+let glob_Ropp = ConstRef (make_path rdefinitions "Ropp")
+let glob_Rplus = ConstRef (make_path rdefinitions "Rplus")
+let glob_Rmult = ConstRef (make_path rdefinitions "Rmult")
+
+let two = mult_2 one
+let three = add_1 two
+let four = mult_2 two
+
+(* Unary representation of strictly positive numbers *)
+let rec small_r dloc n =
+ if is_one n then RRef (dloc, glob_R1)
+ else RApp(dloc,RRef (dloc,glob_Rplus),
+ [RRef (dloc, glob_R1);small_r dloc (sub_1 n)])
+
+let r_of_posint dloc n =
+ let r1 = RRef (dloc, glob_R1) in
+ let r2 = small_r dloc two in
+ let rec r_of_pos n =
+ if less_than n four then small_r dloc n
+ else
+ let (q,r) = div2_with_rest n in
+ let b = RApp(dloc,RRef(dloc,glob_Rmult),[r2;r_of_pos q]) in
+ if r then RApp(dloc,RRef(dloc,glob_Rplus),[r1;b]) else b in
+ if is_nonzero n then r_of_pos n else RRef(dloc,glob_R0)
+
+let r_of_int dloc z =
+ match z with
+ | NEG n -> RApp (dloc, RRef(dloc,glob_Ropp), [r_of_posint dloc n])
+ | POS n -> r_of_posint dloc n
+
+(**********************************************************************)
+(* Printing R via scopes *)
+(**********************************************************************)
+
+exception Non_closed_number
+
+(* for numbers > 1 *)
+let rec bignat_of_pos = function
+ (* 1+1 *)
+ | RApp (_,RRef (_,p), [RRef (_,o1); RRef (_,o2)])
+ when p = glob_Rplus & o1 = glob_R1 & o2 = glob_R1 -> two
+ (* 1+1+1 *)
+ | RApp (_,RRef (_,p1), [RRef (_,o1);
+ RApp(_,RRef (_,p2),[RRef(_,o2);RRef(_,o3)])])
+ when p1 = glob_Rplus & p2 = glob_Rplus &
+ o1 = glob_R1 & o2 = glob_R1 & o3 = glob_R1 -> three
+ (* (1+1)*b *)
+ | RApp (_,RRef (_,p), [a; b]) when p = glob_Rmult ->
+ if bignat_of_pos a <> two then raise Non_closed_number;
+ mult_2 (bignat_of_pos b)
+ (* 1+(1+1)*b *)
+ | RApp (_,RRef (_,p1), [RRef (_,o); RApp (_,RRef (_,p2),[a;b])])
+ when p1 = glob_Rplus & p2 = glob_Rmult & o = glob_R1 ->
+ if bignat_of_pos a <> two then raise Non_closed_number;
+ add_1 (mult_2 (bignat_of_pos b))
+ | _ -> raise Non_closed_number
+
+let bignat_of_r = function
+ | RRef (_,a) when a = glob_R0 -> zero
+ | RRef (_,a) when a = glob_R1 -> one
+ | r -> bignat_of_pos r
+
+let bigint_of_r = function
+ | RApp (_,RRef (_,o), [a]) when o = glob_Ropp -> NEG (bignat_of_r a)
+ | a -> POS (bignat_of_r a)
+
+let uninterp_r p =
+ try
+ Some (bigint_of_r p)
+ with Non_closed_number ->
+ None
+
+let _ = Symbols.declare_numeral_interpreter "R_scope"
+ ["Coq";"Reals";"Rsyntax"]
+ (r_of_int,None)
+ ([RRef(dummy_loc,glob_Ropp);RRef(dummy_loc,glob_R0);
+ RRef(dummy_loc,glob_Rplus);RRef(dummy_loc,glob_Rmult);RRef(dummy_loc,glob_R1)],
+ uninterp_r,
+ None)
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index c7f8217d1..fe77a3095 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -22,6 +22,10 @@ open Constr
open Prim
open Tactic
+let tactic_kw =
+ [ "using"; "Orelse"; "Proof"; "Qed"; "And"; "()"; "|-" ]
+let _ = List.iter (fun s -> Lexer.add_token ("",s)) tactic_kw
+
(* Functions overloaded by quotifier *)
let induction_arg_of_constr c =
@@ -319,9 +323,9 @@ GEXTEND Gram
(* Constructors *)
| IDENT "Left"; bl = with_binding_list -> TacLeft bl
| IDENT "Right"; bl = with_binding_list -> TacRight bl
- | IDENT "Split"; bl = with_binding_list -> TacSplit bl
- | IDENT "Exists"; bl = binding_list -> TacSplit bl
- | IDENT "Exists" -> TacSplit NoBindings
+ | IDENT "Split"; bl = with_binding_list -> TacSplit (false,bl)
+ | IDENT "Exists"; bl = binding_list -> TacSplit (true,bl)
+ | IDENT "Exists" -> TacSplit (true,NoBindings)
| IDENT "Constructor"; n = num_or_meta; l = with_binding_list ->
TacConstructor (n,l)
| IDENT "Constructor"; t = OPT tactic -> TacAnyConstructor t
diff --git a/parsing/g_tacticnew.ml4 b/parsing/g_tacticnew.ml4
new file mode 100644
index 000000000..4083fe82c
--- /dev/null
+++ b/parsing/g_tacticnew.ml4
@@ -0,0 +1,355 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Pp
+open Ast
+open Pcoq
+open Util
+open Tacexpr
+open Rawterm
+
+let tactic_kw =
+ [ "->"; "<-" ]
+let _ = List.iter (fun s -> Lexer.add_token("",s)) tactic_kw
+
+(* Hack to parse "with n := c ..." as a binder without conflicts with the *)
+(* admissible notation "with c1 c2..." *)
+let test_coloneq2 =
+ Gram.Entry.of_parser "test_int_coloneq"
+ (fun strm ->
+ match Stream.npeek 2 strm with
+ | [_; ("", ":=")] -> ()
+ | _ -> raise Stream.Failure)
+
+(* open grammar entries, possibly in quotified form *)
+ifdef Quotify then open Qast
+
+open Constr
+open Prim
+open Tactic
+
+(* Functions overloaded by quotifier *)
+
+let induction_arg_of_constr c =
+ try ElimOnIdent (Topconstr.constr_loc c,coerce_to_id c) with _ -> ElimOnConstr c
+
+let local_compute = [FBeta;FIota;FDeltaBut [];FZeta]
+
+let error_oldelim _ = error "OldElim no longer supported"
+
+ifdef Quotify then
+ let induction_arg_of_constr = function
+ | Qast.Node ("Nvar", [_;id]) -> Qast.Node ("ElimOnIdent", [id])
+ | c -> Qast.Node ("ElimOnConstr", [c])
+
+ifdef Quotify then
+let make_red_flag s = Qast.Apply ("make_red_flag", [s])
+
+ifdef Quotify then
+let local_compute =
+ Qast.List [
+ Qast.Node ("FBeta", []);
+ Qast.Node ("FDeltaBut", [Qast.List []]);
+ Qast.Node ("FIota", []);
+ Qast.Node ("FZeta", [])]
+
+ifdef Quotify then open Q
+
+let join_to_constr loc c2 = (fst loc), snd (Topconstr.constr_loc c2)
+
+(* Auxiliary grammar rules *)
+
+GEXTEND Gram
+ GLOBAL: simple_tactic constrarg constr_with_bindings quantified_hypothesis
+ red_expr int_or_var castedopenconstr;
+
+ int_or_var:
+ [ [ n = integer -> Genarg.ArgArg n
+ | id = identref -> Genarg.ArgVar id ] ]
+ ;
+ autoarg_depth:
+ [ [ n = OPT natural -> n ] ]
+ ;
+ autoarg_adding:
+ [ [ IDENT "adding" ; "["; l = LIST1 global; "]" -> l | -> [] ] ]
+ ;
+ autoarg_destructing:
+ [ [ IDENT "destructing" -> true | -> false ] ]
+ ;
+ autoarg_usingTDB:
+ [ [ "using"; "tdb" -> true | -> false ] ]
+ ;
+ autoargs:
+ [ [ a0 = autoarg_depth; l = autoarg_adding;
+ a2 = autoarg_destructing; a3 = autoarg_usingTDB -> (a0,l,a2,a3) ] ]
+ ;
+ (* Either an hypothesis or a ltac ref (variable or pattern metavariable) *)
+ id_or_ltac_ref:
+ [ [ id = base_ident -> AN id
+ | "?"; n = natural -> MetaNum (loc,n) ] ]
+ ;
+ (* Either a global ref or a ltac ref (variable or pattern metavariable) *)
+ global_or_ltac_ref:
+ [ [ qid = global -> AN qid
+ | "?"; n = natural -> MetaNum (loc,n) ] ]
+ ;
+ (* An identifier or a quotation meta-variable *)
+ id_or_meta:
+ [ [ id = identref -> AI id
+
+ (* This is used in quotations *)
+ | id = METAIDENT -> MetaId (loc,id) ] ]
+ ;
+ (* A number or a quotation meta-variable *)
+ num_or_meta:
+ [ [ n = integer -> AI n
+ | id = METAIDENT -> MetaId (loc,id)
+ ] ]
+ ;
+ constrarg:
+ [ [ IDENT "inst"; id = identref; "["; c = Constr.lconstr; "]" ->
+ ConstrContext (id, c)
+ | IDENT "eval"; rtc = Tactic.red_expr; "in"; c = Constr.lconstr ->
+ ConstrEval (rtc,c)
+ | IDENT "check"; c = Constr.lconstr -> ConstrTypeOf c
+ | c = Constr.lconstr -> ConstrTerm c ] ]
+ ;
+ castedopenconstr:
+ [ [ c = lconstr -> c ] ]
+ ;
+ induction_arg:
+ [ [ n = natural -> ElimOnAnonHyp n
+ | c = lconstr -> induction_arg_of_constr c
+ ] ]
+ ;
+ quantified_hypothesis:
+ [ [ id = base_ident -> NamedHyp id
+ | n = natural -> AnonHyp n ] ]
+ ;
+ conversion:
+ [ [ nl = LIST1 integer; c1 = constr; "with"; c2 = constr ->
+ (Some (nl,c1), c2)
+ | c1 = constr; "with"; c2 = constr -> (Some ([],c1), c2)
+ | c = constr -> (None, c) ] ]
+ ;
+ pattern_occ:
+ [ [ nl = LIST0 integer; c = [c=constr->c | g=global->Topconstr.CRef g]-> (nl,c) ] ]
+ ;
+ pattern_occ_hyp_list:
+ [ [ nl = LIST1 natural; IDENT "Goal" -> (Some nl,[])
+ | nl = LIST1 natural; id = id_or_meta; (g,l) = pattern_occ_hyp_list ->
+ (g,(id,nl)::l)
+ | IDENT "Goal" -> (Some [],[])
+ | id = id_or_meta; (g,l) = pattern_occ_hyp_list -> (g,(id,[])::l) ] ]
+ ;
+ clause_pattern:
+ [ [ "in"; p = pattern_occ_hyp_list -> p | -> None, [] ] ]
+ ;
+ intropatterns:
+ [ [ l = LIST0 simple_intropattern -> l ]]
+ ;
+ simple_intropattern:
+ [ [ "["; tc = LIST1 intropatterns SEP "|" ; "]" -> IntroOrAndPattern tc
+ | "("; tc = LIST1 simple_intropattern SEP "," ; ")" -> IntroOrAndPattern [tc]
+ | IDENT "_" -> IntroWildcard
+ | id = base_ident -> IntroIdentifier id
+ ] ]
+ ;
+ simple_binding:
+ [ [ id = base_ident; ":="; c = constr -> (loc, NamedHyp id, c)
+ | n = natural; ":="; c = constr -> (loc, AnonHyp n, c) ] ]
+ ;
+ binding_list:
+ [ [ test_coloneq2; n = natural; ":="; c = constr;
+ bl = LIST0 simple_binding ->
+ ExplicitBindings ((join_to_constr loc c,AnonHyp n, c) :: bl)
+ | test_coloneq2; id = base_ident; ":="; c2 = constr;
+ bl = LIST0 simple_binding ->
+ ExplicitBindings
+ ((join_to_constr loc c2,NamedHyp id, c2) :: bl)
+ | c1 = constr; bl = LIST0 constr ->
+ ImplicitBindings (c1 :: bl) ] ]
+ ;
+ constr_with_bindings:
+ [ [ c = constr; l = with_binding_list -> (c, l) ] ]
+ ;
+ with_binding_list:
+ [ [ "with"; bl = binding_list -> bl | -> NoBindings ] ]
+ ;
+ unfold_occ:
+ [ [ nl = LIST0 integer; c = global_or_ltac_ref -> (nl,c) ] ]
+ ;
+ red_flag:
+ [ [ IDENT "beta" -> FBeta
+ | IDENT "delta" -> FDeltaBut []
+ | IDENT "iota" -> FIota
+ | IDENT "zeta" -> FZeta
+ | IDENT "delta"; "["; idl = LIST1 global_or_ltac_ref; "]" -> FConst idl
+ | IDENT "delta"; "-"; "["; idl = LIST1 global_or_ltac_ref; "]" -> FDeltaBut idl
+ ] ]
+ ;
+ red_tactic:
+ [ [ IDENT "red" -> Red false
+ | IDENT "hnf" -> Hnf
+ | IDENT "simpl"; po = OPT pattern_occ -> Simpl po
+ | IDENT "cbv"; s = LIST1 red_flag -> Cbv (make_red_flag s)
+ | IDENT "lazy"; s = LIST1 red_flag -> Lazy (make_red_flag s)
+ | IDENT "compute" -> Cbv (make_red_flag [FBeta;FIota;FDeltaBut [];FZeta])
+ | IDENT "unfold"; ul = LIST1 unfold_occ -> Unfold ul
+ | IDENT "fold"; cl = LIST1 constr -> Fold cl
+ | IDENT "pattern"; pl = LIST1 pattern_occ -> Pattern pl ] ]
+ ;
+ (* This is [red_tactic] including possible extensions *)
+ red_expr:
+ [ [ IDENT "red" -> Red false
+ | IDENT "hnf" -> Hnf
+ | IDENT "simpl"; po = OPT pattern_occ -> Simpl po
+ | IDENT "cbv"; s = LIST1 red_flag -> Cbv (make_red_flag s)
+ | IDENT "lazy"; s = LIST1 red_flag -> Lazy (make_red_flag s)
+ | IDENT "compute" -> Cbv (make_red_flag [FBeta;FIota;FDeltaBut [];FZeta])
+ | IDENT "unfold"; ul = LIST1 unfold_occ -> Unfold ul
+ | IDENT "fold"; cl = LIST1 constr -> Fold cl
+ | IDENT "pattern"; pl = LIST1 pattern_occ -> Pattern pl
+ | s = IDENT; c = constr -> ExtraRedExpr (s,c) ] ]
+ ;
+ hypident:
+ [ [ id = id_or_meta -> InHyp id
+ | "("; "type"; "of"; id = id_or_meta; ")" -> InHypType id ] ]
+ ;
+ clause:
+ [ [ "in"; idl = LIST1 hypident -> idl
+ | -> [] ] ]
+ ;
+ fixdecl:
+ [ [ id = base_ident; "/"; n = natural; ":"; c = constr -> (id,n,c) ] ]
+ ;
+ cofixdecl:
+ [ [ id = base_ident; ":"; c = constr -> (id,c) ] ]
+ ;
+ hintbases:
+ [ [ "with"; "*" -> None
+ | "with"; l = LIST1 IDENT -> Some l
+ | -> Some [] ] ]
+ ;
+ eliminator:
+ [ [ "using"; el = constr_with_bindings -> el ] ]
+ ;
+ with_names:
+ [ [ "as"; "["; ids = LIST1 (LIST0 base_ident) SEP "|"; "]" -> ids
+ | -> [] ] ]
+ ;
+ simple_tactic:
+ [ [
+ (* Basic tactics *)
+ IDENT "intros"; IDENT "until"; id = quantified_hypothesis ->
+ TacIntrosUntil id
+ | IDENT "intros"; pl = intropatterns -> TacIntroPattern pl
+ | IDENT "intro"; id = base_ident; IDENT "after"; id2 = identref ->
+ TacIntroMove (Some id, Some id2)
+ | IDENT "intro"; IDENT "after"; id2 = identref ->
+ TacIntroMove (None, Some id2)
+ | IDENT "intro"; id = base_ident -> TacIntroMove (Some id, None)
+ | IDENT "intro" -> TacIntroMove (None, None)
+
+ | IDENT "assumption" -> TacAssumption
+ | IDENT "exact"; c = lconstr -> TacExact c
+
+ | IDENT "apply"; cl = constr_with_bindings -> TacApply cl
+ | IDENT "elim"; cl = constr_with_bindings; el = OPT eliminator ->
+ TacElim (cl,el)
+ | IDENT "elimtype"; c = lconstr -> TacElimType c
+ | IDENT "case"; cl = constr_with_bindings -> TacCase cl
+ | IDENT "casetype"; c = lconstr -> TacCaseType c
+ | "fix"; n = natural -> TacFix (None,n)
+ | "fix"; id = base_ident; n = natural -> TacFix (Some id,n)
+ | "fix"; id = base_ident; n = natural; "with"; fd = LIST0 fixdecl ->
+ TacMutualFix (id,n,fd)
+ | "cofix" -> TacCofix None
+ | "cofix"; id = base_ident -> TacCofix (Some id)
+ | "cofix"; id = base_ident; "with"; fd = LIST0 cofixdecl ->
+ TacMutualCofix (id,fd)
+
+ | IDENT "cut"; c = lconstr -> TacCut c
+ | IDENT "assert"; c = lconstr ->
+ (match c with
+ Topconstr.CCast(_,c,t) -> TacTrueCut (Some (coerce_to_id c),t)
+ | _ -> TacTrueCut (None,c))
+ | IDENT "assert"; c = lconstr; ":="; b = lconstr ->
+ TacForward (false,Names.Name (coerce_to_id c),b)
+ | IDENT "pose"; c = lconstr; ":="; b = lconstr ->
+ TacForward (true,Names.Name (coerce_to_id c),b)
+ | IDENT "pose"; b = lconstr -> TacForward (true,Names.Anonymous,b)
+ | IDENT "generalize"; lc = LIST1 constr -> TacGeneralize lc
+ | IDENT "generalize"; IDENT "dependent"; c = lconstr ->
+ TacGeneralizeDep c
+ | IDENT "lettac"; id = base_ident; ":="; c = lconstr; p = clause_pattern
+ -> TacLetTac (id,c,p)
+ | IDENT "instantiate"; n = natural; c = lconstr -> TacInstantiate (n,c)
+
+ | IDENT "specialize"; n = OPT natural; lcb = constr_with_bindings ->
+ TacSpecialize (n,lcb)
+ | IDENT "lapply"; c = lconstr -> TacLApply c
+
+ (* Derived basic tactics *)
+ | IDENT "induction"; h = quantified_hypothesis -> TacOldInduction h
+ | IDENT "newinduction"; c = induction_arg; el = OPT eliminator;
+ ids = with_names -> TacNewInduction (c,el,ids)
+ | IDENT "double"; IDENT "induction"; h1 = quantified_hypothesis;
+ h2 = quantified_hypothesis -> TacDoubleInduction (h1,h2)
+ | IDENT "destruct"; h = quantified_hypothesis -> TacOldDestruct h
+ | IDENT "newdestruct"; c = induction_arg; el = OPT eliminator;
+ ids = with_names -> TacNewDestruct (c,el,ids)
+ | IDENT "decompose"; IDENT "record" ; c = lconstr -> TacDecomposeAnd c
+ | IDENT "decompose"; IDENT "sum"; c = lconstr -> TacDecomposeOr c
+ | IDENT "decompose"; "["; l = LIST1 global_or_ltac_ref; "]"; c = lconstr
+ -> TacDecompose (l,c)
+
+ (* Automation tactic *)
+ | IDENT "trivial"; db = hintbases -> TacTrivial db
+ | IDENT "auto"; n = OPT natural; db = hintbases -> TacAuto (n, db)
+
+ | IDENT "autotdb"; n = OPT natural -> TacAutoTDB n
+ | IDENT "cdhyp"; id = identref -> TacDestructHyp (true,id)
+ | IDENT "dhyp"; id = identref -> TacDestructHyp (false,id)
+ | IDENT "dconcl" -> TacDestructConcl
+ | IDENT "superauto"; l = autoargs -> TacSuperAuto l
+ | IDENT "auto"; n = OPT natural; IDENT "decomp"; p = OPT natural ->
+ TacDAuto (n, p)
+
+ (* Context management *)
+ | IDENT "clear"; l = LIST1 id_or_ltac_ref -> TacClear l
+ | IDENT "clearbody"; l = LIST1 id_or_ltac_ref -> TacClearBody l
+ | IDENT "move"; id1 = identref; IDENT "after"; id2 = identref ->
+ TacMove (true,id1,id2)
+ | IDENT "rename"; id1 = identref; IDENT "into"; id2 = identref ->
+ TacRename (id1,id2)
+
+ (* Constructors *)
+ | IDENT "left"; bl = with_binding_list -> TacLeft bl
+ | IDENT "right"; bl = with_binding_list -> TacRight bl
+ | IDENT "split"; bl = with_binding_list -> TacSplit (false,bl)
+ | IDENT "exists"; bl = binding_list -> TacSplit (true,bl)
+ | IDENT "exists" -> TacSplit (true,NoBindings)
+ | IDENT "constructor"; n = num_or_meta; l = with_binding_list ->
+ TacConstructor (n,l)
+ | IDENT "constructor"; t = OPT tactic -> TacAnyConstructor t
+
+ (* Equivalence relations *)
+ | IDENT "reflexivity" -> TacReflexivity
+ | IDENT "symmetry" -> TacSymmetry
+ | IDENT "transitivity"; c = lconstr -> TacTransitivity c
+
+ (* Conversion *)
+ | r = red_tactic; cl = clause -> TacReduce (r, cl)
+ (* Change ne doit pas s'appliquer dans un Definition t := Eval ... *)
+ | IDENT "change"; (oc,c) = conversion; cl = clause -> TacChange (oc,c,cl)
+ ] ]
+ ;
+END;;
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 68e6fe858..a082772ac 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -27,6 +27,9 @@ open Genarg
let evar_constr loc = CHole loc
+let class_rawexpr = G_basevernac.class_rawexpr
+let thm_token = G_proofs.thm_token
+
(* Rem: do not join the different GEXTEND into one, it breaks native *)
(* compilation on PowerPC and Sun architectures *)
@@ -325,15 +328,13 @@ GEXTEND Gram
| IDENT "Chapter"; id = base_ident -> VernacBeginSection id ] ]
;
- module_vardecls: (* This is interpreted by Pcoq.abstract_binder *)
- [ [ id = base_ident; idl = ident_comma_list_tail; ":"; mty = Module.module_type
+ module_vardecls:
+ [ [ "("; id = base_ident; idl = ident_comma_list_tail;
+ ":"; mty = Module.module_type; ")"
-> (id::idl,mty) ] ]
;
- module_binders:
- [ [ "["; bl = LIST1 module_vardecls SEP ";"; "]" -> bl ] ]
- ;
module_binders_list:
- [ [ bls = LIST0 module_binders -> List.flatten bls ] ]
+ [ [ bl = LIST0 module_vardecls -> bl ] ]
;
of_module_type:
[ [ ":"; mty = Module.module_type -> (mty, true)
@@ -417,7 +418,7 @@ GEXTEND Gram
let l = list_tabulate (fun _ -> (CHole (loc),None)) n in
CApp (loc,c,l)
| None -> c in
- VernacNotation ("'"^id^"'",c,[],None)
+ VernacNotation ("'"^id^"'",c,[],None,None)
| IDENT "Implicits"; qid = global; "["; l = LIST0 natural; "]" ->
VernacDeclareImplicits (qid,Some l)
| IDENT "Implicits"; qid = global -> VernacDeclareImplicits (qid,None)
@@ -474,7 +475,7 @@ GEXTEND Gram
VernacRequireFrom (export, specif, id, filename) *)
| IDENT "Require"; export = export_token; specif = specif_token;
filename = STRING ->
- VernacRequireFrom (export, specif, filename)
+ VernacRequireFrom (Some export, specif, filename)
| IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 STRING ->
VernacDeclareMLModule l
| IDENT "Import"; qidl = LIST1 global -> VernacImport (false,qidl)
diff --git a/parsing/g_vernacnew.ml4 b/parsing/g_vernacnew.ml4
new file mode 100644
index 000000000..e88e97141
--- /dev/null
+++ b/parsing/g_vernacnew.ml4
@@ -0,0 +1,817 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Pp
+open Util
+open Names
+open Coqast
+open Topconstr
+open Vernacexpr
+open Pcoq
+open Tactic
+open Decl_kinds
+open Genarg
+open Extend
+open Ppextend
+open Goptions
+
+open Prim
+open Constr
+open Vernac_
+open Module
+
+
+let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:" ]
+let _ = List.iter (fun s -> Lexer.add_token ("",s)) vernac_kw
+
+(* Rem: do not join the different GEXTEND into one, it breaks native *)
+(* compilation on PowerPC and Sun architectures *)
+
+let check_command = Gram.Entry.create "vernac:check_command"
+let class_rawexpr = Gram.Entry.create "vernac:class_rawexpr"
+let thm_token = Gram.Entry.create "vernac:thm_token"
+let def_body = Gram.Entry.create "vernac:def_body"
+
+GEXTEND Gram
+ GLOBAL: vernac gallina_ext;
+ vernac:
+ (* Better to parse ";" here: in case of failure (e.g. in coerce_to_var), *)
+ (* ";" is still in the stream and discard_to_dot works correctly *)
+ [ [ g = gallina; ";" -> g
+ | g = gallina_ext; ";" -> g
+ | c = command; ";" -> c
+ | c = syntax; ";" -> c
+ | "["; l = LIST1 located_vernac; "]"; ";" -> VernacList l
+ ] ]
+ ;
+ vernac: FIRST
+ [ [ IDENT "Time"; v = vernac -> VernacTime v ] ]
+ ;
+ vernac: LAST
+ [ [ gln = OPT[n=natural; ":" -> n];
+ tac = subgoal_command; ";" -> tac gln ] ]
+ ;
+ subgoal_command:
+ [ [ c = check_command -> c
+ | d = use_default_tac; tac = Tactic.tactic ->
+ (fun g ->
+ let g = match g with Some gl -> gl | _ -> 1 in
+ VernacSolve(g,tac,d)) ] ]
+ ;
+ located_vernac:
+ [ [ v = vernac -> loc, v ] ]
+ ;
+ use_default_tac:
+ [ [ "!!" -> false
+ | -> true ] ]
+ ;
+END
+
+
+let test_plurial_form = function
+ | [_] ->
+ Options.if_verbose warning
+ "Keywords Variables/Hypotheses/Parameters expect more than one assumption"
+ | _ -> ()
+
+let no_coercion loc (c,x) =
+ if c then Util.user_err_loc
+ (loc,"no_coercion",Pp.str"no coercion allowed here");
+ x
+
+(* Gallina declarations *)
+GEXTEND Gram
+ GLOBAL: gallina gallina_ext thm_token def_body;
+
+ gallina:
+ (* Definition, Theorem, Variable, Axiom, ... *)
+ [ [ thm = thm_token; id = base_ident; bl = LIST0 binder; ":";
+ c = lconstr ->
+ VernacStartTheoremProof (thm, id, (bl, c), false, (fun _ _ -> ()))
+ | (f,d,e) = def_token; id = base_ident; b = def_body ->
+ VernacDefinition (d, id, b, f, e)
+ | stre = assumption_token; bl = LIST1 simple_binder_coe ->
+ VernacAssumption (stre, bl)
+ | stre = assumptions_token; bl = LIST1 simple_binder_coe ->
+ test_plurial_form bl;
+ VernacAssumption (stre, bl)
+ (* Gallina inductive declarations *)
+ | OPT[IDENT "Mutual"]; f = finite_token;
+ indl = LIST1 inductive_definition SEP "with" ->
+ VernacInductive (f,indl)
+ | IDENT "Fixpoint"; recs = LIST1 rec_definition SEP "with" ->
+ VernacFixpoint recs
+ | IDENT "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" ->
+ VernacCoFixpoint corecs
+ | IDENT "Scheme"; l = LIST1 scheme SEP "with" -> VernacScheme l ] ]
+ ;
+ gallina_ext:
+ [ [ record_token; oc = opt_coercion; name = base_ident;
+ ps = LIST0 simple_binder; ":";
+ s = lconstr; ":="; cstr = OPT base_ident; "{";
+ fs = LIST0 local_decl_expr; "}" ->
+ VernacRecord ((oc,name),ps,s,cstr,fs)
+ | f = finite_token; s = csort; id = base_ident;
+ indpar = LIST0 simple_binder; ":="; lc = constructor_list ->
+ VernacInductive (f,[id,indpar,s,lc])
+ ] ]
+ ;
+ thm_token:
+ [ [ IDENT "Theorem" -> Theorem
+ | IDENT "Lemma" -> Lemma
+ | IDENT "Fact" -> Fact
+ | IDENT "Remark" -> Remark ] ]
+ ;
+ def_token:
+ [ [ IDENT "Definition" -> (fun _ _ -> ()), Global, GDefinition
+ | IDENT "Local" -> (fun _ _ -> ()), Local, LDefinition
+ | IDENT "SubClass" -> Class.add_subclass_hook, Global, GCoercion
+ | IDENT "Local"; IDENT "SubClass" ->
+ Class.add_subclass_hook, Local, LCoercion ] ]
+ ;
+ assumption_token:
+ [ [ IDENT "Hypothesis" -> (Local, Logical)
+ | IDENT "Variable" -> (Local, Definitional)
+ | IDENT "Axiom" -> (Global, Logical)
+ | IDENT "Parameter" -> (Global, Definitional) ] ]
+ ;
+ assumptions_token:
+ [ [ IDENT "Hypotheses" -> (Local, Logical)
+ | IDENT "Variables" -> (Local, Definitional)
+ | IDENT "Parameters" -> (Global, Definitional) ] ]
+ ;
+ finite_token:
+ [ [ IDENT "Inductive" -> true
+ | IDENT "CoInductive" -> false ] ]
+ ;
+ record_token:
+ [ [ IDENT "Record" -> () | IDENT "Structure" -> () ] ]
+ ;
+ (* Simple definitions *)
+ def_body:
+ [ [ bl = LIST0 binder; ":="; red = reduce; c = lconstr ->
+ (match c with
+ CCast(_,c,t) -> DefineBody (bl, red, c, Some t)
+ | _ -> DefineBody (bl, red, c, None))
+ | bl = LIST0 binder; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
+ DefineBody (bl, red, c, Some t)
+ | bl = LIST0 binder; ":"; t = lconstr ->
+ ProveBody (bl, t) ] ]
+ ;
+ reduce:
+ [ [ IDENT "Eval"; r = Tactic.red_expr; "in" -> Some r
+ | -> None ] ]
+ ;
+ (* Inductives and records *)
+ inductive_definition:
+ [ [ id = base_ident; indpar = LIST0 simple_binder; ":"; c = lconstr; ":=";
+ lc = constructor_list -> (id,indpar,c,lc) ] ]
+ ;
+ constructor_list:
+ [ [ "|"; l = LIST1 constructor_binder SEP "|" -> l
+ | l = LIST1 constructor_binder SEP "|" -> l
+ | -> [] ] ]
+ ;
+ csort:
+ [ [ s = sort -> CSort (loc,s) ] ]
+ ;
+ opt_coercion:
+ [ [ ">" -> true
+ | -> false ] ]
+ ;
+ (* (co)-fixpoints *)
+ rec_definition:
+ [ [ id = base_ident; bl = LIST1 binder_nodef; ":"; type_ = lconstr;
+ ":="; def = lconstr ->
+ let ni = List.length (List.flatten (List.map fst bl)) - 1 in
+ let loc0 = fst (List.hd (fst (List.hd bl))) in
+ let loc1 = join_loc loc0 (constr_loc type_) in
+ let loc2 = join_loc loc0 (constr_loc def) in
+ (id, ni, CProdN (loc1,bl,type_), CLambdaN (loc2,bl,def)) ] ]
+ ;
+ corec_definition:
+ [ [ id = base_ident; ":"; c = lconstr; ":="; def = lconstr ->
+ (id,c,def) ] ]
+ ;
+ (* Inductive schemes *)
+ scheme:
+ [ [ id = base_ident; ":="; dep = dep_scheme; "for"; ind = global;
+ IDENT "Sort"; s = sort ->
+ (id,dep,ind,s) ] ]
+ ;
+ dep_scheme:
+ [ [ IDENT "Induction" -> true
+ | IDENT "Minimality" -> false ] ]
+ ;
+ (* Various Binders *)
+ (* ... without coercions *)
+ simple_binder:
+ [ [ b = simple_binder_coe -> no_coercion loc b ] ]
+ ;
+ binder:
+ [ [ na = name -> LocalRawAssum([na],CHole loc)
+ | "("; na = name; ")" -> LocalRawAssum([na],CHole loc)
+ | "("; na = name; ":"; c = lconstr; ")"
+ -> LocalRawAssum([na],c)
+ | "("; na = name; ":="; c = lconstr; ")" ->
+ LocalRawDef (na,c)
+ ] ]
+ ;
+ binder_nodef:
+ [ [ b = binder ->
+ (match b with
+ LocalRawAssum(l,ty) -> (l,ty)
+ | LocalRawDef _ ->
+ Util.user_err_loc
+ (loc,"fix_param",Pp.str"defined binder not allowed here")) ] ]
+ ;
+ (* ... with coercions *)
+ local_decl_expr:
+ [ [ id = base_ident -> (false,AssumExpr(id,CHole loc))
+ | "("; id = base_ident; ")" -> (false,AssumExpr(id,CHole loc))
+ | "("; id = base_ident; oc = of_type_with_opt_coercion;
+ t = lconstr; ")" ->
+ (oc,AssumExpr (id,t))
+ | "("; id = base_ident; oc = of_type_with_opt_coercion;
+ t = lconstr; ":="; b = lconstr; ")" ->
+ (oc,DefExpr (id,b,Some t))
+ | "("; id = base_ident; ":="; b = lconstr; ")" ->
+ match b with
+ CCast(_,b,t) -> (false,DefExpr(id,b,Some t))
+ | _ -> (false,DefExpr(id,b,None)) ] ]
+ ;
+ simple_binder_coe:
+ [ [ id=base_ident -> (false,(id,CHole loc))
+ | "("; id = base_ident; ")" -> (false,(id,CHole loc))
+ | "("; id = base_ident; oc = of_type_with_opt_coercion;
+ t = lconstr; ")" ->
+ (oc,(id,t)) ] ]
+ ;
+ constructor_binder:
+ [ [ id = base_ident; coe = of_type_with_opt_coercion; c = lconstr ->
+ (coe,(id,c)) ] ]
+ ;
+ of_type_with_opt_coercion:
+ [ [ ":>" -> true
+ | ":"; ">" -> true
+ | ":" -> false ] ]
+ ;
+END
+
+
+(* Modules and Sections *)
+GEXTEND Gram
+ GLOBAL: gallina_ext module_expr module_type;
+
+ gallina_ext:
+ [ [ (* Interactive module declaration *)
+ IDENT "Module"; id = base_ident;
+ bl = LIST0 module_binder; mty_o = OPT of_module_type;
+ mexpr_o = OPT is_module_expr ->
+ VernacDefineModule (id, bl, mty_o, mexpr_o)
+
+ | IDENT "Module"; "Type"; id = base_ident;
+ bl = LIST0 module_binder; mty_o = OPT is_module_type ->
+ VernacDeclareModuleType (id, bl, mty_o)
+
+ | IDENT "Declare"; IDENT "Module"; id = base_ident;
+ bl = LIST0 module_binder; mty_o = OPT of_module_type;
+ mexpr_o = OPT is_module_expr ->
+ VernacDeclareModule (id, bl, mty_o, mexpr_o)
+ (* Section beginning *)
+ | IDENT "Section"; id = base_ident -> VernacBeginSection id
+ | IDENT "Chapter"; id = base_ident -> VernacBeginSection id
+
+ (* This end a Section a Module or a Module Type *)
+ | IDENT "End"; id = base_ident -> VernacEndSegment id
+
+ (* Requiring an already compiled module *)
+ | IDENT "Require"; export = export_token; specif = specif_token;
+ qidl = LIST1 global ->
+ VernacRequire (export, specif, qidl)
+ | IDENT "Require"; export = export_token; specif = specif_token;
+ filename = STRING ->
+ VernacRequireFrom (export, specif, filename)
+ | IDENT "Import"; qidl = LIST1 global -> VernacImport (false,qidl)
+ | IDENT "Export"; qidl = LIST1 global -> VernacImport (true,qidl) ] ]
+ ;
+ export_token:
+ [ [ IDENT "Import" -> Some false
+ | IDENT "Export" -> Some true
+ | IDENT "Closed" -> None
+ | -> Some false ] ]
+ ;
+ specif_token:
+ [ [ IDENT "Implementation" -> Some false
+ | IDENT "Specification" -> Some true
+ | -> None ] ]
+ ;
+ of_module_type:
+ [ [ ":"; mty = module_type -> (mty, true)
+ | "<:"; mty = module_type -> (mty, false) ] ]
+ ;
+ is_module_type:
+ [ [ ":="; mty = module_type -> mty ] ]
+ ;
+ is_module_expr:
+ [ [ ":="; mexpr = module_expr -> mexpr ] ]
+ ;
+
+ (* Module binder *)
+ module_binder:
+ [ [ "("; id = base_ident; ":"; mty = module_type; ")" ->
+ ([id],mty) ] ]
+ ;
+
+ (* Module expressions *)
+ module_expr:
+ [ [ qid = qualid -> CMEident qid
+ | me1 = module_expr; me2 = module_expr -> CMEapply (me1,me2)
+ | "("; me = module_expr; ")" -> me
+(* ... *)
+ ] ]
+ ;
+ with_declaration:
+ [ [ IDENT "Definition"; id = base_ident; ":="; c = Constr.constr ->
+ CWith_Definition (id,c)
+ | IDENT "Module"; id = base_ident; ":="; qid = qualid ->
+ CWith_Module (id,qid)
+ ] ]
+ ;
+ module_type:
+ [ [ qid = qualid -> CMTEident qid
+(* ... *)
+ | mty = module_type; "with"; decl = with_declaration ->
+ CMTEwith (mty,decl) ] ]
+ ;
+END
+
+(* Extensions: implicits, coercions, etc. *)
+GEXTEND Gram
+ GLOBAL: gallina_ext;
+
+ gallina_ext:
+ [ [ (* Transparent and Opaque *)
+ IDENT "Transparent"; l = LIST1 global -> VernacSetOpacity (false, l)
+ | IDENT "Opaque"; l = LIST1 global -> VernacSetOpacity (true, l)
+
+ (* Canonical structure *)
+ | IDENT "Canonical"; IDENT "Structure"; qid = global ->
+ VernacCanonical qid
+ | IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
+ let s = Ast.coerce_global_to_id qid in
+ VernacDefinition (Global,s,d,Recordobj.add_object_hook,SCanonical)
+
+ (* Coercions *)
+ | IDENT "Coercion"; qid = global; d = def_body ->
+ let s = Ast.coerce_global_to_id qid in
+ VernacDefinition (Global,s,d,Class.add_coercion_hook,GCoercion)
+ | IDENT "Coercion"; IDENT "Local"; qid = global; d = def_body ->
+ let s = Ast.coerce_global_to_id qid in
+ VernacDefinition (Local,s,d,Class.add_coercion_hook,LCoercion)
+ | IDENT "Identity"; IDENT "Coercion"; IDENT "Local"; f = base_ident;
+ ":"; s = class_rawexpr; ">->"; t = class_rawexpr ->
+ VernacIdentityCoercion (Local, f, s, t)
+ | IDENT "Identity"; IDENT "Coercion"; f = base_ident; ":";
+ s = class_rawexpr; ">->"; t = class_rawexpr ->
+ VernacIdentityCoercion (Global, f, s, t)
+ | IDENT "Coercion"; IDENT "Local"; qid = global; ":";
+ s = class_rawexpr; ">->"; t = class_rawexpr ->
+ VernacCoercion (Local, qid, s, t)
+ | IDENT "Coercion"; qid = global; ":"; s = class_rawexpr; ">->";
+ t = class_rawexpr ->
+ VernacCoercion (Global, qid, s, t)
+
+ (* Implicit *)
+ | IDENT "Syntactic"; IDENT "Definition"; id = IDENT; ":="; c = lconstr;
+ n = OPT [ "|"; n = natural -> n ] ->
+ let c = match n with
+ | Some n ->
+ let l = list_tabulate (fun _ -> (CHole (loc),None)) n in
+ CApp (loc,c,l)
+ | None -> c in
+ VernacNotation ("'"^id^"'",c,[],None,None)
+ | IDENT "Implicits"; qid = global; "["; l = LIST0 natural; "]" ->
+ VernacDeclareImplicits (qid,Some l)
+ | IDENT "Implicits"; qid = global -> VernacDeclareImplicits (qid,None)
+
+ (* For compatibility *)
+ | IDENT "Implicit"; IDENT "Arguments"; IDENT "On" ->
+ VernacSetOption
+ (Goptions.SecondaryTable ("Implicit","Arguments"),
+ BoolValue true)
+ | IDENT "Implicit"; IDENT "Arguments"; IDENT "Off" ->
+ VernacSetOption
+ (Goptions.SecondaryTable ("Implicit","Arguments"),
+ BoolValue false) ] ]
+ ;
+END
+
+GEXTEND Gram
+ GLOBAL: command check_command class_rawexpr;
+
+ command:
+ [ [ IDENT "Comments"; l = LIST0 comment -> VernacComments l
+
+ (* System directory *)
+ | IDENT "Pwd" -> VernacChdir None
+ | IDENT "Cd" -> VernacChdir None
+ | IDENT "Cd"; dir = STRING -> VernacChdir (Some dir)
+
+ (* Toplevel control *)
+ | IDENT "Drop" -> VernacToplevelControl Drop
+ | IDENT "ProtectedLoop" -> VernacToplevelControl ProtectedLoop
+ | IDENT "Quit" -> VernacToplevelControl Quit
+
+ | IDENT "Load"; verbosely = [ IDENT "Verbose" -> true | -> false ];
+ s = [ s = STRING -> s | s = IDENT -> s ] ->
+ VernacLoad (verbosely, s)
+ | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 STRING ->
+ VernacDeclareMLModule l
+
+ (* Dump of the universe graph - to file or to stdout *)
+ | IDENT "Dump"; IDENT "Universes"; fopt = OPT STRING ->
+ VernacPrint (PrintUniverses fopt)
+
+ | IDENT "Locate"; l = locatable -> VernacLocate l
+
+ (* Managing load paths *)
+ | IDENT "Add"; IDENT "LoadPath"; dir = STRING; alias = as_dirpath ->
+ VernacAddLoadPath (false, dir, alias)
+ | IDENT "Add"; IDENT "Rec"; IDENT "LoadPath"; dir = STRING;
+ alias = as_dirpath -> VernacAddLoadPath (true, dir, alias)
+ | IDENT "Remove"; IDENT "LoadPath"; dir = STRING ->
+ VernacRemoveLoadPath dir
+
+ (* For compatibility *)
+ | IDENT "AddPath"; dir = STRING; "as"; alias = as_dirpath ->
+ VernacAddLoadPath (false, dir, alias)
+ | IDENT "AddRecPath"; dir = STRING; "as"; alias = as_dirpath ->
+ VernacAddLoadPath (true, dir, alias)
+ | IDENT "DelPath"; dir = STRING ->
+ VernacRemoveLoadPath dir
+
+ (* Type-Checking (pas dans le refman) *)
+ | "Type"; c = lconstr -> VernacGlobalCheck c
+
+ (* Printing (careful factorization of entries) *)
+ | IDENT "Print"; p = printable -> VernacPrint p
+ | IDENT "Print"; qid = global -> VernacPrint (PrintName qid)
+ | IDENT "Print" -> VernacPrint PrintLocalContext
+ | IDENT "Print"; IDENT "Module"; "Type"; qid = global ->
+ VernacPrint (PrintModuleType qid)
+ | IDENT "Print"; IDENT "Module"; qid = global ->
+ VernacPrint (PrintModule qid)
+ | IDENT "Inspect"; n = natural -> VernacPrint (PrintInspect n)
+
+ (* Searching the environment *)
+ | IDENT "Search"; qid = global; l = in_or_out_modules ->
+ VernacSearch (SearchHead qid, l)
+ | IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules ->
+ VernacSearch (SearchPattern c, l)
+ | IDENT "SearchRewrite"; c = constr_pattern; l = in_or_out_modules ->
+ VernacSearch (SearchRewrite c, l)
+ | IDENT "SearchAbout"; qid = global; l = in_or_out_modules ->
+ VernacSearch (SearchAbout qid, l)
+
+ | IDENT "Add"; IDENT "ML"; IDENT "Path"; dir = STRING ->
+ VernacAddMLPath (false, dir)
+ | IDENT "Add"; IDENT "Rec"; IDENT "ML"; IDENT "Path"; dir = STRING ->
+ VernacAddMLPath (true, dir)
+
+ (* Pour intervenir sur les tables de paramètres *)
+ | "Set"; table = IDENT; field = IDENT; v = option_value ->
+ VernacSetOption (SecondaryTable (table,field),v)
+ | "Set"; table = IDENT; field = IDENT; lv = LIST1 option_ref_value ->
+ VernacAddOption (SecondaryTable (table,field),lv)
+ | "Set"; table = IDENT; field = IDENT ->
+ VernacSetOption (SecondaryTable (table,field),BoolValue true)
+ | IDENT "Unset"; table = IDENT; field = IDENT ->
+ VernacUnsetOption (SecondaryTable (table,field))
+ | IDENT "Unset"; table = IDENT; field = IDENT; lv = LIST1 option_ref_value ->
+ VernacRemoveOption (SecondaryTable (table,field),lv)
+ | "Set"; table = IDENT; value = option_value ->
+ VernacSetOption (PrimaryTable table, value)
+ | "Set"; table = IDENT ->
+ VernacSetOption (PrimaryTable table, BoolValue true)
+ | IDENT "Unset"; table = IDENT ->
+ VernacUnsetOption (PrimaryTable table)
+
+ | IDENT "Print"; IDENT "Table"; table = IDENT; field = IDENT ->
+ VernacPrintOption (SecondaryTable (table,field))
+ | IDENT "Print"; IDENT "Table"; table = IDENT ->
+ VernacPrintOption (PrimaryTable table)
+
+ | IDENT "Add"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
+ -> VernacAddOption (SecondaryTable (table,field), v)
+
+ (* Un value global ci-dessous va être caché par un field au dessus! *)
+ | IDENT "Add"; table = IDENT; v = LIST1 option_ref_value ->
+ VernacAddOption (PrimaryTable table, v)
+
+ | IDENT "Test"; table = IDENT; field = IDENT; v = LIST1 option_ref_value
+ -> VernacMemOption (SecondaryTable (table,field), v)
+ | IDENT "Test"; table = IDENT; field = IDENT ->
+ VernacPrintOption (SecondaryTable (table,field))
+ | IDENT "Test"; table = IDENT; v = LIST1 option_ref_value ->
+ VernacMemOption (PrimaryTable table, v)
+ | IDENT "Test"; table = IDENT ->
+ VernacPrintOption (PrimaryTable table)
+
+ | IDENT "Remove"; table = IDENT; field = IDENT; v= LIST1 option_ref_value
+ -> VernacRemoveOption (SecondaryTable (table,field), v)
+ | IDENT "Remove"; table = IDENT; v = LIST1 option_ref_value ->
+ VernacRemoveOption (PrimaryTable table, v) ] ]
+ ;
+ check_command: (* TODO: rapprocher Eval et Check *)
+ [ [ IDENT "Eval"; r = Tactic.red_expr; "in"; c = lconstr ->
+ fun g -> VernacCheckMayEval (Some r, g, c)
+ | IDENT "Check"; c = lconstr ->
+ fun g -> VernacCheckMayEval (None, g, c) ] ]
+ ;
+ printable:
+ [ [ IDENT "Term"; qid = global -> PrintName qid
+ | IDENT "All" -> PrintFullContext
+ | IDENT "Section"; s = global -> PrintSectionContext s
+ | IDENT "Grammar"; uni = IDENT; ent = IDENT ->
+ (* This should be in "syntax" section but is here for factorization*)
+ PrintGrammar (uni, ent)
+ | IDENT "LoadPath" -> PrintLoadPath
+ | IDENT "Modules" -> PrintModules
+
+ | IDENT "ML"; IDENT "Path" -> PrintMLLoadPath
+ | IDENT "ML"; IDENT "Modules" -> PrintMLModules
+ | IDENT "Graph" -> PrintGraph
+ | IDENT "Classes" -> PrintClasses
+ | IDENT "Coercions" -> PrintCoercions
+ | IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr
+ -> PrintCoercionPaths (s,t)
+ | IDENT "Tables" -> PrintTables
+ | IDENT "Proof"; qid = global -> PrintOpaqueName qid
+ | IDENT "Hint" -> PrintHintGoal
+ | IDENT "Hint"; qid = global -> PrintHint qid
+ | IDENT "Hint"; "*" -> PrintHintDb
+ | IDENT "HintDb"; s = IDENT -> PrintHintDbName s
+ | IDENT "Scope"; s = IDENT -> PrintScope s ] ]
+ ;
+ class_rawexpr:
+ [ [ IDENT "FUNCLASS" -> FunClass
+ | IDENT "SORTCLASS" -> SortClass
+ | qid = global -> RefClass qid ] ]
+ ;
+ locatable:
+ [ [ qid = global -> LocateTerm qid
+ | IDENT "File"; f = STRING -> LocateFile f
+ | IDENT "Library"; qid = global -> LocateLibrary qid
+ | s = STRING -> LocateNotation s ] ]
+ ;
+ option_value:
+ [ [ n = integer -> IntValue n
+ | s = STRING -> StringValue s ] ]
+ ;
+ option_ref_value:
+ [ [ id = global -> QualidRefValue id
+ | s = STRING -> StringRefValue s ] ]
+ ;
+ as_dirpath:
+ [ [ d = OPT [ "as"; d = dirpath -> d ] -> d ] ]
+ ;
+ in_or_out_modules:
+ [ [ IDENT "inside"; l = LIST1 global -> SearchInside l
+ | IDENT "outside"; l = LIST1 global -> SearchOutside l
+ | -> SearchOutside [] ] ]
+ ;
+ comment:
+ [ [ c = constr -> CommentConstr c
+ | s = STRING -> CommentString s
+ | n = natural -> CommentInt n ] ]
+ ;
+END;
+
+GEXTEND Gram
+ command:
+ [ [
+(* State management *)
+ IDENT "Write"; IDENT "State"; s = IDENT -> VernacWriteState s
+ | IDENT "Write"; IDENT "State"; s = STRING -> VernacWriteState s
+ | IDENT "Restore"; IDENT "State"; s = IDENT -> VernacRestoreState s
+ | IDENT "Restore"; IDENT "State"; s = STRING -> VernacRestoreState s
+
+(* Resetting *)
+ | IDENT "Reset"; id = identref -> VernacResetName id
+ | IDENT "Reset"; IDENT "Initial" -> VernacResetInitial
+ | IDENT "Back" -> VernacBack 1
+ | IDENT "Back"; n = natural -> VernacBack n
+
+(* Tactic Debugger *)
+ | IDENT "Debug"; IDENT "On" -> VernacDebug true
+ | IDENT "Debug"; IDENT "Off" -> VernacDebug false
+
+ ] ];
+ END
+;;
+
+(* Grammar extensions *)
+
+GEXTEND Gram
+ GLOBAL: syntax;
+
+ syntax:
+ [ [ IDENT "Open"; IDENT "Scope"; sc = IDENT -> VernacOpenScope sc
+
+ | IDENT "Delimits"; IDENT "Scope"; sc = IDENT; "with"; key = IDENT ->
+ VernacDelimiters (sc,key)
+
+ | IDENT "Arguments"; IDENT "Scope"; qid = global;
+ "["; scl = LIST0 opt_scope; "]" -> VernacArgumentsScope (qid,scl)
+
+ | IDENT "Infix"; a = entry_prec; n = OPT natural; op = STRING;
+ p = global;
+ modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
+ sc = OPT [ ":"; sc = IDENT -> sc ] ->
+ let (a,n,b) = Metasyntax.interp_infix_modifiers a n modl in
+ VernacInfix (a,n,op,p,b,None,sc)
+ | IDENT "Notation"; s = IDENT; ":="; c = constr ->
+ VernacNotation ("'"^s^"'",c,[],None,None)
+ | IDENT "Notation"; s = STRING; ":="; c = constr;
+ modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
+ sc = OPT [ ":"; sc = IDENT -> sc ] ->
+ VernacNotation (s,c,modl,None,sc)
+
+ | IDENT "Grammar"; IDENT "tactic"; IDENT "simple_tactic";
+ OPT [ ":"; IDENT "tactic" ]; ":=";
+ OPT "|"; tl = LIST0 grammar_tactic_rule SEP "|" ->
+ VernacTacticGrammar tl
+
+ | IDENT "Grammar"; u = univ;
+ tl = LIST1 grammar_entry SEP "with" ->
+ VernacGrammar (rename_command_entry u,tl)
+
+ | IDENT "Syntax"; u = univ; el = LIST1 syntax_entry SEP "," ->
+ VernacSyntax (u,el)
+
+ | IDENT "Uninterpreted"; IDENT "Notation"; s = STRING;
+ l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]
+ -> VernacSyntaxExtension (s,l)
+
+ (* "Print" "Grammar" should be here but is in "command" entry in order
+ to factorize with other "Print"-based vernac entries *)
+ ] ]
+ ;
+ univ:
+ [ [ univ = IDENT ->
+ set_default_action_parser (parser_type_from_name univ); univ ] ]
+ ;
+ syntax_modifier:
+ [ [ x = IDENT; IDENT "at"; IDENT "level"; n = natural ->
+ SetItemLevel ([x],n)
+ | x = IDENT; ","; l = LIST1 IDENT SEP ","; IDENT "at"; IDENT "level";
+ n = natural -> SetItemLevel (x::l,n)
+ | IDENT "at"; IDENT "level"; n = natural -> SetLevel n
+ | IDENT "left"; IDENT "associativity" -> SetAssoc Gramext.LeftA
+ | IDENT "right"; IDENT "associativity" -> SetAssoc Gramext.RightA
+ | IDENT "no"; IDENT "associativity" -> SetAssoc Gramext.NonA
+ | x = IDENT; typ = syntax_extension_type -> SetEntryType (x,typ)
+ | IDENT "only"; IDENT "parsing" -> SetOnlyParsing ] ]
+ ;
+ syntax_extension_type:
+ [ [ IDENT "ident" -> ETIdent | IDENT "global" -> ETReference
+ | IDENT "bigint" -> ETBigint
+ | e=IDENT -> ETOther("constr",e)
+ ] ]
+ ;
+ opt_scope:
+ [ [ IDENT "_" -> None | sc = IDENT -> Some sc ] ]
+ ;
+ (* Syntax entries for Grammar. Only grammar_entry is exported *)
+ grammar_entry:
+ [[ nont = IDENT; set_entry_type; ":=";
+ ep = entry_prec; OPT "|"; rl = LIST0 grammar_rule SEP "|" ->
+ (rename_command_entry nont,ep,rl) ]]
+ ;
+ entry_prec:
+ [[ IDENT "LEFTA" -> Some Gramext.LeftA
+ | IDENT "RIGHTA" -> Some Gramext.RightA
+ | IDENT "NONA" -> Some Gramext.NonA
+ | -> None ]]
+ ;
+ grammar_tactic_rule:
+ [[ name = rule_name; "["; s = STRING; pil = LIST0 production_item; "]";
+ "->"; "["; t = Tactic.tactic; "]" -> (name, (s,pil), t) ]]
+ ;
+ grammar_rule:
+ [[ name = rule_name; "["; pil = LIST0 production_item; "]"; "->";
+ a = action -> (name, pil, a) ]]
+ ;
+ rule_name:
+ [[ name = IDENT -> name ]]
+ ;
+ production_item:
+ [[ s = STRING -> VTerm s
+ | nt = non_terminal; po = OPT [ "("; p = METAIDENT; ")" -> p ] ->
+ match po with
+ | Some p -> VNonTerm (loc,nt,Some (Names.id_of_string p))
+ | _ -> VNonTerm (loc,nt,None) ]]
+ ;
+ non_terminal:
+ [[ u = IDENT; ":"; nt = IDENT ->
+ NtQual(rename_command_entry u, rename_command_entry nt)
+ | nt = IDENT -> NtShort (rename_command_entry nt) ]]
+ ;
+
+
+ (* Syntax entries for Syntax. Only syntax_entry is exported *)
+ syntax_entry:
+ [ [ IDENT "level"; p = precedence; ":";
+ OPT "|"; rl = LIST1 syntax_rule SEP "|" -> (p,rl) ] ]
+ ;
+ syntax_rule:
+ [ [ nm = IDENT; "["; s = astpat; "]"; "->"; u = unparsing -> (nm,s,u) ] ]
+ ;
+ precedence:
+ [ [ a = natural -> a
+(* | "["; a1 = natural; a2 = natural; a3 = natural; "]" -> (a1,a2,a3)*)
+ ] ]
+ ;
+ unparsing:
+ [ [ "["; ll = LIST0 next_hunks; "]" -> ll ] ]
+ ;
+ next_hunks:
+ [ [ IDENT "FNL" -> UNP_FNL
+ | IDENT "TAB" -> UNP_TAB
+ | c = STRING -> RO c
+ | "[";
+ x =
+ [ b = box; ll = LIST0 next_hunks -> UNP_BOX (b,ll)
+ | n = natural; m = natural -> UNP_BRK (n, m)
+ | IDENT "TBRK"; n = natural; m = natural -> UNP_TBRK (n, m) ];
+ "]" -> x
+ | e = Prim.ast; oprec = OPT [ ":"; pr = paren_reln_or_extern -> pr ] ->
+ match oprec with
+ | Some (ext,pr) -> PH (e,ext,pr)
+ | None -> PH (e,None,Any)
+ ]]
+ ;
+ box:
+ [ [ "<"; bk = box_kind; ">" -> bk ] ]
+ ;
+ box_kind:
+ [ [ IDENT "h"; n = natural -> PpHB n
+ | IDENT "v"; n = natural -> PpVB n
+ | IDENT "hv"; n = natural -> PpHVB n
+ | IDENT "hov"; n = natural -> PpHOVB n
+ | IDENT "t" -> PpTB ] ]
+ ;
+ paren_reln_or_extern:
+ [ [ IDENT "L" -> None, L
+ | IDENT "E" -> None, E
+ | pprim = STRING; precrec = OPT [ ":"; p = precedence -> p ] ->
+ match precrec with
+ | Some p -> Some pprim, Prec p
+ | None -> Some pprim, Any ] ]
+ ;
+ (* meta-syntax entries *)
+ astpat:
+ [ [ "<<" ; a = Prim.ast; ">>" -> a
+ | a = Constr.lconstr ->
+ Termast.ast_of_rawconstr
+ (Constrintern.interp_rawconstr Evd.empty (Global.env()) a)
+ ] ]
+ ;
+ action:
+ [ [ IDENT "let"; p = Prim.astlist; et = set_internal_entry_type;
+ "="; e1 = action; "in"; e = action -> Ast.CaseAction (loc,e1,et,[p,e])
+ | IDENT "case"; a = action; et = set_internal_entry_type; "of";
+ cl = LIST1 case SEP "|"; IDENT "esac" -> Ast.CaseAction (loc,a,et,cl)
+ | "["; a = default_action_parser; "]" -> Ast.SimpleAction (loc,a) ] ]
+ ;
+ case:
+ [[ p = Prim.astlist; "->"; a = action -> (p,a) ]]
+ ;
+ set_internal_entry_type:
+ [[ ":"; IDENT "ast"; IDENT "list" -> Ast.ETastl
+ | [ ":"; IDENT "ast" -> () | -> () ] -> Ast.ETast ]]
+ ;
+ set_entry_type:
+ [[ ":"; et = entry_type -> set_default_action_parser et
+ | -> () ]]
+ ;
+ entry_type:
+ [[ IDENT "ast"; IDENT "list" -> Util.error "type ast list no longer supported"
+ | IDENT "ast" -> Util.error "type ast no longer supported"
+ | IDENT "constr" -> ConstrParser
+ | IDENT "pattern" -> CasesPatternParser
+ | IDENT "tactic" -> assert false
+ | IDENT "vernac" -> Util.error "vernac extensions no longer supported" ] ]
+ ;
+END
+
+(* Reinstall tactic and vernac extensions *)
+let _ = Egrammar.reset_extend_grammars_v8()
diff --git a/parsing/g_zsyntax.ml b/parsing/g_zsyntax.ml
index 5103aedb0..11c88d113 100644
--- a/parsing/g_zsyntax.ml
+++ b/parsing/g_zsyntax.ml
@@ -54,11 +54,15 @@ let z_of_string pos_or_neg s dloc =
aZERO
(* Declare the primitive parser with Grammar and without the scope mechanism *)
-open Pcoq
+let zsyntax_create name =
+ let e =
+ Pcoq.create_constr_entry (Pcoq.get_univ "znatural") name in
+ Pcoq.Gram.Unsafe.clear_entry e;
+ e
-let number = create_constr_entry (get_univ "znatural") "number"
+let number = zsyntax_create "number"
-let negnumber = create_constr_entry (get_univ "znatural") "negnumber"
+let negnumber = zsyntax_create "negnumber"
let _ =
Gram.extend number None
diff --git a/parsing/g_zsyntaxnew.ml b/parsing/g_zsyntaxnew.ml
new file mode 100644
index 000000000..24b6d4137
--- /dev/null
+++ b/parsing/g_zsyntaxnew.ml
@@ -0,0 +1,168 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Coqast
+open Pcoq
+open Pp
+open Util
+open Names
+open Ast
+open Extend
+open Topconstr
+open Libnames
+open Bignat
+
+(**********************************************************************)
+(* Parsing positive via scopes *)
+(**********************************************************************)
+
+open Libnames
+open Rawterm
+let make_dir l = make_dirpath (List.map id_of_string (List.rev l))
+let fast_integer_module = make_dir ["Coq";"ZArith";"fast_integer"]
+
+(* TODO: temporary hack *)
+let make_path dir id = Libnames.encode_kn dir id
+
+let positive_path = make_path fast_integer_module (id_of_string "positive")
+let path_of_xI = ((positive_path,0),1)
+let path_of_xO = ((positive_path,0),2)
+let path_of_xH = ((positive_path,0),3)
+let glob_xI = ConstructRef path_of_xI
+let glob_xO = ConstructRef path_of_xO
+let glob_xH = ConstructRef path_of_xH
+
+let pos_of_bignat dloc x =
+ let ref_xI = RRef (dloc, glob_xI) in
+ let ref_xH = RRef (dloc, glob_xH) in
+ let ref_xO = RRef (dloc, glob_xO) in
+ let rec pos_of x =
+ match div2_with_rest x with
+ | (q,false) -> RApp (dloc, ref_xO,[pos_of q])
+ | (q,true) when is_nonzero q -> RApp (dloc,ref_xI,[pos_of q])
+ | (q,true) -> ref_xH
+ in
+ pos_of x
+
+let interp_positive dloc = function
+ | POS n when is_nonzero n -> pos_of_bignat dloc n
+ | _ ->
+ user_err_loc (dloc, "interp_positive",
+ str "Only strictly positive numbers in type \"positive\"!")
+
+let rec pat_pos_of_bignat dloc x name =
+ match div2_with_rest x with
+ | (q,false) ->
+ PatCstr (dloc,path_of_xO,[pat_pos_of_bignat dloc q Anonymous],name)
+ | (q,true) when is_nonzero q ->
+ PatCstr (dloc,path_of_xI,[pat_pos_of_bignat dloc q Anonymous],name)
+ | (q,true) ->
+ PatCstr (dloc,path_of_xH,[],name)
+
+let pat_interp_positive dloc = function
+ | POS n -> pat_pos_of_bignat dloc n
+ | NEG n ->
+ user_err_loc (dloc, "interp_positive",
+ str "No negative number in type \"positive\"!")
+
+(**********************************************************************)
+(* Printing positive via scopes *)
+(**********************************************************************)
+
+exception Non_closed_number
+
+let rec bignat_of_pos = function
+ | RApp (_, RRef (_,b),[a]) when b = glob_xO -> mult_2(bignat_of_pos a)
+ | RApp (_, RRef (_,b),[a]) when b = glob_xI -> add_1(mult_2(bignat_of_pos a))
+ | RRef (_, a) when a = glob_xH -> Bignat.one
+ | _ -> raise Non_closed_number
+
+let uninterp_positive p =
+ try
+ Some (POS (bignat_of_pos p))
+ with Non_closed_number ->
+ None
+
+(***********************************************************************)
+(* Declaring interpreters and uninterpreters for positive *)
+(***********************************************************************)
+
+let _ = Symbols.declare_numeral_interpreter "positive_scope"
+ ["Coq";"ZArith";"Zsyntax"]
+ (interp_positive,Some pat_interp_positive)
+ ([RRef (dummy_loc, glob_xI);
+ RRef (dummy_loc, glob_xO);
+ RRef (dummy_loc, glob_xH)],
+ uninterp_positive,
+ None)
+
+(**********************************************************************)
+(* Parsing Z via scopes *)
+(**********************************************************************)
+
+let z_path = make_path fast_integer_module (id_of_string "Z")
+let glob_z = IndRef (z_path,0)
+let path_of_ZERO = ((z_path,0),1)
+let path_of_POS = ((z_path,0),2)
+let path_of_NEG = ((z_path,0),3)
+let glob_ZERO = ConstructRef path_of_ZERO
+let glob_POS = ConstructRef path_of_POS
+let glob_NEG = ConstructRef path_of_NEG
+
+let z_of_posint dloc pos_or_neg n =
+ if is_nonzero n then
+ let sgn = if pos_or_neg then glob_POS else glob_NEG in
+ RApp(dloc, RRef (dloc,sgn), [pos_of_bignat dloc n])
+ else
+ RRef (dloc, glob_ZERO)
+
+let z_of_int dloc z =
+ match z with
+ | POS n -> z_of_posint dloc true n
+ | NEG n -> z_of_posint dloc false n
+
+let pat_z_of_posint dloc pos_or_neg n name =
+ if is_nonzero n then
+ let sgn = if pos_or_neg then path_of_POS else path_of_NEG in
+ PatCstr (dloc, sgn, [pat_pos_of_bignat dloc n Anonymous], name)
+ else
+ PatCstr (dloc, path_of_ZERO, [], name)
+
+let pat_z_of_int dloc n name =
+ match n with
+ | POS n -> pat_z_of_posint dloc true n name
+ | NEG n -> pat_z_of_posint dloc false n name
+
+(**********************************************************************)
+(* Printing Z via scopes *)
+(**********************************************************************)
+
+let bigint_of_z = function
+ | RApp (_, RRef (_,b),[a]) when b = glob_POS -> POS (bignat_of_pos a)
+ | RApp (_, RRef (_,b),[a]) when b = glob_NEG -> NEG (bignat_of_pos a)
+ | RRef (_, a) when a = glob_ZERO -> POS (Bignat.zero)
+ | _ -> raise Non_closed_number
+
+let uninterp_z p =
+ try
+ Some (bigint_of_z p)
+ with Non_closed_number -> None
+
+(***********************************************************************)
+(* Declaring interpreters and uninterpreters for Z *)
+
+let _ = Symbols.declare_numeral_interpreter "Z_scope"
+ ["Coq";"ZArith";"Zsyntax"]
+ (z_of_int,Some pat_z_of_int)
+ ([RRef (dummy_loc, glob_ZERO);
+ RRef (dummy_loc, glob_POS);
+ RRef (dummy_loc, glob_NEG)],
+ uninterp_z,
+ None)
diff --git a/parsing/g_zsyntaxnew.mli b/parsing/g_zsyntaxnew.mli
new file mode 100644
index 000000000..a8370f630
--- /dev/null
+++ b/parsing/g_zsyntaxnew.mli
@@ -0,0 +1,11 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+(* Nice syntax for integers. *)
diff --git a/parsing/lexer.ml4 b/parsing/lexer.ml4
index ff54f74ef..54d0c42c0 100644
--- a/parsing/lexer.ml4
+++ b/parsing/lexer.ml4
@@ -151,22 +151,7 @@ let unfreeze (kw,tt) =
token_tree := tt
let init () =
- unfreeze (empty_ttree, empty_ttree);
- List.iter add_keyword
- [ "Grammar"; "Syntax"; "Quit"; "Load"; "Compile";
- "of"; "with"; "end"; "as"; "in"; "using";
- "Cases"; "Fixpoint"; "CoFixpoint";
- "Definition"; "Inductive"; "CoInductive";
- "Theorem"; "Variable"; "Axiom"; "Parameter"; "Hypothesis";
- "Orelse"; "Proof"; "Qed";
- "Prop"; "Set"; "Type"; "And"
- ]; (* "let" is not a keyword because #Core#let.cci would not parse *)
- List.iter add_special_token
- [ ":"; "("; ")"; "["; "]"; "{"; "}"; "_"; ";"; "`"; "``";
- "()"; "->"; "\\/"; "/\\"; "|-"; ":="; "<->"; "!"; "$"; "%"; "&";
- "*"; "+"; ","; "@"; "^"; "#"; "\\"; "/"; "-"; "<"; ">";
- "|"; "?"; "="; "~"; "'"; "<<"; ">>"; "<>"; "::";
- "<:"; ":<"; "=>"; ">->" ]
+ unfreeze (empty_ttree, empty_ttree)
let _ = init()
@@ -318,20 +303,11 @@ let parse_226_tail tk = parser
| [< len = ident (store 0 '\226') >] ->
TokIdent (get_buff len)
-(* Parse a token in a char stream *)
-let rec next_token = parser bp
- | [< ''\n'; s >] -> (match !current with
- | BeVernac s -> current := InComment s
- | InComment _ -> add_comment_pp (fnl ())
- | _ -> ()); next_token s
- | [< '' ' | '\t'; s >] -> (match !current with
- | BeVernac _ | InComment _ -> add_comment_pp (spc ())
- | _ -> ()); next_token s
- | [< ''\r'; s >] -> next_token s
- | [< ''$'; len = ident (store 0 '$') >] ep ->
- (("METAIDENT", get_buff len), (bp,ep))
- | [< ''.' as c; t = parser
+(* Parse what foolows a dot *)
+let parse_after_dot bp c strm =
+ if !Options.v7 then
+ match strm with parser
| [< ' ('_' | 'a'..'z' | 'A'..'Z' as c); len = ident (store 0 c) >] ->
("FIELD", get_buff len)
(* Greek utf-8 letters [CE80-CEBF and CF80-CFBF] (CE=206; BF=191) *)
@@ -349,10 +325,26 @@ let rec next_token = parser bp
| [< ' ('\192'..'\214' | '\216'..'\246' | '\248'..'\255' as c);
len = ident (store 0 c) >] ->
("FIELD", get_buff len)
-(*
- | [< >] -> ("", ".") >] ep -> (t, (bp,ep))
-*)
- | [< (t,_) = process_chars bp c >] -> t >] ep ->
+ | [< (t,_) = process_chars bp c >] -> t
+ else
+ match strm with parser
+ | [< (t,_) = process_chars bp c >] -> t
+
+
+(* Parse a token in a char stream *)
+
+let rec next_token = parser bp
+ | [< ''\n'; s >] -> (match !current with
+ | BeVernac s -> current := InComment s
+ | InComment _ -> add_comment_pp (fnl ())
+ | _ -> ()); next_token s
+ | [< '' ' | '\t'; s >] -> (match !current with
+ | BeVernac _ | InComment _ -> add_comment_pp (spc ())
+ | _ -> ()); next_token s
+ | [< ''\r'; s >] -> next_token s
+ | [< ''$'; len = ident (store 0 '$') >] ep ->
+ (("METAIDENT", get_buff len), (bp,ep))
+ | [< ''.' as c; t = parse_after_dot bp c >] ep ->
current:=BeVernac ""; (t, (bp,ep))
| [< ' ('_' | 'a'..'z' | 'A'..'Z' as c); len = ident (store 0 c) >] ep ->
let id = get_buff len in current:=InVernac;
diff --git a/parsing/pcoq.ml4 b/parsing/pcoq.ml4
index 33948d83b..6cff40c34 100644
--- a/parsing/pcoq.ml4
+++ b/parsing/pcoq.ml4
@@ -344,7 +344,7 @@ module Constr =
(* Entries that can be refered via the string -> Gram.Entry.e table *)
let constr = gec_constr "constr"
- let constr9 = gec_constr "constr9"
+ let operconstr = gec_constr "operconstr"
let constr_eoi = eoi_entry constr
let lconstr = gec_constr "lconstr"
let ident = make_gen_entry uconstr rawwit_ident "ident"
@@ -398,14 +398,36 @@ module Vernac_ =
let syntax = gec_vernac "syntax_command"
let vernac = gec_vernac "Vernac_.vernac"
- (* Various vernacular entries needed to be exported *)
- let thm_token = Gram.Entry.create "vernac:thm_token"
- let class_rawexpr = Gram.Entry.create "vernac:class_rawexpr"
-
let vernac_eoi = eoi_entry vernac
end
+(* Prim is not re-initialized *)
+let reset_all_grammars () =
+ let f = Gram.Unsafe.clear_entry in
+ List.iter f
+ [Constr.constr;Constr.operconstr;Constr.lconstr;Constr.annot;
+ Constr.constr_pattern];
+ f Constr.ident; f Constr.global; f Constr.sort; f Constr.pattern;
+ f Module.module_expr; f Module.module_type;
+ f Tactic.simple_tactic;
+ f Tactic.castedopenconstr;
+ f Tactic.constr_with_bindings;
+ f Tactic.constrarg;
+ f Tactic.quantified_hypothesis;
+ f Tactic.int_or_var;
+ f Tactic.red_expr;
+ f Tactic.tactic_arg;
+ f Tactic.tactic;
+ f Vernac_.gallina;
+ f Vernac_.gallina_ext;
+ f Vernac_.command;
+ f Vernac_.syntax;
+ f Vernac_.vernac;
+ Lexer.init()
+
+
+
let main_entry = Gram.Entry.create "vernac"
GEXTEND Gram
@@ -425,8 +447,6 @@ open Vernac_
let globalizer = ref (fun x -> failwith "No globalizer")
let set_globalizer f = globalizer := f
-let f = (ast : Coqast.t G.Entry.e)
-
let define_ast_quotation default s (e:Coqast.t G.Entry.e) =
(if default then
GEXTEND Gram
@@ -462,7 +482,7 @@ GEXTEND Gram
dynconstr:
[ [ a = Constr.constr -> ConstrNode a
(* For compatibility *)
- | "<<"; a = Constr.constr; ">>" -> ConstrNode a ] ]
+ | "<<"; a = Constr.lconstr; ">>" -> ConstrNode a ] ]
;
dyncasespattern: [ [ a = Constr.pattern -> CasesPatternNode a ] ];
END
@@ -527,9 +547,7 @@ let adjust_level assoc from = function
| _ -> Some (Some n)
let compute_entry allow_create adjust = function
- | ETConstr (10,_) -> weaken_entry Constr.lconstr, None, true
- | ETConstr (9,_) -> weaken_entry Constr.constr9, None, true
- | ETConstr (n,q) -> weaken_entry Constr.constr, adjust (n,q), false
+ | ETConstr (n,q) -> weaken_entry Constr.operconstr, adjust (n,q), false
| ETIdent -> weaken_entry Constr.ident, None, false
| ETBigint -> weaken_entry Prim.bigint, None, false
| ETReference -> weaken_entry Constr.global, None, false
@@ -543,19 +561,50 @@ let compute_entry allow_create adjust = function
with e when allow_create -> create_entry u n ConstrArgType in
object_of_typed_entry e, None, true
-let get_constr_entry = compute_entry true (fun (n,()) -> Some n)
-
-let get_constr_production_entry ass from =
- compute_entry false (adjust_level ass from)
+let get_constr_entry en =
+ match en with
+ ETConstr(200,_) when not !Options.v7 ->
+ snd (get_entry (get_univ "constr") "binder_constr"),
+ None,
+ false
+ | _ -> compute_entry true (fun (n,()) -> Some n) en
+
+let get_constr_production_entry ass from en =
+ (* first 2 cases to help factorisation *)
+ match en with
+ | ETConstr (10,q) when !Options.v7 ->
+ weaken_entry Constr.lconstr, None, false
+ | ETConstr (8,q) when !Options.v7 ->
+ weaken_entry Constr.constr, None, false
+ | _ -> compute_entry false (adjust_level ass from) en
let constr_prod_level = function
- | 8 -> "top"
- | 4 -> "4L"
+ | 4 when !Options.v7 -> "4L"
| n -> string_of_int n
+let is_self from e =
+ match from, e with
+ ETConstr(n,_), ETConstr(n',
+ BorderProd(false,Some(Gramext.NonA|Gramext.LeftA))) -> false
+ | ETConstr(n,_), ETConstr(n',_) -> n=n'
+ | (ETIdent,ETIdent | ETReference, ETReference | ETBigint,ETBigint
+ | ETPattern, ETPattern) -> true
+ | ETOther(s1,s2), ETOther(s1',s2') -> s1=s1' & s2=s2'
+ | _ -> false
+
+let is_binder_level from e =
+ match from, e with
+ ETConstr(200,_), ETConstr(200,_) -> not !Options.v7
+ | _ -> false
+
let symbol_of_production assoc from typ =
- match get_constr_production_entry assoc from typ with
- | (eobj,None,_) -> Gramext.Snterm (Gram.Entry.obj eobj)
- | (eobj,Some None,_) -> Gramext.Snext
- | (eobj,Some (Some lev),_) ->
- Gramext.Snterml (Gram.Entry.obj eobj,constr_prod_level lev)
+ if is_binder_level from typ then
+ let eobj = snd (get_entry (get_univ "constr") "operconstr") in
+ Gramext.Snterml (Gram.Entry.obj eobj,"200")
+ else if is_self from typ then Gramext.Sself
+ else
+ match get_constr_production_entry assoc from typ with
+ | (eobj,None,_) -> Gramext.Snterm (Gram.Entry.obj eobj)
+ | (eobj,Some None,_) -> Gramext.Snext
+ | (eobj,Some (Some lev),_) ->
+ Gramext.Snterml (Gram.Entry.obj eobj,constr_prod_level lev)
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index b15046c29..325d4f494 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -129,9 +129,9 @@ module Prim :
module Constr :
sig
val constr : constr_expr Gram.Entry.e
- val constr9 : constr_expr Gram.Entry.e
val constr_eoi : constr_expr Gram.Entry.e
val lconstr : constr_expr Gram.Entry.e
+ val operconstr : constr_expr Gram.Entry.e
val ident : identifier Gram.Entry.e
val global : reference Gram.Entry.e
val sort : rawsort Gram.Entry.e
@@ -164,8 +164,6 @@ module Tactic :
module Vernac_ :
sig
open Decl_kinds
- val thm_token : theorem_kind Gram.Entry.e
- val class_rawexpr : class_rawexpr Gram.Entry.e
val gallina : vernac_expr Gram.Entry.e
val gallina_ext : vernac_expr Gram.Entry.e
val command : vernac_expr Gram.Entry.e
@@ -173,3 +171,5 @@ module Vernac_ :
val vernac : vernac_expr Gram.Entry.e
val vernac_eoi : vernac_expr Gram.Entry.e
end
+
+val reset_all_grammars : unit -> unit
diff --git a/parsing/ppconstr.ml b/parsing/ppconstr.ml
index 57e813632..97c7d637b 100644
--- a/parsing/ppconstr.ml
+++ b/parsing/ppconstr.ml
@@ -22,55 +22,6 @@ open Topconstr
open Term
(*i*)
-let dfltpr ast = (str"#GENTERM " ++ print_ast ast);;
-
-let pr_global ref = pr_global_env None ref
-
-let global_const_name kn =
- try pr_global (ConstRef kn)
- with Not_found -> (* May happen in debug *)
- (str ("CONST("^(string_of_kn kn)^")"))
-
-let global_var_name id =
- try pr_global (VarRef id)
- with Not_found -> (* May happen in debug *)
- (str ("SECVAR("^(string_of_id id)^")"))
-
-let global_ind_name (kn,tyi) =
- try pr_global (IndRef (kn,tyi))
- with Not_found -> (* May happen in debug *)
- (str ("IND("^(string_of_kn kn)^","^(string_of_int tyi)^")"))
-
-let global_constr_name ((kn,tyi),i) =
- try pr_global (ConstructRef ((kn,tyi),i))
- with Not_found -> (* May happen in debug *)
- (str ("CONSTRUCT("^(string_of_kn kn)^","^(string_of_int tyi)
- ^","^(string_of_int i)^")"))
-
-let globpr gt = match gt with
- | Nvar(_,s) -> (pr_id s)
- | Node(_,"EVAR", [Num (_,ev)]) -> (str ("?" ^ (string_of_int ev)))
- | Node(_,"CONST",[Path(_,sl)]) ->
- global_const_name (section_path sl)
- | Node(_,"SECVAR",[Nvar(_,s)]) ->
- global_var_name s
- | Node(_,"MUTIND",[Path(_,sl); Num(_,tyi)]) ->
- global_ind_name (section_path sl, tyi)
- | Node(_,"MUTCONSTRUCT",[Path(_,sl); Num(_,tyi); Num(_,i)]) ->
- global_constr_name ((section_path sl, tyi), i)
- | Dynamic(_,d) ->
- if (Dyn.tag d) = "constr" then (str"<dynamic [constr]>")
- else dfltpr gt
- | gt -> dfltpr gt
-
-let wrap_exception = function
- Anomaly (s1,s2) ->
- warning ("Anomaly ("^s1^")"); pp s2;
- str"<PP error: non-printable term>"
- | Failure _ | UserError _ | Not_found ->
- str"<PP error: non-printable term>"
- | s -> raise s
-
let latom = 0
let lannot = 1
let lprod = 8 (* not 1 because the scope extends to 8 on the right *)
@@ -157,6 +108,8 @@ let pr_binder pr (nal,t) =
let pr_binders pr bl =
hv 0 (prlist_with_sep pr_semicolon (pr_binder pr) bl)
+let pr_global vars ref = pr_global_env vars ref
+
let rec pr_lambda_tail pr bll = function
| CLambdaN (_,bl,a) ->
pr_lambda_tail pr (bll ++ pr_semicolon() ++ pr_binders pr bl) a
@@ -230,21 +183,22 @@ let pr_annotation pr = function
| None -> mt ()
| Some t -> str "<" ++ pr ltop t ++ str ">" ++ brk (0,2)
-let rec pr_pat = function
- | CPatAlias (_,p,x) -> pr_pat p ++ spc () ++ str "as" ++ spc () ++ pr_id x
+let rec pr_cases_pattern = function
+ | CPatAlias (_,p,x) ->
+ pr_cases_pattern p ++ spc () ++ str "as" ++ spc () ++ pr_id x
| CPatCstr (_,c,[]) -> pr_reference c
| CPatCstr (_,c,pl) ->
hov 0 (
str "(" ++ pr_reference c ++ spc () ++
- prlist_with_sep spc pr_pat pl ++ str ")")
+ prlist_with_sep spc pr_cases_pattern pl ++ str ")")
| CPatAtom (_,Some c) -> pr_reference c
| CPatAtom (_,None) -> str "_"
| CPatNumeral (_,n) -> Bignat.pr_bigint n
- | CPatDelimiters (_,key,p) -> pr_delimiters key (pr_pat p)
+ | CPatDelimiters (_,key,p) -> pr_delimiters key (pr_cases_pattern p)
let pr_eqn pr (_,patl,rhs) =
hov 0 (
- prlist_with_sep spc pr_pat patl ++ spc () ++
+ prlist_with_sep spc pr_cases_pattern patl ++ spc () ++
str "=>" ++
brk (1,1) ++ pr ltop rhs) ++ spc ()
@@ -394,26 +348,3 @@ let rec pr_may_eval pr = function
str "[" ++ pr c ++ str "]")
| ConstrTypeOf c -> hov 0 (str "Check " ++ brk (1,1) ++ pr c)
| ConstrTerm c -> pr c
-
-(**********************************************************************)
-let constr_syntax_universe = "constr"
-(* This is starting precedence for printing constructions or tactics *)
-(* Level 9 means no parentheses except for applicative terms (at level 10) *)
-let constr_initial_prec = Some (9,Ppextend.L)
-
-let gentermpr_fail gt =
- Esyntax.genprint globpr constr_syntax_universe constr_initial_prec gt
-
-let gentermpr gt =
- try gentermpr_fail gt
- with s -> wrap_exception s
-
-(* [at_top] means ids of env must be avoided in bound variables *)
-
-let gentermpr_core at_top env t =
- gentermpr (Termast.ast_of_constr at_top env t)
-(*
-let gentermpr_core at_top env t =
- pr_constr (Constrextern.extern_constr at_top env t)
-*)
-
diff --git a/parsing/ppconstr.mli b/parsing/ppconstr.mli
index 1a2848f00..6dd3d842c 100644
--- a/parsing/ppconstr.mli
+++ b/parsing/ppconstr.mli
@@ -23,10 +23,7 @@ open Util
val split_fix : int -> constr_expr -> constr_expr ->
(name located list * constr_expr) list * constr_expr * constr_expr
-val pr_global : global_reference -> std_ppcmds
-
-val gentermpr : Coqast.t -> std_ppcmds
-val gentermpr_core : bool -> env -> constr -> std_ppcmds
+val pr_global : Idset.t -> global_reference -> std_ppcmds
val pr_opt : ('a -> std_ppcmds) -> 'a option -> std_ppcmds
val pr_name : name -> std_ppcmds
@@ -39,4 +36,5 @@ val pr_occurrences : ('a -> std_ppcmds) -> 'a occurrences -> std_ppcmds
val pr_sort : rawsort -> std_ppcmds
val pr_pattern : Tacexpr.pattern_expr -> std_ppcmds
val pr_constr : constr_expr -> std_ppcmds
+val pr_cases_pattern : cases_pattern_expr -> std_ppcmds
val pr_may_eval : ('a -> std_ppcmds) -> 'a may_eval -> std_ppcmds
diff --git a/parsing/pptactic.ml b/parsing/pptactic.ml
index 2f18076b7..fbeb697eb 100644
--- a/parsing/pptactic.ml
+++ b/parsing/pptactic.ml
@@ -13,22 +13,32 @@ open Names
open Nameops
open Util
open Extend
-open Ppconstr
open Tacexpr
open Rawterm
open Topconstr
open Genarg
open Libnames
+let pr_red_expr = Ppconstr.pr_red_expr
+let pr_may_eval = Ppconstr.pr_may_eval
+let pr_sort = Ppconstr.pr_sort
+let pr_global = Ppconstr.pr_global Idset.empty
+let pr_name = Ppconstr.pr_name
+let pr_opt = Ppconstr.pr_opt
+let pr_occurrences = Ppconstr.pr_occurrences
+
(* Extensions *)
+let prtac_tab_v7 = Hashtbl.create 17
let prtac_tab = Hashtbl.create 17
-let declare_extra_tactic_pprule s f g =
- Hashtbl.add prtac_tab s (f,g)
+let declare_extra_tactic_pprule for_v8 s f g =
+ Hashtbl.add prtac_tab_v7 s (f,g);
+ if for_v8 then Hashtbl.add prtac_tab s (f,g)
+let genarg_pprule_v7 = ref Stringmap.empty
let genarg_pprule = ref Stringmap.empty
-let declare_extra_genarg_pprule (rawwit, f) (wit, g) =
+let declare_extra_genarg_pprule for_v8 (rawwit, f) (wit, g) =
let s = match unquote wit with
| ExtraArgType s -> s
| _ -> error
@@ -36,7 +46,9 @@ let declare_extra_genarg_pprule (rawwit, f) (wit, g) =
in
let f x = f (out_gen rawwit x) in
let g x = g (out_gen wit x) in
- genarg_pprule := Stringmap.add s (f,g) !genarg_pprule
+ genarg_pprule_v7 := Stringmap.add s (f,g) !genarg_pprule_v7;
+ if for_v8 then
+ genarg_pprule := Stringmap.add s (f,g) !genarg_pprule
(* [pr_rawtac] is here to cheat with ML typing system,
gen_tactic_expr is polymorphic but with some occurrences of its
@@ -66,8 +78,6 @@ let pr_or_meta pr = function
| AI x -> pr x
| _ -> failwith "pr_hyp_location: unexpected quotation meta-variable"
-let pr_casted_open_constr = pr_constr
-
let pr_quantified_hypothesis = function
| AnonHyp n -> int n
| NamedHyp id -> pr_id id
@@ -133,9 +143,9 @@ let pr_induction_arg prc = function
| ElimOnAnonHyp n -> int n
let pr_match_pattern = function
- | Term a -> pr_pattern a
- | Subterm (None,a) -> str "[" ++ pr_pattern a ++ str "]"
- | Subterm (Some id,a) -> pr_id id ++ str "[" ++ pr_pattern a ++ str "]"
+ | Term a -> Ppconstr.pr_pattern a
+ | Subterm (None,a) -> str "[" ++ Ppconstr.pr_pattern a ++ str "]"
+ | Subterm (Some id,a) -> pr_id id ++ str "[" ++ Ppconstr.pr_pattern a ++ str "]"
let pr_match_hyps = function
| NoHypId mp -> str "_:" ++ pr_match_pattern mp
@@ -146,7 +156,8 @@ let pr_match_rule m pr = function
str "[" ++ pr_match_pattern mp ++ str "]"
++ spc () ++ str "->" ++ brk (1,2) ++ pr t
| Pat (rl,mp,t) ->
- str "[" ++ prlist_with_sep pr_semicolon pr_match_hyps rl ++ spc () ++
+ str "[" ++ prlist_with_sep pr_semicolon
+ pr_match_hyps rl ++ spc () ++
str "|-" ++ spc () ++ pr_match_pattern mp ++ spc () ++ str "]" ++
spc () ++ str "->" ++ brk (1,2) ++ pr t
| All t -> str "_" ++ spc () ++ str "->" ++ brk (1,2) ++ pr t
@@ -192,7 +203,16 @@ let pr_autoarg_usingTDB = function
| true -> spc () ++ str "Using TDB"
| false -> mt ()
-let rec pr_rawgen prtac x =
+let rec pr_tacarg_using_rule pr_gen = function
+ | Egrammar.TacTerm s :: l, al ->
+ spc () ++ str s ++ pr_tacarg_using_rule pr_gen (l,al)
+ | Egrammar.TacNonTerm _ :: l, a :: al ->
+ pr_gen a ++ pr_tacarg_using_rule pr_gen (l,al)
+ | [], [] -> mt ()
+ | _ -> failwith "Inconsistent arguments of extended tactic"
+
+
+let rec pr_rawgen prc prtac x =
match Genarg.genarg_tag x with
| BoolArgType -> pr_arg str (if out_gen rawwit_bool x then "true" else "false")
| IntArgType -> pr_arg int (out_gen rawwit_int x)
@@ -202,45 +222,44 @@ let rec pr_rawgen prtac x =
| IdentArgType -> pr_arg pr_id (out_gen rawwit_ident x)
| RefArgType -> pr_arg pr_reference (out_gen rawwit_ref x)
| SortArgType -> pr_arg pr_sort (out_gen rawwit_sort x)
- | ConstrArgType -> pr_arg pr_constr (out_gen rawwit_constr x)
+ | ConstrArgType -> pr_arg prc (out_gen rawwit_constr x)
| ConstrMayEvalArgType ->
- pr_arg (pr_may_eval pr_constr) (out_gen rawwit_constr_may_eval x)
+ pr_arg (pr_may_eval prc) (out_gen rawwit_constr_may_eval x)
| QuantHypArgType ->
pr_arg pr_quantified_hypothesis (out_gen rawwit_quant_hyp x)
| RedExprArgType ->
- pr_arg (pr_red_expr (pr_constr,pr_metanum pr_reference)) (out_gen rawwit_red_expr x)
+ pr_arg (pr_red_expr (prc,pr_metanum pr_reference)) (out_gen rawwit_red_expr x)
| TacticArgType -> pr_arg prtac (out_gen rawwit_tactic x)
| CastedOpenConstrArgType ->
- pr_arg pr_casted_open_constr (out_gen rawwit_casted_open_constr x)
+ pr_arg prc (out_gen rawwit_casted_open_constr x)
| ConstrWithBindingsArgType ->
- pr_arg (pr_with_bindings pr_constr)
+ pr_arg (pr_with_bindings prc)
(out_gen rawwit_constr_with_bindings x)
| List0ArgType _ ->
- hov 0 (fold_list0 (fun x a -> pr_rawgen prtac x ++ a) x (mt()))
+ hov 0 (fold_list0 (fun x a -> pr_rawgen prc prtac x ++ a) x (mt()))
| List1ArgType _ ->
- hov 0 (fold_list1 (fun x a -> pr_rawgen prtac x ++ a) x (mt()))
- | OptArgType _ -> hov 0 (fold_opt (pr_rawgen prtac) (mt()) x)
+ hov 0 (fold_list1 (fun x a -> pr_rawgen prc prtac x ++ a) x (mt()))
+ | OptArgType _ -> hov 0 (fold_opt (pr_rawgen prc prtac) (mt()) x)
| PairArgType _ ->
hov 0
(fold_pair
- (fun a b -> pr_rawgen prtac a ++ spc () ++ pr_rawgen prtac b)
+ (fun a b -> pr_rawgen prc prtac a ++ spc () ++ pr_rawgen prc
+ prtac b)
x)
| ExtraArgType s ->
- try fst (Stringmap.find s !genarg_pprule) x
+ let tab = if Options.do_translate() then !genarg_pprule
+ else !genarg_pprule_v7 in
+ try fst (Stringmap.find s tab) x
with Not_found -> str " [no printer for " ++ str s ++ str "] "
-let rec pr_raw_tacarg_using_rule pr_gen = function
- | Egrammar.TacTerm s :: l, al -> spc () ++ str s ++ pr_raw_tacarg_using_rule pr_gen (l,al)
- | Egrammar.TacNonTerm _ :: l, a :: al -> pr_gen a ++ pr_raw_tacarg_using_rule pr_gen (l,al)
- | [], [] -> mt ()
- | _ -> failwith "Inconsistent arguments of extended tactic"
-
-let pr_raw_extend prt s l =
+let pr_raw_extend prc prt s l =
+ let prg = pr_rawgen prc prt in
+ let tab = if Options.do_translate() then prtac_tab else prtac_tab_v7 in
try
- let (s,pl) = fst (Hashtbl.find prtac_tab s) l in
- str s ++ pr_raw_tacarg_using_rule (pr_rawgen prt) (pl,l)
+ let (s,pl) = fst (Hashtbl.find tab s) l in
+ str s ++ pr_tacarg_using_rule prg (pl,l)
with Not_found ->
- str "TODO(" ++ str s ++ prlist (pr_rawgen prt) l ++ str ")"
+ str "TODO(" ++ str s ++ prlist prg l ++ str ")"
open Closure
@@ -284,23 +303,21 @@ let rec pr_generic prtac x =
(fun a b -> pr_generic prtac a ++ spc () ++ pr_generic prtac b)
x)
| ExtraArgType s ->
- try snd (Stringmap.find s !genarg_pprule) x
+ let tab = if Options.do_translate() then !genarg_pprule
+ else !genarg_pprule_v7 in
+ try snd (Stringmap.find s tab) x
with Not_found -> str "[no printer for " ++ str s ++ str "]"
-let rec pr_tacarg_using_rule prt = function
- | Egrammar.TacTerm s :: l, al -> spc () ++ str s ++ pr_tacarg_using_rule prt (l,al)
- | Egrammar.TacNonTerm _ :: l, a :: al -> pr_generic prt a ++ pr_tacarg_using_rule prt (l,al)
- | [], [] -> mt ()
- | _ -> failwith "Inconsistent arguments of extended tactic"
-
let pr_extend prt s l =
+ let prg = pr_generic prt in
+ let tab = if Options.do_translate() then prtac_tab else prtac_tab_v7 in
try
- let (s,pl) = snd (Hashtbl.find prtac_tab s) l in
- str s ++ pr_tacarg_using_rule prt (pl,l)
+ let (s,pl) = snd (Hashtbl.find tab s) l in
+ str s ++ pr_tacarg_using_rule prg (pl,l)
with Not_found ->
- str s ++ prlist (pr_generic prt) l
+ str s ++ prlist prg l
-let make_pr_tac (pr_constr,pr_cst,pr_ind,pr_ident,pr_extend) =
+let make_pr_tac (pr_constr,pr_pattern,pr_cst,pr_ind,pr_ident,pr_extend) =
let pr_bindings = pr_bindings pr_constr in
let pr_with_bindings = pr_with_bindings pr_constr in
@@ -445,7 +462,7 @@ and pr_atom1 = function
(* Constructors *)
| TacLeft l -> hov 1 (str "Left" ++ pr_bindings l)
| TacRight l -> hov 1 (str "Right" ++ pr_bindings l)
- | TacSplit l -> hov 1 (str "Split" ++ pr_bindings l)
+ | TacSplit (_,l) -> hov 1 (str "Split" ++ pr_bindings l)
| TacAnyConstructor (Some t) ->
hov 1 (str "Constructor" ++ pr_arg !pr_rawtac0 t)
| TacAnyConstructor None as t -> pr_atom0 t
@@ -546,13 +563,15 @@ and pr6 = function
hov 0 (str "Match" ++ spc () ++ pr_may_eval Ppconstr.pr_constr t ++ spc()
++ str "With"
++ prlist
- (fun r -> fnl () ++ str "|" ++ spc () ++ pr_match_rule true prtac r)
+ (fun r -> fnl () ++ str "|" ++ spc () ++
+ pr_match_rule true prtac r)
lrul)
| TacMatchContext (lr,lrul) ->
hov 0 (
str (if lr then "Match Reverse Context With" else "Match Context With")
++ prlist
- (fun r -> fnl () ++ str "|" ++ spc () ++ pr_match_rule false prtac r)
+ (fun r -> fnl () ++ str "|" ++ spc () ++
+ pr_match_rule false prtac r)
lrul)
| TacFun (lvar,body) ->
hov 0 (str "Fun" ++
@@ -586,10 +605,11 @@ in (prtac,pr0,pr_match_rule)
let (pr_raw_tactic,pr_raw_tactic0,pr_match_rule) =
make_pr_tac
(Ppconstr.pr_constr,
+ Ppconstr.pr_constr,
pr_metanum pr_reference,
pr_reference,
pr_or_meta (fun (loc,id) -> pr_id id),
- pr_raw_extend)
+ pr_raw_extend Ppconstr.pr_constr)
let _ = pr_rawtac := pr_raw_tactic
let _ = pr_rawtac0 := pr_raw_tactic0
@@ -597,7 +617,9 @@ let _ = pr_rawtac0 := pr_raw_tactic0
let (pr_tactic,_,_) =
make_pr_tac
(Printer.prterm,
+ Ppconstr.pr_constr,
pr_evaluable_reference,
pr_inductive,
pr_id,
pr_extend)
+
diff --git a/parsing/pptactic.mli b/parsing/pptactic.mli
index ca16c21e5..186a726f6 100644
--- a/parsing/pptactic.mli
+++ b/parsing/pptactic.mli
@@ -13,20 +13,24 @@ open Genarg
open Tacexpr
open Pretyping
open Proof_type
+open Topconstr
+(* if the boolean is false then the extension applies only to old syntax *)
val declare_extra_genarg_pprule :
+ bool ->
('a raw_abstract_argument_type * ('a -> std_ppcmds)) ->
('b closed_abstract_argument_type * ('b -> std_ppcmds)) -> unit
+(* idem *)
val declare_extra_tactic_pprule :
- string ->
+ bool -> string ->
(raw_generic_argument list ->
string * Egrammar.grammar_tactic_production list)
-> (closed_generic_argument list ->
string * Egrammar.grammar_tactic_production list)
-> unit
-val pr_match_pattern : Tacexpr.pattern_expr match_pattern -> std_ppcmds
+val pr_match_pattern : pattern_expr match_pattern -> std_ppcmds
val pr_match_rule : bool -> (raw_tactic_expr -> std_ppcmds) ->
(pattern_expr,raw_tactic_expr) match_rule -> std_ppcmds
@@ -34,3 +38,18 @@ val pr_match_rule : bool -> (raw_tactic_expr -> std_ppcmds) ->
val pr_raw_tactic : raw_tactic_expr -> std_ppcmds
val pr_tactic : Proof_type.tactic_expr -> std_ppcmds
+
+val pr_rawgen:
+ (constr_expr -> std_ppcmds) ->
+ (raw_tactic_expr -> std_ppcmds) ->
+ (constr_expr, raw_tactic_expr) generic_argument ->
+ std_ppcmds
+val pr_raw_extend:
+ (constr_expr -> std_ppcmds) ->
+ (raw_tactic_expr -> std_ppcmds) -> string ->
+ (constr_expr, raw_tactic_expr) generic_argument list ->
+ std_ppcmds
+val pr_extend :
+ (raw_tactic_expr -> std_ppcmds) -> string ->
+ (Term.constr, raw_tactic_expr) generic_argument list ->
+ std_ppcmds
diff --git a/parsing/prettyp.ml b/parsing/prettyp.ml
index 4404c1929..648d4690d 100644
--- a/parsing/prettyp.ml
+++ b/parsing/prettyp.ml
@@ -411,12 +411,6 @@ let print_local_context () =
in
(print_var_rec env ++ print_last_const env)
-let fprint_var name typ =
- (str ("*** [" ^ name ^ " :") ++ fprtype typ ++ str "]" ++ fnl ())
-
-let fprint_judge {uj_val=trm;uj_type=typ} =
- (fprterm trm ++ str" : " ++ fprterm typ)
-
let unfold_head_fconst =
let rec unfrec k = match kind_of_term k with
| Const cst -> constant_value (Global.env ()) cst
diff --git a/parsing/printer.ml b/parsing/printer.ml
index 72fe499e6..df2aabdf8 100644
--- a/parsing/printer.ml
+++ b/parsing/printer.ml
@@ -28,15 +28,91 @@ open Ppconstr
let emacs_str s = if !Options.print_emacs then s else ""
-(* These are the names of the universes where the pp rules for constr and
- tactic are put (must be consistent with files PPConstr.v and PPTactic.v *)
-
-let tactic_syntax_universe = "tactic"
+(**********************************************************************)
+(* Old Ast printing *)
+let constr_syntax_universe = "constr"
(* This is starting precedence for printing constructions or tactics *)
(* Level 9 means no parentheses except for applicative terms (at level 10) *)
-let tactic_initial_prec = Some ((tactic_syntax_universe,(9,0,0)),Ppextend.L)
-
+let constr_initial_prec_v7 = Some (9,Ppextend.L)
+let constr_initial_prec = Some (200,Ppextend.E)
+
+let dfltpr ast = (str"#GENTERM " ++ print_ast ast);;
+
+let global_const_name kn =
+ try pr_global Idset.empty (ConstRef kn)
+ with Not_found -> (* May happen in debug *)
+ (str ("CONST("^(string_of_kn kn)^")"))
+
+let global_var_name id =
+ try pr_global Idset.empty (VarRef id)
+ with Not_found -> (* May happen in debug *)
+ (str ("SECVAR("^(string_of_id id)^")"))
+
+let global_ind_name (kn,tyi) =
+ try pr_global Idset.empty (IndRef (kn,tyi))
+ with Not_found -> (* May happen in debug *)
+ (str ("IND("^(string_of_kn kn)^","^(string_of_int tyi)^")"))
+
+let global_constr_name ((kn,tyi),i) =
+ try pr_global Idset.empty (ConstructRef ((kn,tyi),i))
+ with Not_found -> (* May happen in debug *)
+ (str ("CONSTRUCT("^(string_of_kn kn)^","^(string_of_int tyi)
+ ^","^(string_of_int i)^")"))
+
+let globpr gt = match gt with
+ | Nvar(_,s) -> (pr_id s)
+ | Node(_,"EVAR", [Num (_,ev)]) -> (str ("?" ^ (string_of_int ev)))
+ | Node(_,"CONST",[Path(_,sl)]) ->
+ global_const_name (section_path sl)
+ | Node(_,"SECVAR",[Nvar(_,s)]) ->
+ global_var_name s
+ | Node(_,"MUTIND",[Path(_,sl); Num(_,tyi)]) ->
+ global_ind_name (section_path sl, tyi)
+ | Node(_,"MUTCONSTRUCT",[Path(_,sl); Num(_,tyi); Num(_,i)]) ->
+ global_constr_name ((section_path sl, tyi), i)
+ | Dynamic(_,d) ->
+ if (Dyn.tag d) = "constr" then (str"<dynamic [constr]>")
+ else dfltpr gt
+ | gt -> dfltpr gt
+
+
+let wrap_exception = function
+ Anomaly (s1,s2) ->
+ warning ("Anomaly ("^s1^")"); pp s2;
+ str"<PP error: non-printable term>"
+ | Failure _ | UserError _ | Not_found ->
+ str"<PP error: non-printable term>"
+ | s -> raise s
+
+let gentermpr_fail gt =
+ let prec =
+ if !Options.v7 then constr_initial_prec_v7 else constr_initial_prec in
+ Esyntax.genprint globpr constr_syntax_universe prec gt
+
+let gentermpr gt =
+ try gentermpr_fail gt
+ with s -> wrap_exception s
+
+(**********************************************************************)
+(* Generic printing: choose old or new printers *)
+
+(* [at_top] means ids of env must be avoided in bound variables *)
+let gentermpr_core at_top env t =
+ if !Options.v7 then gentermpr (Termast.ast_of_constr at_top env t)
+ else Ppconstrnew.pr_constr (Constrextern.extern_constr at_top env t)
+let pr_cases_pattern t =
+ if !Options.v7 then gentermpr (Termast.ast_of_cases_pattern t)
+ else Ppconstrnew.pr_cases_pattern
+ (Constrextern.extern_cases_pattern Idset.empty t)
+let pr_pattern_env tenv env t =
+ if !Options.v7 then gentermpr (Termast.ast_of_pattern tenv env t)
+ else Ppconstrnew.pr_constr
+ (Constrextern.extern_pattern tenv env t)
+
+(**********************************************************************)
+(* Derived printers *)
+
let prterm_env_at_top env = gentermpr_core true env
let prterm_env env = gentermpr_core false env
let prtype_env env typ = prterm_env env typ
@@ -48,25 +124,14 @@ let prterm t = prterm_env (Global.env()) t
let prtype t = prtype_env (Global.env()) t
let prjudge j = prjudge_env (Global.env()) j
-let fprterm_env a =
- warning "Fw printing not implemented, use CCI printing 1"; prterm_env a
-let fprterm a =
- warning "Fw printing not implemented, use CCI printing 2"; prterm a
-
-let fprtype_env env typ =
- warning "Fw printing not implemented, use CCI printing 3"; prtype_env env typ
-let fprtype a =
- warning "Fw printing not implemented, use CCI printing 4"; prtype a
+let pr_constant env cst = prterm_env env (mkConst cst)
+let pr_existential env ev = prterm_env env (mkEvar ev)
+let pr_inductive env ind = prterm_env env (mkInd ind)
+let pr_constructor env cstr = prterm_env env (mkConstruct cstr)
+let pr_global = pr_global Idset.empty
-(* For compatibility *)
-let fterm0 = fprterm_env
-
-let pr_constant env cst = gentermpr (ast_of_constant env cst)
-let pr_existential env ev = gentermpr (ast_of_existential env ev)
-let pr_inductive env ind = gentermpr (ast_of_inductive env ind)
-let pr_constructor env cstr = gentermpr (ast_of_constructor env cstr)
-
-let pr_global = pr_global
+let pr_rawterm t =
+ pr_constr (Constrextern.extern_rawconstr Idset.empty t)
open Pattern
let pr_ref_label = function (* On triche sur le contexte *)
@@ -75,49 +140,8 @@ let pr_ref_label = function (* On triche sur le contexte *)
| CstrNode sp -> pr_constructor (Global.env()) sp
| VarNode id -> pr_id id
-let pr_cases_pattern t = gentermpr (Termast.ast_of_cases_pattern t)
-(*
-let pr_rawterm t = gentermpr (Termast.ast_of_rawconstr t)
-*)
-let pr_rawterm t = pr_constr (Constrextern.extern_rawconstr t)
-let pr_pattern_env tenv env t = gentermpr (Termast.ast_of_pattern tenv env t)
let pr_pattern t = pr_pattern_env (Global.env()) empty_names_context t
-(*
-let gentacpr x = Pptactic.prtac x
-*)
-
-(*
-and default_tacpr = function
- | Nvar(_,s) -> (pr_id s)
-
- (* constr's may occur inside tac expressions ! *)
- | Node(_,"EVAR", [Num (_,ev)]) -> (str ("?" ^ (string_of_int ev)))
- | Node(_,"CONST",[Path(_,sl)]) ->
- let sp = section_path sl in
- pr_global (ConstRef sp)
- | Node(_,"MUTIND",[Path(_,sl); Num(_,tyi)]) ->
- let sp = section_path sl in
- pr_global (IndRef (sp,tyi))
- | Node(_,"MUTCONSTRUCT",[Path(_,sl); Num(_,tyi); Num(_,i)]) ->
- let sp = section_path sl in
- pr_global (ConstructRef ((sp,tyi),i))
-
- (* This should be tactics *)
- | Node(_,s,[]) -> (str s)
-(* TODO
- | Node(_,s,ta) ->
- (str s ++ brk(1,2) ++ hov 0 (prlist_with_sep pr_spc gentacpr ta))
-*)
- | Dynamic(_,d) as gt ->
- let tg = Dyn.tag d in
- if tg = "tactic" then (str"<dynamic [tactic]>")
- else if tg = "value" then (str"<dynamic [value]>")
- else if tg = "constr" then (str"<dynamic [constr]>")
- else dfltpr gt
- | gt -> dfltpr gt
-*)
-
let pr_var_decl env (id,c,typ) =
let pbody = match c with
| None -> (mt ())
diff --git a/parsing/printer.mli b/parsing/printer.mli
index 48ee955cc..b69a9955b 100644
--- a/parsing/printer.mli
+++ b/parsing/printer.mli
@@ -58,13 +58,3 @@ val pr_context_of : env -> std_ppcmds
val emacs_str : string -> string
-(*i*)
-val fprterm_env : env -> constr -> std_ppcmds
-val fprterm : constr -> std_ppcmds
-val fprtype_env : env -> types -> std_ppcmds
-val fprtype : types -> std_ppcmds
-
-(* For compatibility *)
-val fterm0 : env -> constr -> std_ppcmds
-(*i*)
-
diff --git a/parsing/q_coqast.ml4 b/parsing/q_coqast.ml4
index 1f352f6af..2b3967707 100644
--- a/parsing/q_coqast.ml4
+++ b/parsing/q_coqast.ml4
@@ -407,8 +407,9 @@ let rec mlexpr_of_atomic_tactic = function
<:expr< Tacexpr.TacLeft $mlexpr_of_binding_kind l$>>
| Tacexpr.TacRight l ->
<:expr< Tacexpr.TacRight $mlexpr_of_binding_kind l$>>
- | Tacexpr.TacSplit l ->
- <:expr< Tacexpr.TacSplit $mlexpr_of_binding_kind l$>>
+ | Tacexpr.TacSplit (b,l) ->
+ <:expr< Tacexpr.TacSplit
+ ($mlexpr_of_bool b$,$mlexpr_of_binding_kind l$)>>
| Tacexpr.TacAnyConstructor t ->
<:expr< Tacexpr.TacAnyConstructor $mlexpr_of_option mlexpr_of_tactic t$>>
| Tacexpr.TacConstructor (n,l) ->
diff --git a/parsing/search.ml b/parsing/search.ml
index 74cdd77dd..fc5792fa0 100644
--- a/parsing/search.ml
+++ b/parsing/search.ml
@@ -107,7 +107,7 @@ let plain_display ref a c =
let filter_by_module (module_list:dir_path list) (accept:bool)
(ref:global_reference) _ _ =
try
- let sp = sp_of_global None ref in
+ let sp = sp_of_global ref in
let sl = dirpath sp in
let rec filter_aux = function
| m :: tl -> (not (is_dirpath_prefix_of m sl)) && (filter_aux tl)
diff --git a/parsing/tacextend.ml4 b/parsing/tacextend.ml4
index 593fb0169..a3d5f496e 100644
--- a/parsing/tacextend.ml4
+++ b/parsing/tacextend.ml4
@@ -124,7 +124,16 @@ let make_printing_rule l =
(<:patt< _ >>,None,<:expr< failwith "Tactic extension: cannot occur" >>) in
List.fold_right add_printing_clause l [default]
-let declare_tactic loc s cl =
+let new_tac_ext (s,cl) =
+ (String.lowercase s, List.map
+ (fun (s,l,e) ->
+ (String.lowercase s, List.map
+ (function TacTerm s -> TacTerm (String.lowercase s)
+ | t -> t) l,
+ e))
+ cl)
+
+let declare_tactic_v7 loc s cl =
let pl = make_printing_rule cl in
let gl = mlexpr_of_clause cl in
let hide_tac (_,p,e) =
@@ -142,13 +151,44 @@ let declare_tactic loc s cl =
<:str_item<
declare
open Pcoq;
- declare $list:List.map hide_tac cl$ end;
+ Egrammar.extend_tactic_grammar $se$ $gl$;
+ let pp = fun [ $list:pl$ ] in
+ Pptactic.declare_extra_tactic_pprule False $se$ pp pp;
+ end
+ >>
+
+let declare_tactic loc s cl =
+ let (s',cl') = new_tac_ext (s,cl) in
+ let pl' = make_printing_rule cl' in
+ let gl' = mlexpr_of_clause cl' in
+ let se' = mlexpr_of_string s' in
+ let pl = make_printing_rule cl in
+ let gl = mlexpr_of_clause cl in
+ let hide_tac (_,p,e) =
+ (* reste a definir les fonctions cachees avec des noms frais *)
+ let stac = "h_"^s' in
+ let e =
+ make_fun
+ <:expr<
+ Refiner.abstract_extended_tactic $mlexpr_of_string s'$ $make_args p$ $e$
+ >>
+ p in
+ <:str_item< value $lid:stac$ = $e$ >>
+ in
+ let se = mlexpr_of_string s in
+ <:str_item<
+ declare
+ open Pcoq;
+ declare $list:List.map hide_tac cl'$ end;
try
- Refiner.add_tactic $se$ (fun [ $list:make_clauses s cl$ ])
+ Refiner.add_tactic $se'$ (fun [ $list:make_clauses s' cl'$ ])
with e -> Pp.pp (Cerrors.explain_exn e);
- Egrammar.extend_tactic_grammar $se$ $gl$;
+ Egrammar.extend_tactic_grammar $se'$ $gl'$;
+ let pp' = fun [ $list:pl'$ ] in
+ Pptactic.declare_extra_tactic_pprule True $se'$ pp' pp';
+ Egrammar.extend_tactic_grammar $se'$ $gl$;
let pp = fun [ $list:pl$ ] in
- Pptactic.declare_extra_tactic_pprule $se$ pp pp;
+ Pptactic.declare_extra_tactic_pprule False $se'$ pp pp;
end
>>
@@ -194,7 +234,11 @@ EXTEND
[ [ "TACTIC"; "EXTEND"; s = [ UIDENT | LIDENT ];
OPT "|"; l = LIST1 tacrule SEP "|";
"END" ->
- declare_tactic loc s l ] ]
+ declare_tactic loc s l
+ | "V7"; "TACTIC"; "EXTEND"; s = [ UIDENT | LIDENT ];
+ OPT "|"; l = LIST1 tacrule SEP "|";
+ "END" ->
+ declare_tactic_v7 loc s l ] ]
;
tacrule:
[ [ "["; s = STRING; l = LIST0 tacargs; "]"; "->"; "["; e = Pcaml.expr; "]"