diff options
author | Samuel Mimram <smimram@debian.org> | 2006-04-28 14:59:16 +0000 |
---|---|---|
committer | Samuel Mimram <smimram@debian.org> | 2006-04-28 14:59:16 +0000 |
commit | 3ef7797ef6fc605dfafb32523261fe1b023aeecb (patch) | |
tree | ad89c6bb57ceee608fcba2bb3435b74e0f57919e /parsing/g_vernac.ml4 | |
parent | 018ee3b0c2be79eb81b1f65c3f3fa142d24129c8 (diff) |
Imported Upstream version 8.0pl3+8.1alphaupstream/8.0pl3+8.1alpha
Diffstat (limited to 'parsing/g_vernac.ml4')
-rw-r--r-- | parsing/g_vernac.ml4 | 941 |
1 files changed, 580 insertions, 361 deletions
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4 index 87183e18..18a424a8 100644 --- a/parsing/g_vernac.ml4 +++ b/parsing/g_vernac.ml4 @@ -6,35 +6,39 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(* $Id: g_vernac.ml4,v 1.93.2.3 2004/10/12 10:11:28 herbelin Exp $ *) +(* $Id: g_vernac.ml4 8624 2006-03-13 17:38:17Z msozeau $ *) +(*i camlp4deps: "parsing/grammar.cma" i*) +open Pp +open Util open Names open Topconstr open Vernacexpr open Pcoq -open Pp open Tactic -open Util -open Constr -open Vernac_ -open Prim open Decl_kinds - open Genarg +open Extend +open Ppextend +open Goptions -let evar_constr loc = CHole loc +open Prim +open Constr +open Vernac_ +open Module -let class_rawexpr = G_basevernac.class_rawexpr -let thm_token = G_proofs.thm_token +let vernac_kw = [ ";"; ","; ">->"; ":<"; "<:"; "where"; "at" ] +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 filter_com (b,e) = - let (b,e) = unloc (b,e) in - Pp.comments := List.filter (fun ((b',e'),s) -> b'<b || e'>e) !Pp.comments +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" -if !Options.v7 then +let no_hook _ _ = () GEXTEND Gram GLOBAL: vernac gallina_ext; vernac: @@ -44,163 +48,121 @@ GEXTEND Gram | g = gallina_ext; "." -> g | c = command; "." -> c | c = syntax; "." -> c - | n = natural; ":"; tac = Tactic.tactic; "." -> VernacSolve (n,tac,true) - | n = natural; ":"; tac = Tactic.tactic; "!!" -> VernacSolve (n,tac,false) - | n = natural; ":"; v = check_command; "." -> v (Some n) - | "["; l = vernac_list_tail -> VernacList l - - (* For translation from V7 to V8 *) - | IDENT "V7only"; v = vernac -> - filter_com loc; VernacV7only v - | IDENT "V8only"; v = vernac -> VernacV8only v - -(* - (* This is for "Grammar vernac" rules *) - | id = METAIDENT -> VernacVar (Names.id_of_string id) -*) + | "["; l = LIST1 located_vernac; "]"; "." -> VernacList l ] ] ; - - check_command: - [ [ IDENT "Eval"; r = Tactic.red_expr; "in"; c = constr -> - fun g -> VernacCheckMayEval (Some r, g, c) - | IDENT "Check"; c = constr -> - fun g -> VernacCheckMayEval (None, g, c) ] ] - ; vernac: FIRST [ [ IDENT "Time"; v = vernac -> VernacTime v ] ] ; vernac: LAST - [ [ tac = Tactic.tactic; "." -> VernacSolve (1,tac,true) - | tac = Tactic.tactic; "!!" -> VernacSolve (1,tac,false) - | IDENT "Existential"; n = natural; c = constr_body -> - VernacSolveExistential (n,c) - ] ] - ; - constr_body: - [ [ ":="; c = constr; ":"; t = constr -> CCast(loc,c,t) - | ":"; t = constr; ":="; c = constr -> CCast(loc,c,t) - | ":="; c = constr -> c ] ] + [ [ gln = OPT[n=natural; ":" -> n]; + tac = subgoal_command -> tac gln ] ] ; - vernac_list_tail: - [ [ v = located_vernac; l = vernac_list_tail -> v :: l - | "]"; "." -> [] ] ] + subgoal_command: + [ [ c = check_command; "." -> c + | tac = Tactic.tactic; + use_dft_tac = [ "." -> false | "..." -> true ] -> + (fun g -> + let g = match g with Some gl -> gl | _ -> 1 in + VernacSolve(g,tac,use_dft_tac)) ] ] ; located_vernac: [ [ v = vernac -> loc, v ] ] ; END + let test_plurial_form = function - | [_,([_],_)] -> + | [(_,([_],_))] -> Options.if_verbose warning - "Keywords Variables/Hypotheses/Parameters expect more than one assumption" + "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 *) -if !Options.v7 then GEXTEND Gram - GLOBAL: gallina gallina_ext thm_token; + GLOBAL: gallina gallina_ext thm_token def_body; + gallina: + (* Definition, Theorem, Variable, Axiom, ... *) + [ [ thm = thm_token; id = identref; bl = LIST0 binder_let; ":"; + c = lconstr -> + VernacStartTheoremProof (thm, id, (bl, c), false, no_hook) + | stre = assumption_token; bl = assum_list -> + VernacAssumption (stre, bl) + | stre = assumptions_token; bl = assum_list -> + test_plurial_form bl; + VernacAssumption (stre, bl) + | IDENT "Boxed";"Definition";id = identref; b = def_body -> + VernacDefinition ((Global,true,Definition), id, b, no_hook) + | IDENT "Unboxed";"Definition";id = identref; b = def_body -> + VernacDefinition ((Global,false,Definition), id, b, no_hook) + | (f,d) = def_token; id = identref; b = def_body -> + VernacDefinition (d, id, b, f) + (* Gallina inductive declarations *) + | f = finite_token; + indl = LIST1 inductive_definition SEP "with" -> + VernacInductive (f,indl) + | IDENT "Boxed";"Fixpoint"; recs = LIST1 rec_definition SEP "with" -> + VernacFixpoint (recs,true) + | IDENT "Unboxed";"Fixpoint"; recs = LIST1 rec_definition SEP "with" -> + VernacFixpoint (recs,false) + | "Fixpoint"; recs = LIST1 rec_definition SEP "with" -> + VernacFixpoint (recs,Options.boxed_definitions()) + | "CoFixpoint"; corecs = LIST1 corec_definition SEP "with" -> + VernacCoFixpoint (corecs,false) + | IDENT "Scheme"; l = LIST1 scheme SEP "with" -> VernacScheme l ] ] + ; + gallina_ext: + [ [ b = record_token; oc = opt_coercion; name = identref; + ps = LIST0 binder_let; ":"; + s = lconstr; ":="; cstr = OPT identref; "{"; + fs = LIST0 record_field SEP ";"; "}" -> + VernacRecord (b,(oc,name),ps,s,cstr,fs) +(* Non porté ? + | f = finite_token; s = csort; id = identref; + indpar = LIST0 simple_binder; ":="; lc = constructor_list -> + VernacInductive (f,[id,None,indpar,s,lc]) +*) + ] ] + ; thm_token: [ [ "Theorem" -> Theorem | IDENT "Lemma" -> Lemma | IDENT "Fact" -> Fact - | IDENT "Remark" -> Remark ] ] + | IDENT "Remark" -> Remark + | IDENT "Corollary" -> Corollary + | IDENT "Proposition" -> Proposition + | IDENT "Property" -> Property ] ] ; def_token: - [ [ "Definition" -> (fun _ _ -> ()), (Global, Definition) - | IDENT "Local" -> (fun _ _ -> ()), (Local, Definition) - | IDENT "SubClass" -> Class.add_subclass_hook, (Global, SubClass) + [ [ "Definition" -> + no_hook, (Global, Options.boxed_definitions(), Definition) + | IDENT "Let" -> + no_hook, (Local, Options.boxed_definitions(), Definition) + | IDENT "Example" -> + no_hook, (Global, Options.boxed_definitions(), Example) + | IDENT "SubClass" -> Class.add_subclass_hook, (Global, false, SubClass) | IDENT "Local"; IDENT "SubClass" -> - Class.add_subclass_hook, (Local, SubClass) ] ] + Class.add_subclass_hook, (Local, false, SubClass) ] ] ; assumption_token: [ [ "Hypothesis" -> (Local, Logical) | "Variable" -> (Local, Definitional) | "Axiom" -> (Global, Logical) | "Parameter" -> (Global, Definitional) - | IDENT "Conjecture" -> (Global,Conjectural) ] ] + | IDENT "Conjecture" -> (Global, Conjectural) ] ] ; assumptions_token: [ [ IDENT "Hypotheses" -> (Local, Logical) | IDENT "Variables" -> (Local, Definitional) + | IDENT "Axioms" -> (Global, Logical) | IDENT "Parameters" -> (Global, Definitional) ] ] ; - of_type_with_opt_coercion: - [ [ ":>" -> true - | ":"; ">" -> true - | ":" -> false ] ] - ; - params: - [ [ idl = LIST1 identref SEP ","; coe = of_type_with_opt_coercion; - c = constr -> (coe,(idl,c)) - ] ] - ; - ne_params_list: - [ [ ll = LIST1 params SEP ";" -> ll ] ] - ; - name_comma_list_tail: - [ [ ","; nal = LIST1 name SEP "," -> nal | -> [] ] ] - ; - ident_comma_list_tail: - [ [ ","; nal = LIST1 identref SEP "," -> nal | -> [] ] ] - ; - decl_notation: - [ [ "where"; ntn = STRING; ":="; c = constr; - scopt = OPT [ ":"; sc = IDENT -> sc] -> (ntn,c,scopt) ] ] - ; - type_option: - [ [ ":"; c = constr -> c - | -> evar_constr loc ] ] - ; - opt_casted_constr: - [ [ c = constr; ":"; t = constr -> CCast(loc,c,t) - | c = constr -> c ] ] - ; - vardecls: - [ [ na = name; nal = name_comma_list_tail; c = type_option - -> LocalRawAssum (na::nal,c) - | na = name; "="; c = opt_casted_constr -> - LocalRawDef (na,c) - | na = name; ":="; c = opt_casted_constr -> - LocalRawDef (na,c) - ] ] - ; - binders: - [ [ "["; bl = LIST1 vardecls SEP ";"; "]" -> bl ] ] - ; - binders_list: - [ [ bls = LIST0 binders -> List.flatten bls ] ] - ; - reduce: - [ [ IDENT "Eval"; r = Tactic.red_expr; "in" -> Some r - | -> None ] ] - ; - def_body: - [ [ bl = binders_list; ":="; red = reduce; c = constr; ":"; t = constr -> - DefineBody (bl, red, c, Some t) - | bl = binders_list; ":"; t = constr; ":="; red = reduce; c = constr -> - DefineBody (bl, red, c, Some t) - | bl = binders_list; ":="; red = reduce; c = constr -> - DefineBody (bl, red, c, None) - | bl = binders_list; ":"; t = constr -> - ProveBody (bl, t) ] ] - ; - gallina: - (* Definition, Theorem, Variable, Axiom, ... *) - [ [ thm = thm_token; id = identref; bl = binders_list; ":"; c = constr -> - VernacStartTheoremProof (thm, id, (bl, c), false, (fun _ _ -> ())) - | (f,d) = def_token; id = identref; b = def_body -> - VernacDefinition (d, id, b, f) - | stre = assumption_token; bl = ne_params_list -> - VernacAssumption (stre, bl) - | stre = assumptions_token; bl = ne_params_list -> - test_plurial_form bl; - VernacAssumption (stre, bl) - ] ] - ; - (* Gallina inductive declarations *) finite_token: [ [ "Inductive" -> true | "CoInductive" -> false ] ] @@ -208,192 +170,250 @@ GEXTEND Gram record_token: [ [ IDENT "Record" -> true | IDENT "Structure" -> false ] ] ; - constructor: - [ [ idl = LIST1 identref SEP ","; coe = of_type_with_opt_coercion; - c = constr -> List.map (fun id -> (coe,(id,c))) idl ] ] - ; - constructor_list: - [ [ "|"; l = LIST1 constructor SEP "|" -> List.flatten l - | l = LIST1 constructor SEP "|" -> List.flatten l - | -> [] ] ] - ; - block_old_style: - [ [ ind = oneind_old_style; "with"; indl = block_old_style -> ind :: indl - | ind = oneind_old_style -> [ind] ] ] + (* Simple definitions *) + def_body: + [ [ bl = LIST0 binder_let; ":="; red = reduce; c = lconstr -> + (match c with + CCast(_,c,k,t) -> DefineBody (bl, red, c, Some t) + | _ -> DefineBody (bl, red, c, None)) + | bl = LIST0 binder_let; ":"; t = lconstr; ":="; red = reduce; c = lconstr -> + DefineBody (bl, red, c, Some t) + | bl = LIST0 binder_let; ":"; t = lconstr -> + ProveBody (bl, t) ] ] ; - oneind_old_style: - [ [ id = identref; ":"; c = constr; ":="; lc = constructor_list -> - (id,c,lc) ] ] + reduce: + [ [ IDENT "Eval"; r = Tactic.red_expr; "in" -> Some r + | -> None ] ] ; - oneind: - [ [ id = identref; indpar = simple_binders_list; ":"; c = constr; - ":="; lc = constructor_list; ntn = OPT decl_notation -> + decl_notation: + [ [ OPT [ "where"; ntn = ne_string; ":="; c = constr; + scopt = OPT [ ":"; sc = IDENT -> sc] -> (ntn,c,scopt) ] ] ] + ; + (* Inductives and records *) + inductive_definition: + [ [ id = identref; indpar = LIST0 binder_let; ":"; c = lconstr; + ":="; lc = constructor_list; ntn = decl_notation -> (id,ntn,indpar,c,lc) ] ] ; - simple_binders_list: - [ [ bl = ne_simple_binders_list -> bl + constructor_list: + [ [ "|"; l = LIST1 constructor SEP "|" -> l + | l = LIST1 constructor SEP "|" -> l | -> [] ] ] ; +(* + csort: + [ [ s = sort -> CSort (loc,s) ] ] + ; +*) opt_coercion: [ [ ">" -> true | -> false ] ] ; - onescheme: - [ [ id = identref; ":="; dep = dep; ind = global; IDENT "Sort"; - s = sort -> (id,dep,ind,s) ] ] - ; - schemes: - [ [ recl = LIST1 onescheme SEP "with" -> recl ] ] - ; - dep: - [ [ IDENT "Induction"; IDENT "for" -> true - | IDENT "Minimality"; IDENT "for" -> false ] ] + (* (co)-fixpoints *) + rec_definition: + [ [ id = ident; bl = LIST1 binder_let; + annot = rec_annotation; type_ = type_cstr; + ":="; def = lconstr; ntn = decl_notation -> + let names = List.map snd (names_of_local_assums bl) in + let ni = + match fst annot with + Some id -> + (try list_index (Name id) names - 1 + with Not_found -> Util.user_err_loc + (loc,"Fixpoint", + Pp.str "No argument named " ++ Nameops.pr_id id)) + | None -> + if List.length names > 1 then + Util.user_err_loc + (loc,"Fixpoint", + Pp.str "the recursive argument needs to be specified"); + 0 in + ((id, (ni, snd annot), bl, type_, def),ntn) ] ] + ; + corec_definition: + [ [ id = ident; bl = LIST0 binder_let; c = type_cstr; ":="; + def = lconstr -> + (id,bl,c ,def) ] ] + ; + rec_annotation: + [ [ "{"; IDENT "struct"; id=IDENT; "}" -> (Some (id_of_string id), CStructRec) + | "{"; IDENT "wf"; id=IDENT; rel=lconstr; "}" -> (Some (id_of_string id), CWfRec rel) + | -> (None, CStructRec) + ] ] ; - onerec: - [ [ id = base_ident; bl = ne_fix_binders; ":"; type_ = constr; - ":="; def = constr; ntn = OPT decl_notation -> - let ni = List.length (List.flatten (List.map fst bl)) - 1 in - let bl = List.map (fun(nal,ty)->LocalRawAssum(nal,ty)) bl in - ((id, ni, bl, type_, def), ntn) ] ] + type_cstr: + [ [ ":"; c=lconstr -> c + | -> CHole loc ] ] ; - specifrec: - [ [ l = LIST1 onerec SEP "with" -> l ] ] + (* Inductive schemes *) + scheme: + [ [ id = identref; ":="; dep = dep_scheme; "for"; ind = global; + IDENT "Sort"; s = sort -> + (id,dep,ind,s) ] ] ; - onecorec: - [ [ id = base_ident; ":"; c = constr; ":="; def = constr -> - (id,[],c,def) ] ] + dep_scheme: + [ [ IDENT "Induction" -> true + | IDENT "Minimality" -> false ] ] ; - specifcorec: - [ [ l = LIST1 onecorec SEP "with" -> l ] ] + (* Various Binders *) +(* + (* ... without coercions *) + binder_nodef: + [ [ b = binder_let -> + (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 *) record_field: - [ [ id = name; oc = of_type_with_opt_coercion; t = constr -> - (oc,AssumExpr (id,t)) - | id = name; oc = of_type_with_opt_coercion; t = constr; - ":="; b = constr -> - (oc,DefExpr (id,b,Some t)) - | id = name; ":="; b = constr -> - (false,DefExpr (id,b,None)) ] ] - ; - fields: - [ [ fs = LIST0 record_field SEP ";" -> fs ] ] - ; - simple_binders: - [ [ "["; bll = LIST1 vardecls SEP ";"; "]" -> bll ] ] - ; - ne_simple_binders_list: - [ [ bll = LIST1 simple_binders -> (List.flatten bll) ] ] - ; - fix_params: - [ [ idl = LIST1 name SEP ","; ":"; c = constr -> (idl, c) - | idl = LIST1 name SEP "," -> (idl, evar_constr dummy_loc) - ] ] - ; - fix_binders: - [ [ "["; bll = LIST1 fix_params SEP ";"; "]" -> bll ] ] - ; - ne_fix_binders: - [ [ bll = LIST1 fix_binders -> List.flatten bll ] ] + [ [ id = name -> (false,AssumExpr(id,CHole loc)) + | id = name; oc = of_type_with_opt_coercion; t = lconstr -> + (oc,AssumExpr (id,t)) + | id = name; oc = of_type_with_opt_coercion; + t = lconstr; ":="; b = lconstr -> (oc,DefExpr (id,b,Some t)) + | id = name; ":="; b = lconstr -> + match b with + CCast(_,b,_,t) -> (false,DefExpr(id,b,Some t)) + | _ -> (false,DefExpr(id,b,None)) ] ] + ; + assum_list: + [ [ bl = LIST1 assum_coe -> bl | b = simple_assum_coe -> [b] ] ] + ; + assum_coe: + [ [ "("; a = simple_assum_coe; ")" -> a ] ] + ; + simple_assum_coe: + [ [ idl = LIST1 identref; oc = of_type_with_opt_coercion; c = lconstr -> + (oc,(idl,c)) ] ] ; - rec_constructor: - [ [ c = identref -> Some c - | -> None ] ] - ; - gallina_ext: - [ [ IDENT "Mutual"; bl = ne_simple_binders_list ; f = finite_token; - indl = block_old_style -> - let indl' = List.map (fun (id,ar,c) -> (id,None,bl,ar,c)) indl in - VernacInductive (f,indl') - | b = record_token; oc = opt_coercion; name = identref; - ps = simple_binders_list; ":"; - s = constr; ":="; c = rec_constructor; "{"; fs = fields; "}" -> - VernacRecord (b,(oc,name),ps,s,c,fs) - ] ] - ; - gallina: - [ [ IDENT "Mutual"; f = finite_token; indl = LIST1 oneind SEP "with" -> - VernacInductive (f,indl) - | f = finite_token; indl = LIST1 oneind SEP "with" -> - VernacInductive (f,indl) - | "Fixpoint"; recs = specifrec -> VernacFixpoint recs - | "CoFixpoint"; corecs = specifcorec -> VernacCoFixpoint corecs - | IDENT "Scheme"; l = schemes -> VernacScheme l - | f = finite_token; s = csort; id = identref; - indpar = simple_binders_list; ":="; lc = constructor_list -> - VernacInductive (f,[id,None,indpar,s,lc]) ] ] + constructor: + [ [ id = identref; l = LIST0 binder_let; + coe = of_type_with_opt_coercion; c = lconstr -> + (coe,(id,G_constr.mkCProdN loc l c)) + | id = identref; l = LIST0 binder_let -> + (false,(id,G_constr.mkCProdN loc l (CHole loc))) ] ] ; - csort: - [ [ s = sort -> CSort (loc,s) ] ] + of_type_with_opt_coercion: + [ [ ":>" -> true + | ":"; ">" -> true + | ":" -> false ] ] ; +END + + +(* Modules and Sections *) +GEXTEND Gram + GLOBAL: gallina_ext module_expr module_type; + gallina_ext: - [ [ -(* Sections *) - IDENT "Section"; id = identref -> VernacBeginSection id - | IDENT "Chapter"; id = identref -> VernacBeginSection id ] ] - ; - module_vardecls: - [ [ id = identref; idl = ident_comma_list_tail; ":"; - mty = Module.module_type -> (id::idl,mty) ] ] + [ [ (* Interactive module declaration *) + IDENT "Module"; export = export_token; id = identref; + bl = LIST0 module_binder; mty_o = OPT of_module_type; + mexpr_o = OPT is_module_expr -> + VernacDefineModule (export, id, bl, mty_o, mexpr_o) + + | IDENT "Module"; "Type"; id = identref; + bl = LIST0 module_binder; mty_o = OPT is_module_type -> + VernacDeclareModuleType (id, bl, mty_o) + + | IDENT "Declare"; IDENT "Module"; export = export_token; id = identref; + bl = LIST0 module_binder; mty_o = of_module_type -> + VernacDeclareModule (export, id, bl, mty_o) + (* Section beginning *) + | IDENT "Section"; id = identref -> VernacBeginSection id + | IDENT "Chapter"; id = identref -> VernacBeginSection id + + (* This end a Section a Module or a Module Type *) + | IDENT "End"; id = identref -> 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 = ne_string -> + VernacRequireFrom (export, specif, filename) + | IDENT "Import"; qidl = LIST1 global -> VernacImport (false,qidl) + | IDENT "Export"; qidl = LIST1 global -> VernacImport (true,qidl) ] ] ; - module_binders: - [ [ "["; bl = LIST1 module_vardecls SEP ";"; "]" -> bl ] ] + export_token: + [ [ IDENT "Import" -> Some false + | IDENT "Export" -> Some true + | -> None ] ] ; - module_binders_list: - [ [ bls = LIST0 module_binders -> List.flatten bls ] ] + specif_token: + [ [ IDENT "Implementation" -> Some false + | IDENT "Specification" -> Some true + | -> None ] ] ; of_module_type: - [ [ ":"; mty = Module.module_type -> (mty, true) - | "<:"; mty = Module.module_type -> (mty, false) ] ] + [ [ ":"; mty = module_type -> (mty, true) + | "<:"; mty = module_type -> (mty, false) ] ] ; is_module_type: - [ [ ":="; mty = Module.module_type -> mty ] ] + [ [ ":="; mty = module_type -> mty ] ] ; is_module_expr: - [ [ ":="; mexpr = Module.module_expr -> mexpr ] ] + [ [ ":="; mexpr = module_expr -> mexpr ] ] ; - gallina_ext: - [ [ - (* Interactive module declaration *) - IDENT "Module"; id = identref; - bl = module_binders_list; mty_o = OPT of_module_type; - mexpr_o = OPT is_module_expr -> - VernacDefineModule (id, bl, mty_o, mexpr_o) - - | IDENT "Module"; "Type"; id = identref; - bl = module_binders_list; mty_o = OPT is_module_type -> - VernacDeclareModuleType (id, bl, mty_o) - - | IDENT "Declare"; IDENT "Module"; id = identref; - bl = module_binders_list; mty_o = OPT of_module_type; - mexpr_o = OPT is_module_expr -> - VernacDeclareModule (id, bl, mty_o, mexpr_o) - (* This end a Section a Module or a Module Type *) + (* Module binder *) + module_binder: + [ [ "("; export = export_token; idl = LIST1 identref; ":"; + mty = module_type; ")" -> (export,idl,mty) ] ] + ; - | IDENT "End"; id = identref -> VernacEndSegment id + (* Module expressions *) + module_expr: + [ [ qid = qualid -> CMEident qid + | me1 = module_expr; me2 = module_expr -> CMEapply (me1,me2) + | "("; me = module_expr; ")" -> me +(* ... *) + ] ] + ; + with_declaration: + [ [ "Definition"; fqid = fullyqualid; ":="; c = Constr.lconstr -> + CWith_Definition (fqid,c) + | IDENT "Module"; fqid = fullyqualid; ":="; qid = qualid -> + CWith_Module (fqid,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; -(* Transparent and Opaque *) - | IDENT "Transparent"; l = LIST1 global -> VernacSetOpacity (false, l) + gallina_ext: + [ [ (* Transparent and Opaque *) + IDENT "Transparent"; l = LIST1 global -> VernacSetOpacity (false, l) | IDENT "Opaque"; l = LIST1 global -> VernacSetOpacity (true, l) -(* Canonical structure *) + (* 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 + let s = coerce_global_to_id qid in VernacDefinition - ((Global,CanonicalStructure),(dummy_loc,s),d,Recordobj.add_object_hook) - (* Rem: LOBJECT, OBJCOERCION, LOBJCOERCION have been removed - (they were unused and undocumented) *) + ((Global,false,CanonicalStructure),(dummy_loc,s),d, + (fun _ -> Recordops.declare_canonical_structure)) -(* Coercions *) + (* Coercions *) | IDENT "Coercion"; qid = global; d = def_body -> - let s = Ast.coerce_global_to_id qid in - VernacDefinition ((Global,Coercion),(dummy_loc,s),d,Class.add_coercion_hook) + let s = coerce_global_to_id qid in + VernacDefinition ((Global,false,Coercion),(dummy_loc,s),d,Class.add_coercion_hook) | IDENT "Coercion"; IDENT "Local"; qid = global; d = def_body -> - let s = Ast.coerce_global_to_id qid in - VernacDefinition ((Local,Coercion),(dummy_loc,s),d,Class.add_coercion_hook) + let s = coerce_global_to_id qid in + VernacDefinition ((Local,false,Coercion),(dummy_loc,s),d,Class.add_coercion_hook) | IDENT "Identity"; IDENT "Coercion"; IDENT "Local"; f = identref; ":"; s = class_rawexpr; ">->"; t = class_rawexpr -> VernacIdentityCoercion (Local, f, s, t) @@ -406,114 +426,230 @@ GEXTEND Gram | IDENT "Coercion"; qid = global; ":"; s = class_rawexpr; ">->"; t = class_rawexpr -> VernacCoercion (Global, qid, s, t) - | IDENT "Class"; IDENT "Local"; c = global -> - Pp.warning "Class is obsolete"; VernacNop - | IDENT "Class"; c = global -> - Pp.warning "Class is obsolete"; VernacNop -(* Implicit *) -(* - | IDENT "Syntactic"; "Definition"; id = identref; ":="; c = constr; - n = OPT [ "|"; n = natural -> n ] -> - VernacSyntacticDefinition (id,c,n) -*) - | IDENT "Syntactic"; "Definition"; id = ident; ":="; c = constr; - n = OPT [ "|"; n = natural -> n ] -> - let c = match n with - | Some n -> - let l = list_tabulate (fun _ -> (CHole (loc),None)) n in - CApp (loc,(None,c),l) - | None -> c in - VernacSyntacticDefinition (id,c,false,true) - | IDENT "Implicits"; qid = global; "["; l = LIST0 natural; "]" -> - let l = List.map (fun n -> ExplByPos n) l in - VernacDeclareImplicits (qid,Some l) - | IDENT "Implicits"; qid = global -> VernacDeclareImplicits (qid,None) - - | IDENT "Implicit"; ["Variable"; "Type" | IDENT "Variables"; "Type"]; - idl = LIST1 identref SEP ","; ":"; c = constr -> VernacReserve (idl,c) - - (* 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) - ] ] + (* Implicit *) + | IDENT "Implicit"; IDENT "Arguments"; qid = global; + pos = OPT [ "["; l = LIST0 ident; "]" -> l ] -> + let pos = option_app (List.map (fun id -> ExplByName id)) pos in + VernacDeclareImplicits (qid,pos) + + | IDENT "Implicit"; ["Type" | IDENT "Types"]; + idl = LIST1 identref; ":"; c = lconstr -> VernacReserve (idl,c) ] ] ; END -(* Modules management *) -if !Options.v7 then GEXTEND Gram - GLOBAL: command; + GLOBAL: command check_command class_rawexpr; - export_token: - [ [ IDENT "Import" -> false - | IDENT "Export" -> true - | -> false ] ] - ; - specif_token: - [ [ IDENT "Implementation" -> Some false - | IDENT "Specification" -> Some true - | -> None ] ] - ; command: - [ [ "Load"; verbosely = [ IDENT "Verbose" -> true | -> false ]; - s = [ s = STRING -> s | s = IDENT -> s ] -> + [ [ IDENT "Comments"; l = LIST0 comment -> VernacComments l + + (* System directory *) + | IDENT "Pwd" -> VernacChdir None + | IDENT "Cd" -> VernacChdir None + | IDENT "Cd"; dir = ne_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 = ne_string -> s | s = IDENT -> s ] -> VernacLoad (verbosely, s) -(* | "Compile"; - verbosely = - [ IDENT "Verbose" -> "Verbose" - | -> "" ]; - IDENT "Module"; - only_spec = - [ IDENT "Specification" -> "Specification" - | -> "" ]; - mname = [ s = STRING -> s | s = IDENT -> s ]; - fname = OPT [ s = STRING -> s | s = IDENT -> s ] -> ExtraVernac - let fname = match fname with Some s -> s | None -> mname in - <:ast< (CompileFile ($STR $verbosely) ($STR $only_spec) - ($STR $mname) ($STR $fname))>> -*) - | IDENT "Read"; IDENT "Module"; qidl = LIST1 global -> - VernacRequire (None, None, qidl) - | IDENT "Require"; export = export_token; specif = specif_token; - qidl = LIST1 global -> VernacRequire (Some export, specif, qidl) -(* | IDENT "Require"; export = export_token; specif = specif_token; - id = identref; filename = STRING -> - VernacRequireFrom (export, specif, id, filename) *) - | IDENT "Require"; export = export_token; specif = specif_token; - filename = STRING -> - VernacRequireFrom (Some export, specif, filename) - | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 STRING -> + | IDENT "Declare"; IDENT "ML"; IDENT "Module"; l = LIST1 ne_string -> VernacDeclareMLModule l - | IDENT "Import"; qidl = LIST1 global -> VernacImport (false,qidl) - | IDENT "Export"; qidl = LIST1 global -> VernacImport (true,qidl) - ] -] + + (* Dump of the universe graph - to file or to stdout *) + | IDENT "Dump"; IDENT "Universes"; fopt = OPT ne_string -> + VernacPrint (PrintUniverses fopt) + + | IDENT "Locate"; l = locatable -> VernacLocate l + + (* Managing load paths *) + | IDENT "Add"; IDENT "LoadPath"; dir = ne_string; alias = as_dirpath -> + VernacAddLoadPath (false, dir, alias) + | IDENT "Add"; IDENT "Rec"; IDENT "LoadPath"; dir = ne_string; + alias = as_dirpath -> VernacAddLoadPath (true, dir, alias) + | IDENT "Remove"; IDENT "LoadPath"; dir = ne_string -> + VernacRemoveLoadPath dir + + (* For compatibility *) + | IDENT "AddPath"; dir = ne_string; "as"; alias = as_dirpath -> + VernacAddLoadPath (false, dir, alias) + | IDENT "AddRecPath"; dir = ne_string; "as"; alias = as_dirpath -> + VernacAddLoadPath (true, dir, alias) + | IDENT "DelPath"; dir = ne_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"; IDENT "Module"; "Type"; qid = global -> + VernacPrint (PrintModuleType qid) + | IDENT "Print"; IDENT "Module"; qid = global -> + VernacPrint (PrintModule qid) + | IDENT "Inspect"; n = natural -> VernacPrint (PrintInspect n) + | IDENT "About"; qid = global -> VernacPrint (PrintAbout qid) + + (* 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"; + sl = [ "["; l = LIST1 [ r = global -> SearchRef r + | s = ne_string -> SearchString s ]; "]" -> l + | qid = global -> [SearchRef qid] ]; + l = in_or_out_modules -> + VernacSearch (SearchAbout sl, l) + + | IDENT "Add"; IDENT "ML"; IDENT "Path"; dir = ne_string -> + VernacAddMLPath (false, dir) + | IDENT "Add"; IDENT "Rec"; IDENT "ML"; IDENT "Path"; dir = ne_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) ] ] ; -END + 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"; ent = IDENT -> + (* This should be in "syntax" section but is here for factorization*) + PrintGrammar ("", ent) + | IDENT "LoadPath" -> PrintLoadPath + | IDENT "Modules" -> PrintModules -if !Options.v7 then -GEXTEND Gram - GLOBAL: command; + | IDENT "ML"; IDENT "Path" -> PrintMLLoadPath + | IDENT "ML"; IDENT "Modules" -> PrintMLModules + | IDENT "Graph" -> PrintGraph + | IDENT "Classes" -> PrintClasses + | IDENT "Ltac"; qid = global -> PrintLtac qid + | IDENT "Coercions" -> PrintCoercions + | IDENT "Coercion"; IDENT "Paths"; s = class_rawexpr; t = class_rawexpr + -> PrintCoercionPaths (s,t) + | IDENT "Canonical"; IDENT "Projections" -> PrintCanonicalConversions + | IDENT "Tables" -> PrintTables +(* Obsolete: was used for cooking V6.3 recipes ?? + | IDENT "Proof"; qid = global -> PrintOpaqueName qid +*) + | IDENT "Hint" -> PrintHintGoal + | IDENT "Hint"; qid = global -> PrintHint qid + | IDENT "Hint"; "*" -> PrintHintDb + | IDENT "HintDb"; s = IDENT -> PrintHintDbName s + | "Rewrite"; IDENT "HintDb"; s = IDENT -> PrintRewriteHintDbName s + | IDENT "Setoids" -> PrintSetoids + | IDENT "Scopes" -> PrintScopes + | IDENT "Scope"; s = IDENT -> PrintScope s + | IDENT "Visibility"; s = OPT IDENT -> PrintVisibility s + | IDENT "Implicit"; qid = global -> PrintImplicit qid ] ] + ; + class_rawexpr: + [ [ IDENT "Funclass" -> FunClass + | IDENT "Sortclass" -> SortClass + | qid = global -> RefClass qid ] ] + ; + locatable: + [ [ qid = global -> LocateTerm qid + | IDENT "File"; f = ne_string -> LocateFile f + | IDENT "Library"; qid = global -> LocateLibrary qid + | IDENT "Module"; qid = global -> LocateModule qid + | s = ne_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 "Write"; IDENT "State"; s = ne_string -> VernacWriteState s | IDENT "Restore"; IDENT "State"; s = IDENT -> VernacRestoreState s - | IDENT "Restore"; IDENT "State"; s = STRING -> VernacRestoreState s + | IDENT "Restore"; IDENT "State"; s = ne_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 + | IDENT "BackTo"; n = natural -> VernacBackTo n + | IDENT "Backtrack"; n = natural ; m = natural ; p = natural -> + VernacBacktrack (n,m,p) (* Tactic Debugger *) | IDENT "Debug"; IDENT "On" -> VernacDebug true @@ -522,3 +658,86 @@ GEXTEND Gram ] ]; END ;; + +(* Grammar extensions *) + +GEXTEND Gram + GLOBAL: syntax; + + syntax: + [ [ IDENT "Open"; local = locality; IDENT "Scope"; sc = IDENT -> + VernacOpenCloseScope (local,true,sc) + + | IDENT "Close"; local = locality; IDENT "Scope"; sc = IDENT -> + VernacOpenCloseScope (local,false,sc) + + | IDENT "Delimit"; IDENT "Scope"; sc = IDENT; "with"; key = IDENT -> + VernacDelimiters (sc,key) + + | IDENT "Bind"; IDENT "Scope"; sc = IDENT; "with"; + refl = LIST1 class_rawexpr -> VernacBindScope (sc,refl) + + | IDENT "Arguments"; IDENT "Scope"; qid = global; + "["; scl = LIST0 opt_scope; "]" -> VernacArgumentsScope (qid,scl) + + | IDENT "Infix"; local = locality; + op = ne_string; ":="; p = global; + modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]; + sc = OPT [ ":"; sc = IDENT -> sc ] -> + VernacInfix (local,(op,modl),p,sc) + | IDENT "Notation"; local = locality; id = ident; ":="; c = constr; + b = [ "("; IDENT "only"; IDENT "parsing"; ")" -> true | -> false ] -> + VernacSyntacticDefinition (id,c,local,b) + | IDENT "Notation"; local = locality; s = ne_string; ":="; c = constr; + modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]; + sc = OPT [ ":"; sc = IDENT -> sc ] -> + VernacNotation (local,c,(s,modl),sc) + + | IDENT "Tactic"; IDENT "Notation"; n = tactic_level; + pil = LIST1 production_item; ":="; t = Tactic.tactic + -> VernacTacticNotation (n,pil,t) + + | IDENT "Reserved"; IDENT "Notation"; local = locality; s = ne_string; + l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ] + -> VernacSyntaxExtension (local,(s,l)) + + (* "Print" "Grammar" should be here but is in "command" entry in order + to factorize with other "Print"-based vernac entries *) + ] ] + ; + tactic_level: + [ [ "("; "at"; IDENT "level"; n = natural; ")" -> n | -> 0 ] ] + ; + locality: + [ [ IDENT "Local" -> true | -> false ] ] + ; + level: + [ [ IDENT "level"; n = natural -> NumLevel n + | IDENT "next"; IDENT "level" -> NextLevel ] ] + ; + syntax_modifier: + [ [ x = IDENT; "at"; lev = level -> SetItemLevel ([x],lev) + | x = IDENT; ","; l = LIST1 IDENT SEP ","; "at"; + lev = level -> SetItemLevel (x::l,lev) + | "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 + | IDENT "format"; s = [s = STRING -> (loc,s)] -> SetFormat s ] ] + ; + syntax_extension_type: + [ [ IDENT "ident" -> ETIdent | IDENT "global" -> ETReference + | IDENT "bigint" -> ETBigint + ] ] + ; + opt_scope: + [ [ "_" -> None | sc = IDENT -> Some sc ] ] + ; + production_item: + [ [ s = ne_string -> VTerm s + | nt = IDENT; po = OPT [ "("; p = ident; ")" -> p ] -> + VNonTerm (loc,nt,po) ] ] + ; +END |