aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2002-11-24 23:13:25 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2002-11-24 23:13:25 +0000
commit5c7cd2b0c85470a96b1edb09956ebef8e5d45cfe (patch)
treeb531583709303b92d62dee37571250eb7cde48c7
parentd2b7a94fe0ed982a6dd7ff2c07991c2f1b1a6fc8 (diff)
Utilisation des niveaux de camlp4 pour gérer les niveaux de constr; améliorations diverses de l'affichage; affinement de la syntaxe et des options de Notation; branchement de Syntactic Definition sur Notation
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@3270 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--.depend170
-rw-r--r--.depend.coq2
-rw-r--r--CHANGES9
-rw-r--r--Makefile2
-rw-r--r--contrib/interface/xlate.ml3
-rw-r--r--interp/constrextern.ml187
-rw-r--r--interp/constrextern.mli14
-rw-r--r--interp/constrintern.ml29
-rw-r--r--interp/symbols.ml327
-rw-r--r--interp/symbols.mli105
-rw-r--r--interp/topconstr.ml107
-rw-r--r--interp/topconstr.mli8
-rwxr-xr-xparsing/ast.ml2
-rw-r--r--parsing/egrammar.ml103
-rw-r--r--parsing/egrammar.mli4
-rw-r--r--parsing/esyntax.ml17
-rw-r--r--parsing/extend.ml120
-rw-r--r--parsing/extend.mli25
-rw-r--r--parsing/g_basevernac.ml441
-rw-r--r--parsing/g_cases.ml45
-rw-r--r--parsing/g_constr.ml4153
-rw-r--r--parsing/g_proofs.ml42
-rw-r--r--parsing/g_vernac.ml410
-rw-r--r--parsing/pcoq.ml447
-rw-r--r--parsing/pcoq.mli21
-rw-r--r--parsing/ppconstr.ml49
-rw-r--r--parsing/printer.ml3
-rw-r--r--theories/Reals/Rsyntax.v19
-rw-r--r--theories/ZArith/Zsyntax.v41
-rw-r--r--toplevel/metasyntax.ml437
-rw-r--r--toplevel/vernacentries.ml4
-rw-r--r--toplevel/vernacexpr.ml1
32 files changed, 1266 insertions, 801 deletions
diff --git a/.depend b/.depend
index e44966fc9..ed944c6af 100644
--- a/.depend
+++ b/.depend
@@ -1,6 +1,6 @@
interp/constrextern.cmi: kernel/environ.cmi library/libnames.cmi \
kernel/names.cmi library/nametab.cmi pretyping/pattern.cmi \
- pretyping/rawterm.cmi kernel/sign.cmi kernel/term.cmi \
+ pretyping/rawterm.cmi kernel/sign.cmi interp/symbols.cmi kernel/term.cmi \
pretyping/termops.cmi interp/topconstr.cmi
interp/constrintern.cmi: parsing/coqast.cmi kernel/environ.cmi \
pretyping/evd.cmi library/impargs.cmi library/libnames.cmi \
@@ -429,16 +429,16 @@ interp/constrextern.cmo: pretyping/classops.cmi library/declare.cmi \
pretyping/detyping.cmi kernel/environ.cmi library/impargs.cmi \
kernel/inductive.cmi library/libnames.cmi library/nameops.cmi \
kernel/names.cmi library/nametab.cmi pretyping/pattern.cmi lib/pp.cmi \
- pretyping/rawterm.cmi pretyping/reductionops.cmi kernel/sign.cmi \
- kernel/term.cmi pretyping/termops.cmi interp/topconstr.cmi \
- kernel/univ.cmi lib/util.cmi interp/constrextern.cmi
+ pretyping/rawterm.cmi kernel/sign.cmi interp/symbols.cmi kernel/term.cmi \
+ pretyping/termops.cmi interp/topconstr.cmi kernel/univ.cmi lib/util.cmi \
+ interp/constrextern.cmi
interp/constrextern.cmx: pretyping/classops.cmx library/declare.cmx \
pretyping/detyping.cmx kernel/environ.cmx library/impargs.cmx \
kernel/inductive.cmx library/libnames.cmx library/nameops.cmx \
kernel/names.cmx library/nametab.cmx pretyping/pattern.cmx lib/pp.cmx \
- pretyping/rawterm.cmx pretyping/reductionops.cmx kernel/sign.cmx \
- kernel/term.cmx pretyping/termops.cmx interp/topconstr.cmx \
- kernel/univ.cmx lib/util.cmx interp/constrextern.cmi
+ pretyping/rawterm.cmx kernel/sign.cmx interp/symbols.cmx kernel/term.cmx \
+ pretyping/termops.cmx interp/topconstr.cmx kernel/univ.cmx lib/util.cmx \
+ interp/constrextern.cmi
interp/constrintern.cmo: library/declare.cmi kernel/environ.cmi \
pretyping/evd.cmi library/global.cmi library/impargs.cmi \
library/libnames.cmi library/nameops.cmi kernel/names.cmi \
@@ -479,14 +479,16 @@ interp/ppextend.cmo: kernel/names.cmi lib/pp.cmi lib/util.cmi \
interp/ppextend.cmi
interp/ppextend.cmx: kernel/names.cmx lib/pp.cmx lib/util.cmx \
interp/ppextend.cmi
-interp/symbols.cmo: lib/bignat.cmi library/lib.cmi library/libnames.cmi \
- library/libobject.cmi kernel/names.cmi library/nametab.cmi \
- lib/options.cmi lib/pp.cmi interp/ppextend.cmi pretyping/rawterm.cmi \
- library/summary.cmi interp/topconstr.cmi lib/util.cmi interp/symbols.cmi
-interp/symbols.cmx: lib/bignat.cmx library/lib.cmx library/libnames.cmx \
- library/libobject.cmx kernel/names.cmx library/nametab.cmx \
- lib/options.cmx lib/pp.cmx interp/ppextend.cmx pretyping/rawterm.cmx \
- library/summary.cmx interp/topconstr.cmx lib/util.cmx interp/symbols.cmi
+interp/symbols.cmo: lib/bignat.cmi lib/gmapl.cmi library/lib.cmi \
+ library/libnames.cmi library/libobject.cmi library/library.cmi \
+ kernel/names.cmi library/nametab.cmi lib/options.cmi lib/pp.cmi \
+ interp/ppextend.cmi pretyping/rawterm.cmi library/summary.cmi \
+ interp/topconstr.cmi lib/util.cmi interp/symbols.cmi
+interp/symbols.cmx: lib/bignat.cmx lib/gmapl.cmx library/lib.cmx \
+ library/libnames.cmx library/libobject.cmx library/library.cmx \
+ kernel/names.cmx library/nametab.cmx lib/options.cmx lib/pp.cmx \
+ interp/ppextend.cmx pretyping/rawterm.cmx library/summary.cmx \
+ interp/topconstr.cmx lib/util.cmx interp/symbols.cmi
interp/syntax_def.cmo: library/lib.cmi library/libnames.cmi \
library/libobject.cmi library/nameops.cmi kernel/names.cmi \
library/nametab.cmi lib/pp.cmi library/summary.cmi interp/topconstr.cmi \
@@ -850,15 +852,15 @@ parsing/g_module.cmo: parsing/ast.cmi parsing/pcoq.cmi lib/pp.cmi \
parsing/g_module.cmx: parsing/ast.cmx parsing/pcoq.cmx lib/pp.cmx \
interp/topconstr.cmx lib/util.cmx
parsing/g_natsyntax.cmo: parsing/ast.cmi lib/bignat.cmi parsing/coqast.cmi \
- interp/coqlib.cmi parsing/esyntax.cmi parsing/extend.cmi \
- library/libnames.cmi kernel/names.cmi lib/options.cmi parsing/pcoq.cmi \
- lib/pp.cmi pretyping/rawterm.cmi interp/symbols.cmi parsing/termast.cmi \
- lib/util.cmi parsing/g_natsyntax.cmi
+ interp/coqlib.cmi parsing/esyntax.cmi library/libnames.cmi \
+ kernel/names.cmi lib/options.cmi lib/pp.cmi pretyping/rawterm.cmi \
+ interp/symbols.cmi parsing/termast.cmi lib/util.cmi \
+ parsing/g_natsyntax.cmi
parsing/g_natsyntax.cmx: parsing/ast.cmx lib/bignat.cmx parsing/coqast.cmx \
- interp/coqlib.cmx parsing/esyntax.cmx parsing/extend.cmx \
- library/libnames.cmx kernel/names.cmx lib/options.cmx parsing/pcoq.cmx \
- lib/pp.cmx pretyping/rawterm.cmx interp/symbols.cmx parsing/termast.cmx \
- lib/util.cmx parsing/g_natsyntax.cmi
+ interp/coqlib.cmx parsing/esyntax.cmx library/libnames.cmx \
+ kernel/names.cmx lib/options.cmx lib/pp.cmx pretyping/rawterm.cmx \
+ interp/symbols.cmx parsing/termast.cmx lib/util.cmx \
+ parsing/g_natsyntax.cmi
parsing/g_prim.cmo: parsing/coqast.cmi library/libnames.cmi kernel/names.cmi \
library/nametab.cmi parsing/pcoq.cmi interp/topconstr.cmi
parsing/g_prim.cmx: parsing/coqast.cmx library/libnames.cmx kernel/names.cmx \
@@ -871,14 +873,14 @@ parsing/g_proofs.cmx: interp/genarg.cmx parsing/pcoq.cmx lib/pp.cmx \
toplevel/vernacexpr.cmx
parsing/g_rsyntax.cmo: parsing/ast.cmi lib/bignat.cmi parsing/coqast.cmi \
parsing/esyntax.cmi parsing/extend.cmi library/libnames.cmi \
- library/library.cmi kernel/names.cmi library/nametab.cmi lib/options.cmi \
- parsing/pcoq.cmi lib/pp.cmi pretyping/rawterm.cmi interp/symbols.cmi \
- parsing/termast.cmi interp/topconstr.cmi lib/util.cmi
+ kernel/names.cmi library/nametab.cmi lib/options.cmi parsing/pcoq.cmi \
+ lib/pp.cmi pretyping/rawterm.cmi interp/symbols.cmi parsing/termast.cmi \
+ interp/topconstr.cmi lib/util.cmi
parsing/g_rsyntax.cmx: parsing/ast.cmx lib/bignat.cmx parsing/coqast.cmx \
parsing/esyntax.cmx parsing/extend.cmx library/libnames.cmx \
- library/library.cmx kernel/names.cmx library/nametab.cmx lib/options.cmx \
- parsing/pcoq.cmx lib/pp.cmx pretyping/rawterm.cmx interp/symbols.cmx \
- parsing/termast.cmx interp/topconstr.cmx lib/util.cmx
+ kernel/names.cmx library/nametab.cmx lib/options.cmx parsing/pcoq.cmx \
+ lib/pp.cmx pretyping/rawterm.cmx interp/symbols.cmx parsing/termast.cmx \
+ interp/topconstr.cmx lib/util.cmx
parsing/g_tactic.cmo: parsing/ast.cmi interp/genarg.cmi kernel/names.cmi \
parsing/pcoq.cmi lib/pp.cmi pretyping/rawterm.cmi proofs/tacexpr.cmo \
interp/topconstr.cmi lib/util.cmi
@@ -897,13 +899,13 @@ parsing/g_vernac.cmx: parsing/ast.cmx toplevel/class.cmx \
toplevel/vernacexpr.cmx
parsing/g_zsyntax.cmo: parsing/ast.cmi lib/bignat.cmi parsing/coqast.cmi \
parsing/esyntax.cmi parsing/extend.cmi library/libnames.cmi \
- library/library.cmi kernel/names.cmi library/nametab.cmi parsing/pcoq.cmi \
- lib/pp.cmi pretyping/rawterm.cmi interp/symbols.cmi parsing/termast.cmi \
+ kernel/names.cmi library/nametab.cmi parsing/pcoq.cmi lib/pp.cmi \
+ pretyping/rawterm.cmi interp/symbols.cmi parsing/termast.cmi \
interp/topconstr.cmi lib/util.cmi parsing/g_zsyntax.cmi
parsing/g_zsyntax.cmx: parsing/ast.cmx lib/bignat.cmx parsing/coqast.cmx \
parsing/esyntax.cmx parsing/extend.cmx library/libnames.cmx \
- library/library.cmx kernel/names.cmx library/nametab.cmx parsing/pcoq.cmx \
- lib/pp.cmx pretyping/rawterm.cmx interp/symbols.cmx parsing/termast.cmx \
+ kernel/names.cmx library/nametab.cmx parsing/pcoq.cmx lib/pp.cmx \
+ pretyping/rawterm.cmx interp/symbols.cmx parsing/termast.cmx \
interp/topconstr.cmx lib/util.cmx parsing/g_zsyntax.cmi
parsing/lexer.cmo: parsing/lexer.cmi
parsing/lexer.cmx: parsing/lexer.cmi
@@ -917,17 +919,17 @@ parsing/pcoq.cmx: parsing/ast.cmx parsing/coqast.cmx library/decl_kinds.cmx \
library/libnames.cmx kernel/names.cmx lib/options.cmx lib/pp.cmx \
pretyping/rawterm.cmx proofs/tacexpr.cmx interp/topconstr.cmx \
lib/util.cmx parsing/pcoq.cmi
-parsing/ppconstr.cmo: parsing/ast.cmi lib/bignat.cmi parsing/coqast.cmi \
- lib/dyn.cmi parsing/esyntax.cmi interp/genarg.cmi library/libnames.cmi \
- library/nameops.cmi kernel/names.cmi library/nametab.cmi lib/pp.cmi \
- interp/ppextend.cmi pretyping/rawterm.cmi interp/symbols.cmi \
- kernel/term.cmi parsing/termast.cmi interp/topconstr.cmi lib/util.cmi \
+parsing/ppconstr.cmo: parsing/ast.cmi lib/bignat.cmi interp/constrextern.cmi \
+ parsing/coqast.cmi lib/dyn.cmi parsing/esyntax.cmi interp/genarg.cmi \
+ library/libnames.cmi library/nameops.cmi kernel/names.cmi \
+ library/nametab.cmi lib/pp.cmi interp/ppextend.cmi pretyping/rawterm.cmi \
+ interp/symbols.cmi kernel/term.cmi interp/topconstr.cmi lib/util.cmi \
parsing/ppconstr.cmi
-parsing/ppconstr.cmx: parsing/ast.cmx lib/bignat.cmx parsing/coqast.cmx \
- lib/dyn.cmx parsing/esyntax.cmx interp/genarg.cmx library/libnames.cmx \
- library/nameops.cmx kernel/names.cmx library/nametab.cmx lib/pp.cmx \
- interp/ppextend.cmx pretyping/rawterm.cmx interp/symbols.cmx \
- kernel/term.cmx parsing/termast.cmx interp/topconstr.cmx lib/util.cmx \
+parsing/ppconstr.cmx: parsing/ast.cmx lib/bignat.cmx interp/constrextern.cmx \
+ parsing/coqast.cmx lib/dyn.cmx parsing/esyntax.cmx interp/genarg.cmx \
+ library/libnames.cmx library/nameops.cmx kernel/names.cmx \
+ library/nametab.cmx lib/pp.cmx interp/ppextend.cmx pretyping/rawterm.cmx \
+ interp/symbols.cmx kernel/term.cmx interp/topconstr.cmx lib/util.cmx \
parsing/ppconstr.cmi
parsing/pptactic.cmo: kernel/closure.cmi lib/dyn.cmi parsing/egrammar.cmi \
parsing/extend.cmi interp/genarg.cmi library/libnames.cmi \
@@ -957,20 +959,20 @@ parsing/prettyp.cmx: pretyping/classops.cmx kernel/declarations.cmx \
parsing/printmod.cmx kernel/reduction.cmx kernel/safe_typing.cmx \
kernel/sign.cmx interp/syntax_def.cmx kernel/term.cmx \
pretyping/termops.cmx lib/util.cmx parsing/prettyp.cmi
-parsing/printer.cmo: parsing/ast.cmi parsing/coqast.cmi library/declare.cmi \
- kernel/environ.cmi parsing/extend.cmi library/global.cmi \
- library/libnames.cmi library/nameops.cmi kernel/names.cmi \
- library/nametab.cmi lib/options.cmi pretyping/pattern.cmi lib/pp.cmi \
- parsing/ppconstr.cmi interp/ppextend.cmi kernel/sign.cmi kernel/term.cmi \
- parsing/termast.cmi pretyping/termops.cmi lib/util.cmi \
- parsing/printer.cmi
-parsing/printer.cmx: parsing/ast.cmx parsing/coqast.cmx library/declare.cmx \
- kernel/environ.cmx parsing/extend.cmx library/global.cmx \
- library/libnames.cmx library/nameops.cmx kernel/names.cmx \
- library/nametab.cmx lib/options.cmx pretyping/pattern.cmx lib/pp.cmx \
- parsing/ppconstr.cmx interp/ppextend.cmx kernel/sign.cmx kernel/term.cmx \
- parsing/termast.cmx pretyping/termops.cmx lib/util.cmx \
- parsing/printer.cmi
+parsing/printer.cmo: parsing/ast.cmi interp/constrextern.cmi \
+ parsing/coqast.cmi library/declare.cmi kernel/environ.cmi \
+ parsing/extend.cmi library/global.cmi library/libnames.cmi \
+ library/nameops.cmi kernel/names.cmi library/nametab.cmi lib/options.cmi \
+ pretyping/pattern.cmi lib/pp.cmi parsing/ppconstr.cmi interp/ppextend.cmi \
+ kernel/sign.cmi kernel/term.cmi parsing/termast.cmi pretyping/termops.cmi \
+ lib/util.cmi parsing/printer.cmi
+parsing/printer.cmx: parsing/ast.cmx interp/constrextern.cmx \
+ parsing/coqast.cmx library/declare.cmx kernel/environ.cmx \
+ parsing/extend.cmx library/global.cmx library/libnames.cmx \
+ library/nameops.cmx kernel/names.cmx library/nametab.cmx lib/options.cmx \
+ pretyping/pattern.cmx lib/pp.cmx parsing/ppconstr.cmx interp/ppextend.cmx \
+ kernel/sign.cmx kernel/term.cmx parsing/termast.cmx pretyping/termops.cmx \
+ lib/util.cmx parsing/printer.cmi
parsing/printmod.cmo: kernel/declarations.cmi library/global.cmi \
library/libnames.cmi library/nameops.cmi kernel/names.cmi \
library/nametab.cmi lib/pp.cmi lib/util.cmi parsing/printmod.cmi
@@ -1962,38 +1964,40 @@ toplevel/vernac.cmx: parsing/coqast.cmx library/lib.cmx library/library.cmx \
library/states.cmx lib/system.cmx lib/util.cmx toplevel/vernacentries.cmx \
toplevel/vernacexpr.cmx toplevel/vernacinterp.cmx toplevel/vernac.cmi
toplevel/vernacentries.cmo: tactics/auto.cmi toplevel/class.cmi \
- pretyping/classops.cmi toplevel/command.cmi interp/constrintern.cmi \
- library/decl_kinds.cmo library/declaremods.cmi tactics/dhyp.cmi \
- toplevel/discharge.cmi kernel/entries.cmi kernel/environ.cmi \
- pretyping/evarutil.cmi pretyping/evd.cmi library/global.cmi \
- library/goptions.cmi library/impargs.cmi pretyping/inductiveops.cmi \
- library/lib.cmi library/libnames.cmi library/library.cmi \
- toplevel/metasyntax.cmi toplevel/mltop.cmi interp/modintern.cmi \
- library/nameops.cmi kernel/names.cmi library/nametab.cmi lib/options.cmi \
- proofs/pfedit.cmi lib/pp.cmi lib/pp_control.cmi parsing/prettyp.cmi \
- pretyping/pretyping.cmi parsing/printer.cmi parsing/printmod.cmi \
- proofs/proof_trees.cmi proofs/proof_type.cmi toplevel/record.cmi \
- toplevel/recordobj.cmi proofs/refiner.cmi kernel/safe_typing.cmi \
- parsing/search.cmi library/states.cmi interp/symbols.cmi lib/system.cmi \
+ pretyping/classops.cmi toplevel/command.cmi interp/constrextern.cmi \
+ interp/constrintern.cmi library/decl_kinds.cmo library/declaremods.cmi \
+ tactics/dhyp.cmi toplevel/discharge.cmi kernel/entries.cmi \
+ kernel/environ.cmi pretyping/evarutil.cmi pretyping/evd.cmi \
+ library/global.cmi library/goptions.cmi library/impargs.cmi \
+ pretyping/inductiveops.cmi library/lib.cmi library/libnames.cmi \
+ library/library.cmi toplevel/metasyntax.cmi toplevel/mltop.cmi \
+ interp/modintern.cmi library/nameops.cmi kernel/names.cmi \
+ library/nametab.cmi lib/options.cmi proofs/pfedit.cmi lib/pp.cmi \
+ lib/pp_control.cmi parsing/prettyp.cmi pretyping/pretyping.cmi \
+ parsing/printer.cmi parsing/printmod.cmi proofs/proof_trees.cmi \
+ proofs/proof_type.cmi toplevel/record.cmi toplevel/recordobj.cmi \
+ proofs/refiner.cmi kernel/safe_typing.cmi parsing/search.cmi \
+ library/states.cmi interp/symbols.cmi lib/system.cmi \
tactics/tacinterp.cmi proofs/tacmach.cmi pretyping/tacred.cmi \
proofs/tactic_debug.cmi tactics/tactics.cmi kernel/term.cmi \
parsing/termast.cmi interp/topconstr.cmi kernel/typeops.cmi \
kernel/univ.cmi lib/util.cmi toplevel/vernacexpr.cmo \
toplevel/vernacinterp.cmi toplevel/vernacentries.cmi
toplevel/vernacentries.cmx: tactics/auto.cmx toplevel/class.cmx \
- pretyping/classops.cmx toplevel/command.cmx interp/constrintern.cmx \
- library/decl_kinds.cmx library/declaremods.cmx tactics/dhyp.cmx \
- toplevel/discharge.cmx kernel/entries.cmx kernel/environ.cmx \
- pretyping/evarutil.cmx pretyping/evd.cmx library/global.cmx \
- library/goptions.cmx library/impargs.cmx pretyping/inductiveops.cmx \
- library/lib.cmx library/libnames.cmx library/library.cmx \
- toplevel/metasyntax.cmx toplevel/mltop.cmx interp/modintern.cmx \
- library/nameops.cmx kernel/names.cmx library/nametab.cmx lib/options.cmx \
- proofs/pfedit.cmx lib/pp.cmx lib/pp_control.cmx parsing/prettyp.cmx \
- pretyping/pretyping.cmx parsing/printer.cmx parsing/printmod.cmx \
- proofs/proof_trees.cmx proofs/proof_type.cmx toplevel/record.cmx \
- toplevel/recordobj.cmx proofs/refiner.cmx kernel/safe_typing.cmx \
- parsing/search.cmx library/states.cmx interp/symbols.cmx lib/system.cmx \
+ pretyping/classops.cmx toplevel/command.cmx interp/constrextern.cmx \
+ interp/constrintern.cmx library/decl_kinds.cmx library/declaremods.cmx \
+ tactics/dhyp.cmx toplevel/discharge.cmx kernel/entries.cmx \
+ kernel/environ.cmx pretyping/evarutil.cmx pretyping/evd.cmx \
+ library/global.cmx library/goptions.cmx library/impargs.cmx \
+ pretyping/inductiveops.cmx library/lib.cmx library/libnames.cmx \
+ library/library.cmx toplevel/metasyntax.cmx toplevel/mltop.cmx \
+ interp/modintern.cmx library/nameops.cmx kernel/names.cmx \
+ library/nametab.cmx lib/options.cmx proofs/pfedit.cmx lib/pp.cmx \
+ lib/pp_control.cmx parsing/prettyp.cmx pretyping/pretyping.cmx \
+ parsing/printer.cmx parsing/printmod.cmx proofs/proof_trees.cmx \
+ proofs/proof_type.cmx toplevel/record.cmx toplevel/recordobj.cmx \
+ proofs/refiner.cmx kernel/safe_typing.cmx parsing/search.cmx \
+ library/states.cmx interp/symbols.cmx lib/system.cmx \
tactics/tacinterp.cmx proofs/tacmach.cmx pretyping/tacred.cmx \
proofs/tactic_debug.cmx tactics/tactics.cmx kernel/term.cmx \
parsing/termast.cmx interp/topconstr.cmx kernel/typeops.cmx \
diff --git a/.depend.coq b/.depend.coq
index 8be4567ff..6f6be0579 100644
--- a/.depend.coq
+++ b/.depend.coq
@@ -5,7 +5,7 @@ theories/Init/PeanoSyntax.vo: theories/Init/PeanoSyntax.v theories/Init/Datatype
theories/Init/Logic.vo: theories/Init/Logic.v theories/Init/Datatypes.vo
theories/Init/Specif.vo: theories/Init/Specif.v theories/Init/Datatypes.vo theories/Init/Logic.vo theories/Init/LogicSyntax.vo
theories/Init/LogicSyntax.vo: theories/Init/LogicSyntax.v theories/Init/Logic.vo
-theories/Init/SpecifSyntax.vo: theories/Init/SpecifSyntax.v theories/Init/Datatypes.vo theories/Init/LogicSyntax.vo theories/Init/Specif.vo
+theories/Init/SpecifSyntax.vo: theories/Init/SpecifSyntax.v theories/Init/DatatypesSyntax.vo theories/Init/Specif.vo
theories/Init/Logic_Type.vo: theories/Init/Logic_Type.v theories/Init/Logic.vo theories/Init/LogicSyntax.vo
theories/Init/Wf.vo: theories/Init/Wf.v theories/Init/Logic.vo theories/Init/LogicSyntax.vo
theories/Init/Logic_TypeSyntax.vo: theories/Init/Logic_TypeSyntax.v theories/Init/Logic_Type.vo
diff --git a/CHANGES b/CHANGES
index 5be095ab8..e3393dc6e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -14,6 +14,8 @@ Symbolic notations
- Introduction of a notion of scope gathering notations in a consistent set;
set a notation sets has been developped for nat, Z and R
+- New command "Notation" for declaring notations simultaneously for
+ parsing and printing
- Declarations with only implicit arguments now handled (e.g. the
argument of nil can be set implicit; use !nil to refer to nil
without arguments)
@@ -25,6 +27,10 @@ Library
- Lemmas in Set from Compare_dec.v (le_lt_dec, ...) and Wf_nat.v
(lt_wf_rec, ...) are now transparent. This may be source of
incompatibilities.
+- Syntactic Definitions Fst, Snd, Ex, All, Ex2, AllT, ExT, ExT2,
+ ProjS1, ProjS2, Error, Value and Except are turned to
+ notations. They now must be applied (incompatibilities only in
+ unrealistic cases).
Language
@@ -74,10 +80,13 @@ Tactics
hypothesis was unfolded to `x < y` -> False. This is fixed. In addition,
it can also recognize 'False' in the hypothesis and use it to solve the
goal.
+- New syntax for Ring and Field when arguments are provided (use "Ring on" and
+ "Field on")
Miscellaneous
- Printing Coercion now used through the standard keywords Set/Add, Test, Print
+- "Print Term id" is an alias for "Print id"
Incompatibilities
diff --git a/Makefile b/Makefile
index 2c492ed75..5bdbe1043 100644
--- a/Makefile
+++ b/Makefile
@@ -230,7 +230,7 @@ PARSERREQUIRES=config/coq_config.cmo lib/pp_control.cmo lib/pp.cmo \
interp/constrintern.cmo interp/coqlib.cmo \
parsing/pcoq.cmo parsing/ast.cmo \
parsing/extend.cmo pretyping/detyping.cmo \
- parsing/termast.cmo interp/modintern.cmo \
+ parsing/termast.cmo interp/modintern.cmo interp/constrextern.cmo\
parsing/g_prim.cmo parsing/g_basevernac.cmo \
parsing/egrammar.cmo parsing/esyntax.cmo toplevel/metasyntax.cmo \
parsing/ppconstr.cmo parsing/printer.cmo parsing/pptactic.cmo \
diff --git a/contrib/interface/xlate.ml b/contrib/interface/xlate.ml
index 6bcc2433d..57e7189a7 100644
--- a/contrib/interface/xlate.ml
+++ b/contrib/interface/xlate.ml
@@ -1789,7 +1789,8 @@ let xlate_vernac =
| PrintLocalContext -> xlate_error "TODO: Print"
| PrintTables -> xlate_error "TODO: Print Tables"
| PrintModuleType _ -> xlate_error "TODO: Print Module Type"
- | PrintModule _ -> xlate_error "TODO: Print Module")
+ | PrintModule _ -> xlate_error "TODO: Print Module"
+ | PrintScope _ -> xlate_error "TODO: Print Scope")
| VernacBeginSection id ->
CT_coerce_SECTION_BEGIN_to_COMMAND (CT_section (xlate_ident id))
| VernacEndSegment id -> CT_section_end (xlate_ident id)
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 0ae4c2214..c813cf71d 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -39,9 +39,6 @@ let print_arguments = ref false
(* If true, prints local context of evars, whatever print_arguments *)
let print_evar_arguments = ref false
-(* This forces printing of cast nodes *)
-let print_casts = ref true
-
(* This governs printing of implicit arguments. When
[print_implicits] is on then [print_implicits_explicit_args] tells
how implicit args are printed. If on, implicit args are printed
@@ -56,6 +53,8 @@ let print_coercions = ref false
(* This forces printing universe names of Type{.} *)
let print_universes = ref false
+(* This suppresses printing of numeral and symbols *)
+let print_no_symbol = ref false
let with_option o f x =
let old = !o in o:=true;
@@ -63,10 +62,23 @@ let with_option o f x =
with e -> o := old; raise e
let with_arguments f = with_option print_arguments f
-let with_casts f = with_option print_casts f
let with_implicits f = with_option print_implicits f
let with_coercions f = with_option print_coercions f
let with_universes f = with_option print_universes f
+let without_symbols f = with_option print_no_symbol f
+
+(**********************************************************************)
+(* Various externalisation functions *)
+
+let insert_delimiters e = function
+ | None -> e
+ | Some sc -> CDelimiters (dummy_loc,sc,e)
+
+let insert_pat_delimiters e = function
+ | None -> e
+ | Some sc -> CPatDelimiters (dummy_loc,sc,e)
+
+let loc = dummy_loc (* shorter... *)
(**********************************************************************)
(* conversion of references *)
@@ -90,13 +102,21 @@ let extern_evar loc n = warning "No notation for Meta"; CMeta (loc,n)
let extern_ref r = Qualid (dummy_loc,shortest_qualid_of_global None r)
(**********************************************************************)
-(* conversion of patterns *)
-
-let rec extern_cases_pattern = function (* loc is thrown away for printing *)
- | PatVar (loc,Name id) -> CPatAtom (loc,Some (Ident (loc,id)))
- | PatVar (loc,Anonymous) -> CPatAtom (loc, None)
- | PatCstr(loc,cstrsp,args,na) ->
- let args = List.map extern_cases_pattern args in
+(* conversion of terms and cases patterns *)
+
+let rec extern_cases_pattern_in_scope scopes pat =
+ try
+ if !print_no_symbol then raise No_match;
+ let (sc,n) = Symbols.uninterp_cases_numeral pat in
+ match Symbols.availability_of_numeral sc scopes with
+ | None -> raise No_match
+ | Some scopt -> insert_pat_delimiters (CPatNumeral (loc,n)) scopt
+ with No_match ->
+ match pat with
+ | PatVar (_,Name id) -> CPatAtom (loc,Some (Ident (loc,id)))
+ | PatVar (_,Anonymous) -> CPatAtom (loc, None)
+ | PatCstr(_,cstrsp,args,na) ->
+ let args = List.map (extern_cases_pattern_in_scope scopes) args in
let p = CPatCstr (loc,extern_ref (ConstructRef cstrsp),args) in
(match na with
| Name id -> CPatAlias (loc,p,id)
@@ -140,14 +160,31 @@ let rec skip_coercion dest_ref (f,args as app) =
with Not_found -> app
let extern_app impl f args =
- if !print_implicits & not !print_implicits_explicit_args then
+ if (!print_implicits & not !print_implicits_explicit_args) then
CAppExpl (dummy_loc, f, args)
else
explicitize impl (CRef f) args
-let loc = dummy_loc
+let rec extern_args extern scopes args subscopes =
+ match args with
+ | [] -> []
+ | a::args ->
+ let argscopes, subscopes = match subscopes with
+ | [] -> scopes, []
+ | scopt::subscopes -> option_cons scopt scopes, subscopes in
+ extern argscopes a :: extern_args extern scopes args subscopes
+
+let rec extern scopes r =
+ try
+ if !print_no_symbol then raise No_match;
+ extern_numeral scopes r (Symbols.uninterp_numeral r)
+ with No_match ->
+
+ try
+ if !print_no_symbol then raise No_match;
+ extern_symbol scopes r (Symbols.uninterp_notations r)
+ with No_match -> match r with
-let rec extern = function
| RRef (_,ref) -> CRef (extern_ref ref)
| RVar (_,id) -> CRef (Ident (loc,id))
@@ -159,51 +196,55 @@ let rec extern = function
| RApp (_,f,args) ->
let (f,args) =
skip_coercion (function RRef(_,r) -> Some r | _ -> None) (f,args) in
- let args = List.map extern args in
(match f with
| REvar (loc,ev) -> extern_evar loc ev (* we drop args *)
| RRef (loc,ref) ->
+ let subscopes = Symbols.find_arguments_scope ref in
+ let args = extern_args extern scopes args subscopes in
extern_app (implicits_of_global ref) (extern_ref ref) args
- | _ -> explicitize [] (extern f) args)
+ | _ ->
+ explicitize [] (extern scopes f) (List.map (extern scopes) args))
| RProd (_,Anonymous,t,c) ->
(* Anonymous product are never factorized *)
- CArrow (loc,extern t,extern c)
+ CArrow (loc,extern scopes t,extern scopes c)
| RLetIn (_,na,t,c) ->
- CLetIn (loc,(loc,na),extern t,extern c)
+ CLetIn (loc,(loc,na),extern scopes t,extern scopes c)
| RProd (_,na,t,c) ->
- let t = extern t in
- let (idl,c) = factorize_prod t c in
+ let t = extern scopes t in
+ let (idl,c) = factorize_prod scopes t c in
CProdN (loc,[(loc,na)::idl,t],c)
| RLambda (_,na,t,c) ->
- let t = extern t in
- let (idl,c) = factorize_lambda t c in
+ let t = extern scopes t in
+ let (idl,c) = factorize_lambda scopes t c in
CLambdaN (loc,[(loc,na)::idl,t],c)
| RCases (_,typopt,tml,eqns) ->
- let pred = option_app extern typopt in
- let tml = List.map extern tml in
- let eqns = List.map extern_eqn eqns in
+ let pred = option_app (extern scopes) typopt in
+ let tml = List.map (extern scopes) tml in
+ let eqns = List.map (extern_eqn scopes) eqns in
CCases (loc,pred,tml,eqns)
| ROrderedCase (_,cs,typopt,tm,bv) ->
- let bv = Array.to_list (Array.map extern bv) in
- COrderedCase (loc,cs,option_app extern typopt,extern tm,bv)
+ let bv = Array.to_list (Array.map (extern scopes) bv) in
+ COrderedCase
+ (loc,cs,option_app (extern scopes) typopt,extern scopes tm,bv)
| RRec (_,fk,idv,tyv,bv) ->
(match fk with
| RFix (nv,n) ->
let listdecl =
- Array.mapi
- (fun i fi -> (fi,nv.(i),extern tyv.(i),extern bv.(i))) idv
+ Array.mapi (fun i fi ->
+ (fi,nv.(i),extern scopes tyv.(i),extern scopes bv.(i))) idv
in
CFix (loc,(loc,idv.(n)),Array.to_list listdecl)
| RCoFix n ->
let listdecl =
- Array.mapi (fun i fi -> (fi,extern tyv.(i),extern bv.(i))) idv
+ Array.mapi (fun i fi ->
+ (fi,extern scopes tyv.(i),extern scopes bv.(i))) idv
in
CCoFix (loc,(loc,idv.(n)),Array.to_list listdecl))
@@ -216,46 +257,71 @@ let rec extern = function
| RHole (_,e) -> CHole loc
- | RCast (_,c,t) -> CCast (loc,extern c,extern t)
+ | RCast (_,c,t) -> CCast (loc,extern scopes c,extern scopes t)
| RDynamic (_,d) -> CDynamic (loc,d)
-and factorize_prod aty = function
+and factorize_prod scopes aty = function
| RProd (_,Name id,ty,c)
- when aty = extern ty
- & not (occur_var_constr_expr id aty) (*To avoid na in ty escapes scope*)
- -> let (nal,c) = factorize_prod aty c in ((loc,Name id)::nal,c)
- | c -> ([],extern c)
+ when aty = extern scopes ty
+ & not (occur_var_constr_expr id aty) (* avoid na in ty escapes scope *)
+ -> let (nal,c) = factorize_prod scopes aty c in ((loc,Name id)::nal,c)
+ | c -> ([],extern scopes c)
-and factorize_lambda aty = function
+and factorize_lambda scopes aty = function
| RLambda (_,na,ty,c)
- when aty = extern ty
+ when aty = extern scopes ty
& not (occur_name na aty) (* To avoid na in ty' escapes scope *)
- -> let (nal,c) = factorize_lambda aty c in ((loc,na)::nal,c)
- | c -> ([],extern c)
-
-and extern_eqn (loc,ids,pl,c) =
- (loc,List.map extern_cases_pattern pl,extern c)
-(*
-and extern_numerals r =
- on_numeral (fun p ->
- match filter p r with
- | Some f
-
-and extern_symbols r =
-*)
-
-let extern_rawconstr = extern
+ -> let (nal,c) = factorize_lambda scopes aty c in ((loc,na)::nal,c)
+ | c -> ([],extern scopes c)
+
+and extern_eqn scopes (loc,ids,pl,c) =
+ (loc,List.map (extern_cases_pattern_in_scope scopes) pl,extern scopes c)
+
+and extern_numeral scopes t (sc,n) =
+ match Symbols.availability_of_numeral sc scopes with
+ | None -> raise No_match
+ | Some scopt -> insert_delimiters (CNumeral (loc,n)) scopt
+
+and extern_symbol scopes t = function
+ | [] -> raise No_match
+ | (sc,ntn,pat,n as rule)::rules ->
+ try
+ (* Adjusts to the number of arguments expected by the notation *)
+ let (t,args) = match t,n with
+ | RApp (_,f,args), Some n when List.length args > n ->
+ let args1, args2 = list_chop n args in
+ RApp (loc,f,args1), args2
+ | _ -> t,[] in
+ (* Try matching ... *)
+ let subst = match_aconstr t pat in
+ (* Try availability of interpretation ... *)
+ (match Symbols.availability_of_notation (sc,ntn) scopes with
+ (* Uninterpretation is not allowed in current context *)
+ | None -> raise No_match
+ (* Uninterpretation is allowed in current context *)
+ | Some scopt ->
+ let scopes = option_cons scopt scopes in
+ let l = List.map (fun (id,c) -> (id,extern scopes c)) subst in
+ let e = insert_delimiters (CNotation (loc,ntn,l)) scopt in
+ if args = [] then e
+ else explicitize [] e (List.map (extern scopes) args))
+ with
+ No_match -> extern_symbol scopes t rules
+
+let extern_rawconstr =
+ extern (Symbols.current_scopes())
+
+let extern_cases_pattern =
+ extern_cases_pattern_in_scope (Symbols.current_scopes())
(******************************************************************)
(* Main translation function from constr -> constr_expr *)
let extern_constr at_top env t =
- let t' =
- if !print_casts then t
- else Reductionops.local_strong strip_outer_cast t in
let avoid = if at_top then ids_of_context env else [] in
- extern (Detyping.detype env avoid (names_of_rel_context env) t')
+ extern (Symbols.current_scopes())
+ (Detyping.detype env avoid (names_of_rel_context env) t)
(******************************************************************)
(* Main translation function from pattern -> constr_expr *)
@@ -319,9 +385,12 @@ let rec extern_pattern tenv env = function
(loc,cs,option_app (extern_pattern tenv env) typopt,
extern_pattern tenv env tm,bv)
- | PFix f -> extern (Detyping.detype tenv [] env (mkFix f))
+ | PFix f ->
+ extern (Symbols.current_scopes()) (Detyping.detype tenv [] env (mkFix f))
- | PCoFix c -> extern (Detyping.detype tenv [] env (mkCoFix c))
+ | PCoFix c ->
+ extern (Symbols.current_scopes())
+ (Detyping.detype tenv [] env (mkCoFix c))
| PSort s ->
let s = match s with
diff --git a/interp/constrextern.mli b/interp/constrextern.mli
index cfa00c006..614cbfdd4 100644
--- a/interp/constrextern.mli
+++ b/interp/constrextern.mli
@@ -19,6 +19,7 @@ open Nametab
open Rawterm
open Pattern
open Topconstr
+open Symbols
(*i*)
(* Translation of pattern, cases pattern, rawterm and term into syntax
@@ -36,14 +37,23 @@ val extern_ref : global_reference -> reference
(* For debugging *)
val print_implicits : bool ref
-val print_casts : bool ref
val print_arguments : bool ref
val print_evar_arguments : bool ref
val print_coercions : bool ref
val print_universes : bool ref
-val with_casts : ('a -> 'b) -> 'a -> 'b
+(* This governs printing of implicit arguments. If [with_implicits] is
+ on and not [with_arguments] then implicit args are printed prefixed
+ by "!"; if [with_implicits] and [with_arguments] are both on the
+ function and not the arguments is prefixed by "!" *)
val with_implicits : ('a -> 'b) -> 'a -> 'b
val with_arguments : ('a -> 'b) -> 'a -> 'b
+
+(* This forces printing of coercions *)
val with_coercions : ('a -> 'b) -> 'a -> 'b
+
+(* This forces printing universe names of Type{.} *)
val with_universes : ('a -> 'b) -> 'a -> 'b
+
+(* This suppresses printing of numeral and symbols *)
+val without_symbols : ('a -> 'b) -> 'a -> 'b
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index e760f3e92..7236335c3 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -117,23 +117,21 @@ let add_glob loc ref =
[vars2] is the set of global variables, env is the set of variables
abstracted until this point *)
-(* Is it a bound variables? *)
let intern_var (env,impls,_) (vars1,vars2) loc id =
+ (* Is [id] bound in *)
+ if Idset.mem id env or List.mem id vars1
+ then
+ RVar (loc,id), (try List.assoc id impls with Not_found -> []), []
+ else
+ (* Is [id] a section variable *)
+ let _ = Sign.lookup_named id vars2 in
+ (* Car Fixpoint met les fns définies temporairement comme vars de sect *)
let imps, args_scopes =
- (* Is [id] bound in *)
- if Idset.mem id env or List.mem id vars1
- then
- try List.assoc id impls, []
- with Not_found -> [], []
- else
- (* Is [id] a section variable *)
- let _ = Sign.lookup_named id vars2 in
- (* Car Fixpoint met les fns définies temporairement comme vars de sect *)
try
let ref = VarRef id in
implicits_of_global ref, find_arguments_scope ref
- with _ -> [], []
- in RVar (loc, id), imps, args_scopes
+ with _ -> [], [] in
+ RRef (loc, VarRef id), imps, args_scopes
(* Is it a global reference or a syntactic definition? *)
let intern_qualid env vars loc qid =
@@ -334,11 +332,8 @@ let coerce_to_id = function
str"This expression should be a simple identifier")
let traverse_binder id (subst,(ids,impls,scopes as env)) =
- try
- let id' = coerce_to_id (List.assoc id subst) in
- id', (subst,(Idset.add id' ids,impls,scopes))
- with Not_found ->
- id, (List.remove_assoc id subst,env)
+ let id = try coerce_to_id (List.assoc id subst) with Not_found -> id in
+ id,(subst,(Idset.add id ids,impls,scopes))
let rec subst_rawconstr loc interp (subst,env as senv) = function
| AVar id ->
diff --git a/interp/symbols.ml b/interp/symbols.ml
index c6eff9ab9..87282f046 100644
--- a/interp/symbols.ml
+++ b/interp/symbols.ml
@@ -14,6 +14,7 @@ open Pp
open Bignat
open Names
open Nametab
+open Libnames
open Summary
open Rawterm
open Topconstr
@@ -41,7 +42,7 @@ open Ppextend
type level = precedence * precedence list
type delimiters = string * string
type scope = {
- notations: (aconstr * level) Stringmap.t;
+ notations: (aconstr * (level * string)) Stringmap.t;
delimiters: delimiters option
}
type scopes = scope_name list
@@ -58,6 +59,9 @@ let default_scope = "core_scope"
let _ = Stringmap.add default_scope empty_scope !scope_map
+(**********************************************************************)
+(* The global stack of scopes *)
+
let scope_stack = ref [default_scope]
let current_scopes () = !scope_stack
@@ -65,26 +69,8 @@ let current_scopes () = !scope_stack
(* TODO: push nat_scope, z_scope, ... in scopes summary *)
(**********************************************************************)
-(* Interpreting numbers (not in summary because functional objects) *)
-
-type numeral_interpreter_name = string
-type numeral_interpreter =
- (loc -> bigint -> rawconstr)
- * (loc -> bigint -> name -> cases_pattern) option
-
-let numeral_interpreter_tab =
- (Hashtbl.create 17 : (numeral_interpreter_name,numeral_interpreter)Hashtbl.t)
-
-let declare_numeral_interpreter sc t =
- Hashtbl.add numeral_interpreter_tab sc t
-
-let lookup_numeral_interpreter s =
- try
- Hashtbl.find numeral_interpreter_tab s
- with Not_found ->
- error ("No interpretation for numerals in scope "^s)
+(* Operations on scopes *)
-(* For loading without opening *)
let declare_scope scope =
try let _ = Stringmap.find scope !scope_map in ()
with Not_found ->
@@ -97,6 +83,9 @@ let find_scope scope =
let check_scope sc = let _ = find_scope sc in ()
+(**********************************************************************)
+(* Delimiters *)
+
let declare_delimiters scope dlm =
let sc = find_scope scope in
if sc.delimiters <> None && Options.is_verbose () then
@@ -104,105 +93,147 @@ let declare_delimiters scope dlm =
let sc = { sc with delimiters = Some dlm } in
scope_map := Stringmap.add scope sc !scope_map
-(* The mapping between notations and production *)
+let find_delimiters scope = (find_scope scope).delimiters
-let declare_notation nt scope (c,prec as info) =
- let sc = find_scope scope in
- if Stringmap.mem nt sc.notations && Options.is_verbose () then
- warning ("Notation "^nt^" is already used in scope "^scope);
- let sc = { sc with notations = Stringmap.add nt info sc.notations } in
- scope_map := Stringmap.add scope sc !scope_map
+(* Uninterpretation tables *)
-let rec find_interpretation f = function
- | scope::scopes ->
- (try f (find_scope scope)
- with Not_found -> find_interpretation f scopes)
- | [] -> raise Not_found
+type interpretation = identifier list * aconstr
+type interp_rule = scope_name * notation * interpretation * int option
-let rec interp_notation ntn scopes =
- let f scope = fst (Stringmap.find ntn scope.notations) in
- try find_interpretation f scopes
- with Not_found -> anomaly ("Unknown interpretation for notation "^ntn)
+(* We define keys for rawterm and aconstr to split the syntax entries
+ according to the key of the pattern (adapted from Chet Murthy by HH) *)
-let find_notation_with_delimiters scope =
- match (Stringmap.find scope !scope_map).delimiters with
- | Some dlm -> Some (Some dlm)
- | None -> None
+type key =
+ | RefKey of global_reference
+ | Oth
-let rec find_notation_without_delimiters ntn_scope ntn = function
- | scope::scopes ->
- (* Is the expected printer attached to the most recently open scope? *)
- if scope = ntn_scope then
- Some None
- else
- (* If the most recently open scope has a printer for this pattern
- but not the expected one then we need delimiters *)
- if Stringmap.mem ntn (Stringmap.find scope !scope_map).notations then
- find_notation_with_delimiters ntn_scope
- else
- find_notation_without_delimiters ntn_scope ntn scopes
- | [] ->
- find_notation_with_delimiters ntn_scope
+(* Scopes table : interpretation -> scope_name *)
+let notations_key_table = ref Gmapl.empty
+let numeral_key_table = Hashtbl.create 7
-let find_notation ntn_scope ntn scopes =
- match
- find_notation_without_delimiters ntn_scope ntn scopes
- with
- | None -> None
- | Some None -> Some (None,scopes)
- | Some x -> Some (x,ntn_scope::scopes)
+let rawconstr_key = function
+ | RApp (_,RRef (_,ref),_) -> RefKey ref
+ | RRef (_,ref) -> RefKey ref
+ | _ -> Oth
-let exists_notation_in_scope scope prec ntn r =
- try Stringmap.find ntn (Stringmap.find scope !scope_map).notations = (r,prec)
- with Not_found -> false
+let aconstr_key = function
+ | AApp (ARef ref,args) -> RefKey ref, Some (List.length args)
+ | ARef ref -> RefKey ref, Some 0
+ | _ -> Oth, None
-let exists_notation_prec prec nt sc =
- try snd (Stringmap.find nt sc.notations) = prec with Not_found -> false
+let pattern_key = function
+ | PatCstr (_,cstr,_,_) -> RefKey (ConstructRef cstr)
+ | _ -> Oth
-let exists_notation prec nt =
- Stringmap.fold (fun scn sc b -> b or exists_notation_prec prec nt sc)
- !scope_map false
+(**********************************************************************)
+(* Interpreting numbers (not in summary because functional objects) *)
-(* We have to print delimiters; look for the more recent defined one *)
-(* Do we need to print delimiters? To know it, we look for a numeral *)
-(* printer available in the current stack of scopes *)
-let find_numeral_with_delimiters scope =
+type num_interpreter =
+ (loc -> bigint -> rawconstr)
+ * (loc -> bigint -> name -> cases_pattern) option
+
+type num_uninterpreter =
+ rawconstr list * (rawconstr -> bigint option)
+ * (cases_pattern -> bigint option) option
+
+type required_module = string list
+
+let numeral_interpreter_tab =
+ (Hashtbl.create 7 : (scope_name,required_module*num_interpreter) Hashtbl.t)
+
+let declare_numeral_interpreter sc dir interp (patl,uninterp,uninterpc) =
+ declare_scope sc;
+ Hashtbl.add numeral_interpreter_tab sc (dir,interp);
+ List.iter
+ (fun pat -> Hashtbl.add numeral_key_table (rawconstr_key pat)
+ (sc,uninterp,uninterpc))
+ patl
+
+let check_required_module loc sc d =
+ let d' = List.map id_of_string d in
+ let dir = make_dirpath (List.rev d') in
+ if not (Library.library_is_loaded dir) then
+ user_err_loc (loc,"numeral_interpreter",
+ str ("Cannot interpret numbers in "^sc^" without requiring first module "
+ ^(list_last d)))
+
+let lookup_numeral_interpreter loc sc =
+ try
+ let (dir,interpreter) = Hashtbl.find numeral_interpreter_tab sc in
+ check_required_module loc sc dir;
+ interpreter
+ with Not_found ->
+ error ("No interpretation for numerals in scope "^sc)
+
+(* Look if some notation or numeral printer in [scope] can be used in
+ the scope stack [scopes], and if yes, using delimiters or not *)
+
+let find_with_delimiters scope =
match (Stringmap.find scope !scope_map).delimiters with
- | Some dlm -> Some (Some dlm)
+ | Some _ -> Some (Some scope)
| None -> None
-let rec find_numeral_without_delimiters printer_scope = function
+let rec find_without_delimiters find ntn_scope = function
| scope :: scopes ->
- (* Is the expected printer attached to the most recently open scope? *)
- if scope = printer_scope then
+ (* Is the expected ntn/numpr attached to the most recently open scope? *)
+ if scope = ntn_scope then
Some None
else
- (* If the most recently open scope has a printer for numerals
+ (* If the most recently open scope has a notation/numeral printer
but not the expected one then we need delimiters *)
- if not (Hashtbl.mem numeral_interpreter_tab scope) then
- find_numeral_without_delimiters printer_scope scopes
+ if find scope then
+ find_with_delimiters ntn_scope
else
- find_numeral_with_delimiters printer_scope
+ find_without_delimiters find ntn_scope scopes
| [] ->
(* Can we switch to [scope]? Yes if it has defined delimiters *)
- find_numeral_with_delimiters printer_scope
+ find_with_delimiters ntn_scope
+
+(* The mapping between notations and their interpretation *)
+
+let declare_interpretation ntn scope pat =
+ let sc = find_scope scope in
+ if Stringmap.mem ntn sc.notations && Options.is_verbose () then
+ warning ("Notation "^ntn^" is already used in scope "^scope);
+ let sc = { sc with notations = Stringmap.add ntn pat sc.notations } in
+ scope_map := Stringmap.add scope sc !scope_map
+
+let declare_uninterpretation ntn scope metas c =
+ let (key,n) = aconstr_key c in
+ notations_key_table :=
+ Gmapl.add key (scope,ntn,(metas,c),n) !notations_key_table
-let find_numeral_printer printer_scope scopes =
+let declare_notation ntn scope (metas,c) prec df onlyparse =
+ declare_interpretation ntn scope (c,(prec,df));
+ if not onlyparse then declare_uninterpretation ntn scope metas c
+
+let rec find_interpretation f = function
+ | scope::scopes ->
+ (try f (find_scope scope)
+ with Not_found -> find_interpretation f scopes)
+ | [] -> raise Not_found
+
+let rec interp_notation ntn scopes =
+ let f scope = fst (Stringmap.find ntn scope.notations) in
+ try find_interpretation f scopes
+ with Not_found -> anomaly ("Unknown interpretation for notation "^ntn)
+
+let uninterp_notations c =
+ Gmapl.find (rawconstr_key c) !notations_key_table
+
+let availability_of_notation (ntn_scope,ntn) scopes =
match
- find_numeral_without_delimiters printer_scope scopes
+ let f scope =
+ Stringmap.mem ntn (Stringmap.find scope !scope_map).notations in
+ find_without_delimiters f ntn_scope scopes
with
| None -> None
- | Some None -> Some (None,scopes)
- | Some x -> Some (x,printer_scope::scopes)
-
-(* This is the map associating the scope a numeral printer belongs to *)
-(*
-let numeral_printer_map = ref (Stringmap.empty : scope_name Stringmap.t)
-*)
+ | Some None -> Some None
+ | Some (Some dlm) -> Some (Some ntn_scope)
let rec interp_numeral loc n = function
| scope :: scopes ->
- (try fst (lookup_numeral_interpreter scope) loc n
+ (try fst (lookup_numeral_interpreter loc scope) loc n
with Not_found -> interp_numeral loc n scopes)
| [] ->
user_err_loc (loc,"interp_numeral",
@@ -211,7 +242,7 @@ let rec interp_numeral loc n = function
let rec interp_numeral_as_pattern loc n name = function
| scope :: scopes ->
(try
- match snd (lookup_numeral_interpreter scope) with
+ match snd (lookup_numeral_interpreter loc scope) with
| None -> raise Not_found
| Some g -> g loc n name
with Not_found -> interp_numeral_as_pattern loc n name scopes)
@@ -219,6 +250,48 @@ let rec interp_numeral_as_pattern loc n name = function
user_err_loc (loc,"interp_numeral_as_pattern",
str "No interpretation for numeral " ++ pr_bigint n)
+let uninterp_numeral c =
+ try
+ let (sc,numpr,_) = Hashtbl.find numeral_key_table (rawconstr_key c) in
+ match numpr c with
+ | None -> raise No_match
+ | Some n -> (sc,n)
+ with Not_found -> raise No_match
+
+let uninterp_cases_numeral c =
+ try
+ match Hashtbl.find numeral_key_table (pattern_key c) with
+ | (_,_,None) -> raise No_match
+ | (sc,_,Some numpr) ->
+ match numpr c with
+ | None -> raise No_match
+ | Some n -> (sc,n)
+ with Not_found -> raise No_match
+
+let availability_of_numeral printer_scope scopes =
+ match
+ let f scope = Hashtbl.mem numeral_interpreter_tab scope in
+ find_without_delimiters f printer_scope scopes
+ with
+ | None -> None
+ | Some x -> Some x
+
+(* Miscellaneous *)
+
+let exists_notation_in_scope scope prec ntn r =
+ try
+ let sc = Stringmap.find scope !scope_map in
+ let (r',(prec',_)) = Stringmap.find ntn sc.notations in
+ r' = r & prec = prec'
+ with Not_found -> false
+
+let exists_notation_prec prec nt sc =
+ try fst (snd (Stringmap.find nt sc.notations)) = prec with Not_found -> false
+
+let exists_notation prec nt =
+ Stringmap.fold (fun scn sc b -> b or exists_notation_prec prec nt sc)
+ !scope_map false
+
(* Exportation of scopes *)
let cache_scope (_,sc) =
check_scope sc;
@@ -238,19 +311,8 @@ let (inScope,outScope) =
let open_scope sc = Lib.add_anonymous_leaf (inScope sc)
-
(* Special scopes associated to arguments of a global reference *)
-open Libnames
-
-module RefOrdered =
- struct
- type t = global_reference
- let compare = Pervasives.compare
- end
-
-module Refmap = Map.Make(RefOrdered)
-
let arguments_scope = ref Refmap.empty
let cache_arguments_scope (_,(r,scl)) =
@@ -276,18 +338,22 @@ let find_arguments_scope r =
(* Printing *)
-let pr_delimiters = function
+let pr_delimiters_info = function
| None -> str "No delimiters"
| Some (l,r) -> str "Delimiters are " ++ str l ++ str " and " ++ str r
-let pr_notation prraw ntn r =
- str ntn ++ str " stands for " ++ prraw r
+let rec rawconstr_of_aconstr () x =
+ map_aconstr_with_binders_loc dummy_loc (fun id () -> (id,()))
+ rawconstr_of_aconstr () x
+
+let pr_notation_info prraw ntn c =
+ str ntn ++ str " stands for " ++ prraw (rawconstr_of_aconstr () c)
let pr_named_scope prraw scope sc =
str "Scope " ++ str scope ++ fnl ()
- ++ pr_delimiters sc.delimiters ++ fnl ()
+ ++ pr_delimiters_info sc.delimiters ++ fnl ()
++ Stringmap.fold
- (fun ntn (r,_) strm -> pr_notation prraw ntn r ++ fnl () ++ strm)
+ (fun ntn (r,(_,df)) strm -> pr_notation_info prraw df r ++ fnl () ++ strm)
sc.notations (mt ())
let pr_scope prraw scope = pr_named_scope prraw scope (find_scope scope)
@@ -297,20 +363,44 @@ let pr_scopes prraw =
(fun scope sc strm -> pr_named_scope prraw scope sc ++ fnl () ++ strm)
!scope_map (mt ())
+(**********************************************************************)
+(* Mapping notations to concrete syntax *)
+
+type unparsing_rule = unparsing list * precedence
+
+(* Concrete syntax for symbolic-extension table *)
+let printing_rules =
+ ref (Stringmap.empty : unparsing_rule Stringmap.t)
+
+let declare_notation_printing_rule ntn unpl =
+ printing_rules := Stringmap.add ntn unpl !printing_rules
+
+let find_notation_printing_rule ntn =
+ try Stringmap.find ntn !printing_rules
+ with Not_found -> anomaly ("No printing rule found for "^ntn)
+
+(**********************************************************************)
(* Synchronisation with reset *)
-let freeze () = (!scope_map, !scope_stack, !arguments_scope)
+let freeze () =
+ (!scope_map, !scope_stack, !arguments_scope,
+ !notations_key_table, !printing_rules)
-let unfreeze (scm,scs,asc) =
+let unfreeze (scm,scs,asc,fkm,pprules) =
scope_map := scm;
scope_stack := scs;
- arguments_scope := asc
+ arguments_scope := asc;
+ notations_key_table := fkm;
+ printing_rules := pprules
-let init () = ()
+let init () =
(*
scope_map := Strinmap.empty;
scope_stack := Stringmap.empty
+ arguments_scope := Refmap.empty
*)
+ notations_key_table := Gmapl.empty;
+ printing_rules := Stringmap.empty
let _ =
declare_summary "symbols"
@@ -318,14 +408,3 @@ let _ =
unfreeze_function = unfreeze;
init_function = init;
survive_section = false }
-
-
-let printing_rules =
- ref (Stringmap.empty : (unparsing list * precedence) Stringmap.t)
-
-let declare_printing_rule ntn unpl =
- printing_rules := Stringmap.add ntn unpl !printing_rules
-
-let find_notation_printing_rule ntn =
- try Stringmap.find ntn !printing_rules
- with Not_found -> anomaly ("No printing rule found for "^ntn)
diff --git a/interp/symbols.mli b/interp/symbols.mli
index 3c082b2ce..466a2bb28 100644
--- a/interp/symbols.mli
+++ b/interp/symbols.mli
@@ -14,22 +14,17 @@ open Pp
open Bignat
open Names
open Nametab
+open Libnames
open Rawterm
open Topconstr
open Ppextend
-(*i*)
-(*s A numeral interpreter is the pair of an interpreter for _integer_
- numbers in terms and an optional interpreter in pattern, if
- negative numbers are not supported, the interpreter must fail with
- an appropriate error message *)
+(*i*)
-type numeral_interpreter_name = string
-type numeral_interpreter =
- (loc -> bigint -> rawconstr)
- * (loc -> bigint -> name -> cases_pattern) option
+(**********************************************************************)
+(* Scopes *)
-(* A scope is a set of interpreters for symbols + optional
+(*s A scope is a set of interpreters for symbols + optional
interpreter and printers for integers + optional delimiters *)
type level = precedence * precedence list
@@ -38,40 +33,92 @@ type scope
type scopes = scope_name list
val default_scope : scope_name
+val declare_scope : scope_name -> unit
+
+(* Open scope *)
+
val current_scopes : unit -> scopes
val open_scope : scope_name -> unit
-val declare_scope : scope_name -> unit
(* Declare delimiters for printing *)
+
val declare_delimiters : scope_name -> delimiters -> unit
+val find_delimiters : scope_name -> delimiters option
+
+(*s Declare and uses back and forth a numeral interpretation *)
+
+(* A numeral interpreter is the pair of an interpreter for _integer_
+ numbers in terms and an optional interpreter in pattern, if
+ negative numbers are not supported, the interpreter must fail with
+ an appropriate error message *)
+
+type num_interpreter =
+ (loc -> bigint -> rawconstr)
+ * (loc -> bigint -> name -> cases_pattern) option
+
+type num_uninterpreter =
+ rawconstr list * (rawconstr -> bigint option)
+ * (cases_pattern -> bigint option) option
-(* Declare, interpret, and look for a printer for numeral *)
-val declare_numeral_interpreter :
- numeral_interpreter_name -> numeral_interpreter -> unit
+type required_module = string list
+val declare_numeral_interpreter : scope_name -> required_module ->
+ num_interpreter -> num_uninterpreter -> unit
+
+(* Returns the term/cases_pattern bound to a numeral in a given scope context*)
val interp_numeral : loc -> bigint -> scopes -> rawconstr
val interp_numeral_as_pattern : loc -> bigint -> name -> scopes ->cases_pattern
-val find_numeral_printer : string -> scopes ->
- (delimiters option * scopes) option
-(* Declare, interpret, and look for a printer for symbolic notations *)
-val declare_notation : notation -> scope_name -> aconstr * level -> unit
+(* Returns the numeral bound to a term/cases_pattern; raises No_match if no *)
+(* such numeral *)
+val uninterp_numeral : rawconstr -> scope_name * bigint
+val uninterp_cases_numeral : cases_pattern -> scope_name * bigint
+
+val availability_of_numeral : scope_name -> scopes -> scope_name option option
+
+(*s Declare and interpret back and forth a notation *)
+
+type interpretation = identifier list * aconstr
+
+(* Binds a notation in a given scope to an interpretation *)
+type interp_rule = scope_name * notation * interpretation * int option
+val declare_notation : notation -> scope_name -> interpretation -> level ->
+ string -> bool -> unit
+
+(* Returns the interpretation bound to a notation *)
val interp_notation : notation -> scopes -> aconstr
-val find_notation : scope_name -> notation -> scopes ->
- (delimiters option * scopes) option
-val exists_notation_in_scope :
- scope_name -> level -> notation -> aconstr -> bool
+
+(* Returns the possible notations for a given term *)
+val uninterp_notations : rawconstr -> interp_rule list
+
+(* Test if a notation is available in the scopes *)
+(* context [scopes] if available, the result is not None; the first *)
+(* argument is itself not None if a delimiters is needed; the second *)
+(* argument is a numeral printer if the *)
+val availability_of_notation : scope_name * notation -> scopes ->
+ scope_name option option
+
+(*s** Miscellaneous *)
+
+(* Checks for already existing notations *)
+val exists_notation_in_scope : scope_name -> level -> notation -> aconstr->bool
val exists_notation : level -> notation -> bool
-(* Declare and look for scopes associated to arguments of a global ref *)
-open Libnames
+(* Declares and looks for scopes associated to arguments of a global ref *)
val declare_arguments_scope: global_reference -> scope_name option list -> unit
val find_arguments_scope : global_reference -> scope_name option list
-(* Printing scopes *)
-val pr_scope : (aconstr -> std_ppcmds) -> scope_name -> std_ppcmds
-val pr_scopes : (aconstr -> std_ppcmds) -> std_ppcmds
+(* Prints scopes (expect a pure aconstr printer *)
+val pr_scope : (rawconstr -> std_ppcmds) -> scope_name -> std_ppcmds
+val pr_scopes : (rawconstr -> std_ppcmds) -> std_ppcmds
+
+(**********************************************************************)
+(*s Printing rules for notations *)
+(* Declare and look for the printing rule for symbolic notations *)
+type unparsing_rule = unparsing list * precedence
+val declare_notation_printing_rule : notation -> unparsing_rule -> unit
+val find_notation_printing_rule : notation -> unparsing_rule
-val declare_printing_rule : notation -> unparsing list * precedence -> unit
-val find_notation_printing_rule : notation -> unparsing list * precedence
+(**********************************************************************)
+(* Rem: printing rules for numerals are trivial *)
diff --git a/interp/topconstr.ml b/interp/topconstr.ml
index 8d16602b5..8173d3fc4 100644
--- a/interp/topconstr.ml
+++ b/interp/topconstr.ml
@@ -18,8 +18,9 @@ open Rawterm
open Term
(*i*)
-
+(**********************************************************************)
(* This is the subtype of rawconstr allowed in syntactic extensions *)
+
type aconstr =
| ARef of global_reference
| AVar of identifier
@@ -29,7 +30,7 @@ type aconstr =
| ALetIn of name * aconstr * aconstr
| ACases of aconstr option * aconstr list *
(identifier list * cases_pattern list * aconstr) list
- | AOldCase of case_style * aconstr option * aconstr * aconstr array
+ | AOrderedCase of case_style * aconstr option * aconstr * aconstr array
| ASort of rawsort
| AHole of hole_kind
| AMeta of int
@@ -53,7 +54,7 @@ let map_aconstr_with_binders_loc loc g f e = function
let eqnl = List.map (fun (idl,pat,rhs) ->
let (idl,e) = List.fold_right fold idl ([],e) in (loc,idl,pat,f e rhs)) eqnl in
RCases (loc,option_app (f e) tyopt,List.map (f e) tml,eqnl)
- | AOldCase (b,tyopt,tm,bv) ->
+ | AOrderedCase (b,tyopt,tm,bv) ->
ROrderedCase (loc,b,option_app (f e) tyopt,f e tm,Array.map (f e) bv)
| ACast (c,t) -> RCast (loc,f e c,f e t)
| ASort x -> RSort (loc,x)
@@ -114,12 +115,12 @@ let rec subst_aconstr subst raw =
if ro' == ro && rl' == rl && branches' == branches then raw else
ACases (ro',rl',branches')
- | AOldCase (b,ro,r,ra) ->
+ | AOrderedCase (b,ro,r,ra) ->
let ro' = option_smartmap (subst_aconstr subst) ro
and r' = subst_aconstr subst r
and ra' = array_smartmap (subst_aconstr subst) ra in
if ro' == ro && r' == r && ra' == ra then raw else
- AOldCase (b,ro',r',ra')
+ AOrderedCase (b,ro',r',ra')
| AMeta _ | ASort _ -> raw
@@ -145,7 +146,7 @@ let rec aux = function
let eqnl = List.map (fun (_,idl,pat,rhs) -> (idl,pat,aux rhs)) eqnl in
ACases (option_app aux tyopt,List.map aux tml, eqnl)
| ROrderedCase (_,b,tyopt,tm,bv) ->
- AOldCase (b,option_app aux tyopt,aux tm, Array.map aux bv)
+ AOrderedCase (b,option_app aux tyopt,aux tm, Array.map aux bv)
| RCast (_,c,t) -> ACast (aux c,aux t)
| RSort (_,s) -> ASort s
| RHole (_,w) -> AHole w
@@ -157,6 +158,75 @@ allowed in abbreviatable expressions"
let aconstr_of_rawconstr = aux
+(* Pattern-matching rawconstr and aconstr *)
+
+exception No_match
+
+let rec alpha_var id1 id2 = function
+ | (i1,i2)::_ when i1=id1 -> i2 = id2
+ | (i1,i2)::_ when i2=id2 -> i1 = id1
+ | _::idl -> alpha_var id1 id2 idl
+ | [] -> id1 = id2
+
+let alpha_eq_val (x,y) = x = y
+
+let bind_env sigma var v =
+ try
+ let vvar = List.assoc var sigma in
+ if alpha_eq_val (v,vvar) then sigma
+ else raise No_match
+ with Not_found ->
+ (var,v)::sigma
+
+let rec match_ alp metas sigma a1 a2 = match (a1,a2) with
+ | r1, AVar id2 when List.mem id2 metas -> bind_env sigma id2 r1
+ | RVar (_,id1), AVar id2 when alpha_var id1 id2 alp -> sigma
+ | RRef (_,r1), ARef r2 when r1 = r2 -> sigma
+ | RMeta (_,n1), AMeta n2 when n1=n2 -> sigma
+ | RApp (_,f1,l1), AApp (f2,l2) when List.length l1 = List.length l2 ->
+ List.fold_left2 (match_ alp metas) (match_ alp metas sigma f1 f2) l1 l2
+ | RLambda (_,na1,t1,b1), ALambda (na2,t2,b2) ->
+ match_binders alp metas (match_ alp metas sigma t1 t2) b1 b2 na1 na2
+ | RProd (_,na1,t1,b1), AProd (na2,t2,b2) ->
+ match_binders alp metas (match_ alp metas sigma t1 t2) b1 b2 na1 na2
+ | RLetIn (_,na1,t1,b1), AProd (na2,t2,b2) ->
+ match_binders alp metas (match_ alp metas sigma t1 t2) b1 b2 na1 na2
+ | RCases (_,po1,tml1,eqnl1), ACases (po2,tml2,eqnl2) ->
+ let sigma = option_fold_left2 (match_ alp metas) sigma po1 po2 in
+ let sigma = List.fold_left2 (match_ alp metas) sigma tml1 tml2 in
+ List.fold_left2 (match_equations alp metas) sigma eqnl1 eqnl2
+ | ROrderedCase (_,st,po1,c1,bl1), AOrderedCase (st2,po2,c2,bl2) ->
+ let sigma = option_fold_left2 (match_ alp metas) sigma po1 po2 in
+ array_fold_left2 (match_ alp metas) (match_ alp metas sigma c1 c2) bl1 bl2
+ | RCast(_,c1,t1), ACast(c2,t2) ->
+ match_ alp metas (match_ alp metas sigma c1 c2) t1 t2
+ | RSort (_,s1), ASort s2 when s1 = s2 -> sigma
+ | RHole _, a -> sigma
+ | a, AHole _ -> sigma
+ | (RDynamic _ | RRec _ | REvar _), _
+ | _,_ -> raise No_match
+
+and match_binders alp metas sigma b1 b2 na1 na2 = match (na1,na2) with
+ | (na1,Name id2) when List.mem id2 metas ->
+ let sigma =
+ name_fold
+ (fun id sigma -> bind_env sigma id2 (RVar (dummy_loc,id))) na1 sigma
+ in
+ match_ alp metas sigma b1 b2
+ | (na1,na2) ->
+ let alp =
+ name_fold
+ (fun id1 -> name_fold (fun id2 alp -> (id1,id2)::alp) na2) na1 alp in
+ match_ alp metas sigma b1 b2
+
+and match_equations alp metas sigma (_,idl1,pat1,rhs1) (idl2,pat2,rhs2) =
+ if idl1 = idl2 & pat1 = pat2 (* Useful to reason up to alpha ?? *) then
+ match_ alp metas sigma rhs1 rhs2
+ else raise No_match
+
+let match_aconstr c (metas,pat) = match_ [] metas [] c pat
+
+(**********************************************************************)
(*s Concrete syntax for terms *)
type scope_name = string
@@ -200,6 +270,16 @@ and fixpoint_expr = identifier * int * constr_expr * constr_expr
and cofixpoint_expr = identifier * constr_expr * constr_expr
+(***********************)
+(* For binders parsing *)
+
+type local_binder =
+ | LocalRawDef of name located * constr_expr
+ | LocalRawAssum of name located list * constr_expr
+
+(**********************************************************************)
+(* Functions on constr_expr *)
+
let constr_loc = function
| CRef (Ident (loc,_)) -> loc
| CRef (Qualid (loc,_)) -> loc
@@ -230,9 +310,6 @@ let cases_pattern_loc = function
| CPatNumeral (loc,_) -> loc
| CPatDelimiters (loc,_,_) -> loc
-let replace_vars_constr_expr l t =
- if l = [] then t else failwith "replace_constr_expr: TODO"
-
let occur_var_constr_ref id = function
| Ident (loc,id') -> id = id'
| Qualid _ -> false
@@ -307,12 +384,14 @@ let map_constr_expr_with_binders f g e = function
| CCoFix (loc,id,dl) ->
CCoFix (loc,id,List.map (fun (id,t,d) -> (id,f e t,f e d)) dl)
-(* For binders parsing *)
-
-type local_binder =
- | LocalRawDef of name located * constr_expr
- | LocalRawAssum of name located list * constr_expr
+(* Used in constrintern *)
+let rec replace_vars_constr_expr l = function
+ | CRef (Ident (loc,id)) as x ->
+ (try CRef (Ident (loc,List.assoc id l)) with Not_found -> x)
+ | c -> map_constr_expr_with_binders replace_vars_constr_expr
+ (fun id l -> List.remove_assoc id l) l c
+(**********************************************************************)
(* Concrete syntax for modules and modules types *)
type with_declaration_ast =
diff --git a/interp/topconstr.mli b/interp/topconstr.mli
index 2c276ca99..85b05a4fa 100644
--- a/interp/topconstr.mli
+++ b/interp/topconstr.mli
@@ -31,7 +31,7 @@ type aconstr =
| ALetIn of name * aconstr * aconstr
| ACases of aconstr option * aconstr list *
(identifier list * cases_pattern list * aconstr) list
- | AOldCase of case_style * aconstr option * aconstr * aconstr array
+ | AOrderedCase of case_style * aconstr option * aconstr * aconstr array
| ASort of rawsort
| AHole of hole_kind
| AMeta of int
@@ -45,6 +45,12 @@ val subst_aconstr : Names.substitution -> aconstr -> aconstr
val aconstr_of_rawconstr : rawconstr -> aconstr
+(* [match_aconstr metas] match a rawconstr against an aconstr with
+ metavariables in [metas]; it raises [No_match] if the matching fails *)
+exception No_match
+val match_aconstr :
+ rawconstr -> (identifier list * aconstr) -> (identifier * rawconstr) list
+
(*s Concrete syntax for terms *)
type scope_name = string
diff --git a/parsing/ast.ml b/parsing/ast.ml
index ae677979f..13989bcbb 100755
--- a/parsing/ast.ml
+++ b/parsing/ast.ml
@@ -345,6 +345,8 @@ let rec amatch alp sigma spat ast =
| (Pmeta(pv,Tlist),_) -> grammar_type_error (loc ast,"Ast.amatch")
| (Pmeta_slam(pv,pb), Slam(loc, Some s, b)) ->
amatch alp (bind_env_ast sigma pv (Nvar(loc,s))) pb b
+ | (Pmeta_slam(pv,pb), Slam(loc, None, b)) ->
+ amatch alp (bind_env_ast sigma pv (Nvar(loc,id_of_string "_"))) pb b
| (Pmeta_slam(pv,pb), Smetalam(loc, s, b)) ->
anomaly "amatch: match a pattern with an open ast"
| (Pnode(nodp,argp), Node(loc,op,args)) when nodp = op ->
diff --git a/parsing/egrammar.ml b/parsing/egrammar.ml
index 33ca1214f..5b5777492 100644
--- a/parsing/egrammar.ml
+++ b/parsing/egrammar.ml
@@ -20,7 +20,7 @@ open Libnames
(* State of the grammar extensions *)
type all_grammar_command =
- | Notation of (string * notation * prod_item list)
+ | Notation of (int * Gramext.g_assoc option * notation * prod_item list)
| Delimiters of (scope_name * prod_item list * prod_item list)
| Grammar of grammar_command
| TacticGrammar of
@@ -35,6 +35,35 @@ let subst_all_grammar_command subst = function
let (grammar_state : all_grammar_command list ref) = ref []
+
+(**************************************************************************)
+let constr_level = function
+ | 8 -> "top"
+ | n -> string_of_int n
+
+let symbolic_level = function
+ | 9 -> "constr9", None
+ | 10 -> "lconstr", None
+ | 11 -> "pattern", None
+ | n -> "constr", Some n
+
+let numeric_levels = ref [8;1;0]
+
+exception Found
+
+let find_position n =
+ let after = ref 8 in
+ let rec add_level q = function
+ | p::l when p > n -> p :: add_level p l
+ | p::l when p = n -> raise Found
+ | l -> after := q; n::l
+ in
+ try
+ numeric_levels := add_level 8 !numeric_levels;
+ Gramext.After (constr_level !after)
+ with
+ Found -> Gramext.Level (constr_level n)
+
(* Interpretation of the right hand side of grammar rules *)
(* When reporting errors, we add the name of the grammar rule that failed *)
@@ -78,13 +107,15 @@ let make_act f pil =
Gramext.action (fun loc -> f loc env)
| None :: tl -> (* parse a non-binding item *)
Gramext.action (fun _ -> make env tl)
- | Some (p, ETConstr) :: tl -> (* non-terminal *)
+ | Some (p, (ETConstr _| ETOther _)) :: tl -> (* non-terminal *)
Gramext.action (fun (v:constr_expr) -> make ((p,v) :: env) tl)
| Some (p, ETReference) :: tl -> (* non-terminal *)
Gramext.action (fun (v:reference) -> make ((p,CRef v) :: env) tl)
| Some (p, ETIdent) :: tl -> (* non-terminal *)
Gramext.action (fun (v:identifier) ->
- make ((p,CRef (Ident (dummy_loc,v))) :: env) tl) in
+ make ((p,CRef (Ident (dummy_loc,v))) :: env) tl)
+ | Some (p, ETPattern) :: tl ->
+ failwith "Unexpected entry of type cases pattern" in
make [] (List.rev pil)
let make_cases_pattern_act f pil =
@@ -93,12 +124,12 @@ let make_cases_pattern_act f pil =
Gramext.action (fun loc -> f loc env)
| None :: tl -> (* parse a non-binding item *)
Gramext.action (fun _ -> make env tl)
- | Some (p, ETConstr) :: tl -> (* non-terminal *)
+ | Some (p, ETPattern) :: tl -> (* non-terminal *)
Gramext.action (fun v -> make ((p,v) :: env) tl)
| Some (p, ETReference) :: tl -> (* non-terminal *)
Gramext.action (fun v -> make ((p,CPatAtom (dummy_loc,Some v)) :: env) tl)
- | Some (p, ETIdent) :: tl ->
- error "ident entry not admitted in patterns cases syntax extensions" in
+ | Some (p, (ETIdent | ETConstr _ | ETOther _)) :: tl ->
+ error "ident and constr entry not admitted in patterns cases syntax extensions" in
make [] (List.rev pil)
(* Grammar extension command. Rules are assumed correct.
@@ -108,17 +139,16 @@ let make_cases_pattern_act f pil =
* annotations are added when type-checking the command, function
* Extend.of_ast) *)
-let get_entry_type (u,n) =
- if u = "constr" & n = "pattern" then Gram.Entry.obj Constr.pattern
- else Gram.Entry.obj (object_of_typed_entry (get_entry (get_univ u) n))
-
let rec build_prod_item univ = function
| ProdList0 s -> Gramext.Slist0 (build_prod_item univ s)
| ProdList1 s -> Gramext.Slist1 (build_prod_item univ s)
| ProdOpt s -> Gramext.Sopt (build_prod_item univ s)
- | ProdPrimitive nt ->
- let eobj = get_entry_type nt in
- Gramext.Snterm eobj
+ | ProdPrimitive typ ->
+ match entry_of_type false typ with
+ | (eobj,None) ->
+ Gramext.Snterm (Gram.Entry.obj eobj)
+ | (eobj,Some lev) ->
+ Gramext.Snterml (Gram.Entry.obj eobj,constr_level lev)
let symbol_of_prod_item univ = function
| Term tok -> (Gramext.Stoken tok, None)
@@ -126,14 +156,6 @@ let symbol_of_prod_item univ = function
let eobj = build_prod_item univ nt in
(eobj, ovar)
-(*
-let make_rule univ etyp rule =
- let pil = List.map (symbol_of_prod_item univ) rule.gr_production in
- let (symbs,ntl) = List.split pil in
- let act = make_act (rule.gr_name,etyp) rule.gr_action ntl in
- (symbs, act)
-*)
-
let make_rule univ etyp rule =
let pil = List.map (symbol_of_prod_item univ) rule.gr_production in
let (symbs,ntl) = List.split pil in
@@ -147,18 +169,19 @@ let make_rule univ etyp rule =
let act = make_act f ntl in
(symbs, act)
-
(* Rules of a level are entered in reverse order, so that the first rules
are applied before the last ones *)
-let extend_entry univ (te, etyp, ass, rls) =
+let extend_entry univ (te, etyp, pos, name, ass, rls) =
let rules = List.rev (List.map (make_rule univ etyp) rls) in
- grammar_extend (object_of_typed_entry te) None [(None, ass, rules)]
+ grammar_extend te pos [(name, ass, rules)]
(* Defines new entries. If the entry already exists, check its type *)
-let define_entry univ {ge_name=n; ge_type=typ; gl_assoc=ass; gl_rules=rls} =
- let typ = entry_type_of_constr_entry_type typ in
- let e = force_entry_type univ n typ in
- (e,typ,ass,rls)
+let define_entry univ {ge_name=n; gl_assoc=ass; gl_rules=rls} =
+ let typ = explicitize_entry (fst univ) n in
+ let e,lev = entry_of_type true typ in
+ let pos = option_app find_position lev in
+ let name = option_app constr_level lev in
+ (e,typ,pos,name,ass,rls)
(* Add a bunch of grammar rules. Does not check if it is well formed *)
let extend_grammar_rules gram =
@@ -186,29 +209,31 @@ let make_gen_act f pil =
Gramext.action (fun v -> make ((p,in_generic t v) :: env) tl) in
make [] (List.rev pil)
-let extend_constr entry make_act pt =
+let extend_constr entry pos (level,assoc) make_act pt =
let univ = get_univ "constr" in
let pil = List.map (symbol_of_prod_item univ) pt in
let (symbs,ntl) = List.split pil in
let act = make_act ntl in
- grammar_extend entry None [(None, None, [symbs, act])]
+ grammar_extend entry pos [(level, assoc, [symbs, act])]
let constr_entry name =
object_of_typed_entry (get_entry (get_univ "constr") name)
-let extend_constr_notation (name,ntn,rule) =
+let extend_constr_notation (n,assoc,ntn,rule) =
let mkact loc env = CNotation (loc,ntn,env) in
- extend_constr (constr_entry name) (make_act mkact) rule
-
-let extend_constr_grammar (name,c,rule) =
- let mkact loc env = CGrammar (loc,c,env) in
- extend_constr (constr_entry name) (make_act mkact) rule
+ let (e,level) = entry_of_type false (ETConstr ((n,Ppextend.E),Some n)) in
+ let pos = option_app find_position level in
+ extend_constr e pos (option_app constr_level level,assoc)
+ (make_act mkact) rule
let extend_constr_delimiters (sc,rule,pat_rule) =
let mkact loc env = CDelimiters (loc,sc,snd (List.hd env)) in
- extend_constr (constr_entry "constr8") (make_act mkact) rule;
+ extend_constr (constr_entry "constr") (Some (Gramext.Level "top"))
+ (None,None)
+ (make_act mkact) rule;
let mkact loc env = CPatDelimiters (loc,sc,snd (List.hd env)) in
- extend_constr Constr.pattern (make_cases_pattern_act mkact) pat_rule
+ extend_constr Constr.pattern None (None,None)
+ (make_cases_pattern_act mkact) pat_rule
(* These grammars are not a removable *)
let make_rule univ f g (s,pt) =
@@ -246,7 +271,7 @@ let rec interp_entry_name u s =
let e = get_entry (get_univ u) n in
let o = object_of_typed_entry e in
let t = type_of_typed_entry e in
- t, Gramext.Snterm (Pcoq.Gram.Entry.obj o)
+ t,Gramext.Snterm (Pcoq.Gram.Entry.obj o)
let qualified_nterm current_univ = function
| NtQual (univ, en) -> (rename_command univ, rename_command en)
diff --git a/parsing/egrammar.mli b/parsing/egrammar.mli
index ff3f6284b..d24264abc 100644
--- a/parsing/egrammar.mli
+++ b/parsing/egrammar.mli
@@ -24,15 +24,13 @@ val unfreeze : frozen_t -> unit
val init : unit -> unit
type all_grammar_command =
- | Notation of (string * notation * prod_item list)
+ | Notation of (int * Gramext.g_assoc option * notation * prod_item list)
| Delimiters of (scope_name * prod_item list * prod_item list)
| Grammar of grammar_command
| TacticGrammar of (string * (string * grammar_production list) * Tacexpr.raw_tactic_expr) list
val extend_grammar : all_grammar_command -> unit
-val extend_constr_grammar : string * aconstr * prod_item list -> unit
-
(* Add grammar rules for tactics *)
type grammar_tactic_production =
| TacTerm of string
diff --git a/parsing/esyntax.ml b/parsing/esyntax.ml
index 76f4b3f19..859b5548a 100644
--- a/parsing/esyntax.ml
+++ b/parsing/esyntax.ml
@@ -186,7 +186,8 @@ let pr_parenthesis inherited se strm =
let print_delimiters inh se strm = function
| None -> pr_parenthesis inh se strm
- | Some (left,right) ->
+ | Some sc ->
+ let (left,right) = out_some (find_delimiters sc) in
assert (left <> "" && right <> "");
let lspace =
if is_letter (left.[String.length left -1]) then str " " else mt () in
@@ -227,21 +228,21 @@ let call_primitive_parser rec_pr otherwise inherited scopes (se,env) =
(* Test for a primitive printer; may raise Not_found *)
let sc,pr = lookup_primitive_printer c in
(* Look if scope [sc] associated to this printer is OK *)
- (match Symbols.find_numeral_printer sc scopes with
+ (match Symbols.availability_of_numeral sc scopes with
| None -> otherwise ()
- | Some (dlm,scopes) ->
+ | Some scopt ->
(* We can use this printer *)
let node = Ast.pat_sub dummy_loc env e in
match pr node with
- | Some strm -> print_delimiters inherited se strm dlm
+ | Some strm -> print_delimiters inherited se strm scopt
| None -> otherwise ())
| [UNP_SYMBOLIC (sc,pat,sub)] ->
- (match Symbols.find_notation sc pat scopes with
+ (match Symbols.availability_of_notation (sc,pat) scopes with
| None -> otherwise ()
- | Some (dlm,scopes) ->
+ | Some scopt ->
print_delimiters inherited se
- (print_syntax_entry rec_pr scopes env
- {se with syn_hunks = [sub]}) dlm)
+ (print_syntax_entry rec_pr (option_cons scopt scopes) env
+ {se with syn_hunks = [sub]}) scopt)
| _ ->
pr_parenthesis inherited se (print_syntax_entry rec_pr scopes env se)
)
diff --git a/parsing/extend.ml b/parsing/extend.ml
index 0e1f72536..2e4eea4b0 100644
--- a/parsing/extend.ml
+++ b/parsing/extend.ml
@@ -19,13 +19,17 @@ open Topconstr
open Genarg
type entry_type = argument_type
-type constr_entry_type = ETConstr | ETIdent | ETReference
+type constr_entry_type =
+ | ETIdent | ETReference
+ | ETConstr of (int * parenRelation) * int option
+ | ETPattern
+ | ETOther of string * string
type nonterm_prod =
| ProdList0 of nonterm_prod
| ProdList1 of nonterm_prod
| ProdOpt of nonterm_prod
- | ProdPrimitive of (string * string)
+ | ProdPrimitive of constr_entry_type
type prod_item =
| Term of Token.pattern
@@ -38,7 +42,6 @@ type grammar_rule = {
type grammar_entry = {
ge_name : string;
- ge_type : constr_entry_type;
gl_assoc : Gramext.g_assoc option;
gl_rules : grammar_rule list }
@@ -56,18 +59,20 @@ type entry_context = (identifier * constr_entry_type) list
let ast_to_rawconstr = ref (fun _ _ -> AVar (id_of_string "Z"))
let set_ast_to_rawconstr f = ast_to_rawconstr := f
-let act_of_ast vars = function
- | SimpleAction (loc,ConstrNode a) -> !ast_to_rawconstr vars a
- | SimpleAction (loc,CasesPatternNode a) -> failwith "TODO:act_of_ast: cases_pattern"
+let act_of_ast env = function
+ | SimpleAction (loc,ConstrNode a) -> !ast_to_rawconstr env a
+ | SimpleAction (loc,CasesPatternNode a) ->
+ failwith "TODO:act_of_ast: cases_pattern"
| CaseAction _ -> failwith "case/let not supported"
let to_act_check_vars = act_of_ast
type syntax_modifier =
- | SetItemLevel of string * int
+ | SetItemLevel of string list * int
| SetLevel of int
| SetAssoc of Gramext.g_assoc
| SetEntryType of string * constr_entry_type
+ | SetOnlyParsing
type nonterm =
| NtShort of string
@@ -76,8 +81,7 @@ type grammar_production =
| VTerm of string
| VNonTerm of loc * nonterm * Names.identifier option
type raw_grammar_rule = string * grammar_production list * grammar_action
-type raw_grammar_entry =
- string * constr_entry_type * grammar_associativity * raw_grammar_rule list
+type raw_grammar_entry = string * grammar_associativity * raw_grammar_rule list
let subst_grammar_rule subst gr =
{ gr with gr_action = subst_aconstr subst gr.gr_action }
@@ -141,55 +145,85 @@ let rename_command nt =
else if nt = "lassoc_command4" then warn nt "lassoc_constr4"
else nt
-let qualified_nterm current_univ = function
- | NtQual (univ, en) -> (rename_command univ, rename_command en)
- | NtShort en -> (current_univ, rename_command en)
-
-let entry_type_of_constr_entry_type = function
- | ETConstr -> ConstrArgType
- | ETIdent -> IdentArgType
- | ETReference -> RefArgType
-
-let constr_entry_of_entry = function
- | ConstrArgType -> ETConstr
- | IdentArgType -> ETIdent
- | RefArgType -> ETReference
- | _ -> error "Cannot arbitrarily extend non constr/ident/ref entries"
-
-let nterm loc (get_entry_type,univ) nont =
- let nt = qualified_nterm univ nont in
- try (nt,constr_entry_of_entry (get_entry_type nt))
- with Not_found ->
- let (s,n) = nt in
- user_err_loc(loc,"Externd.nterm",str("unknown grammar entry: "^s^":"^n))
+(* This translates constr0, constr1, ... level into camlp4 levels of constr *)
+
+let explicitize_entry univ nt =
+ if univ = "prim" & nt = "var" then ETIdent else
+ if univ <> "constr" then ETOther (univ,nt) else
+ match nt with
+ | "constr0" -> ETConstr ((0,E),Some 0)
+ | "constr1" -> ETConstr ((1,E),Some 1)
+ | "constr2" -> ETConstr ((2,E),Some 2)
+ | "constr3" -> ETConstr ((3,E),Some 3)
+ | "lassoc_constr4" -> ETConstr ((4,E),Some 4)
+ | "constr5" -> ETConstr ((5,E),Some 5)
+ | "constr6" -> ETConstr ((6,E),Some 6)
+ | "constr7" -> ETConstr ((7,E),Some 7)
+ | "constr8" | "constr" -> ETConstr ((8,E),Some 8)
+ | "constr9" -> ETConstr ((9,E),Some 9)
+ | "constr10" | "lconstr" -> ETConstr ((10,E),Some 10)
+ | "ident" -> ETIdent
+ | "global" -> ETReference
+ | _ -> ETOther (univ,nt)
+
+(* This determines if a reference to constr_n is a reference to the level
+ below wrt associativity (to be translated in camlp4 into "constr" without
+ level) or to another level (to be translated into "constr LEVEL n") *)
+
+let clever_explicitize_entry univ name from assoc pos =
+ match explicitize_entry univ name, explicitize_entry "" from, pos with
+ | ETConstr ((n,_ as s),_),ETConstr ((lev,_),_),Some start
+ when n = lev - 1 & assoc <> Some Gramext.LeftA & start
+ or n = lev & assoc = Some Gramext.LeftA & start
+ or n = lev & assoc = Some Gramext.RightA & not start
+ or n = lev - 1 & assoc <> Some Gramext.RightA & not start
+ -> ETConstr (s, None)
+ | x,_,_ -> x
+
+let qualified_nterm current_univ from ass pos = function
+ | NtQual (univ, en) ->
+ let univ = rename_command univ in
+ clever_explicitize_entry univ (rename_command en) from ass pos
+ | NtShort en ->
+ clever_explicitize_entry current_univ (rename_command en) from ass pos
+
+let check_entry check_entry_type = function
+ | ETOther (u,n) -> check_entry_type (u,n)
+ | _ -> ()
+
+let nterm loc (((check_entry_type,univ),lev,ass),pos) nont =
+ let typ = qualified_nterm univ lev ass pos nont in
+ check_entry check_entry_type typ;
+ typ
let prod_item univ env = function
| VTerm s -> env, Term (terminal s)
| VNonTerm (loc, nt, Some p) ->
- let (nont, etyp) = nterm loc univ nt in
- ((p, etyp) :: env, NonTerm (ProdPrimitive nont, Some (p,etyp)))
+ let typ = nterm loc univ nt in
+ ((p, typ) :: env, NonTerm (ProdPrimitive typ, Some (p,typ)))
| VNonTerm (loc, nt, None) ->
- let (nont, etyp) = nterm loc univ nt in
- env, NonTerm (ProdPrimitive nont, None)
+ let typ = nterm loc univ nt in
+ env, NonTerm (ProdPrimitive typ, None)
-let rec prod_item_list univ penv pil =
+let rec prod_item_list univ penv pil start =
match pil with
| [] -> [], penv
| pi :: pitl ->
- let (env, pic) = prod_item univ penv pi in
- let (pictl, act_env) = prod_item_list univ env pitl in
+ let pos = if pitl=[] then Some false else start in
+ let (env, pic) = prod_item (univ,pos) penv pi in
+ let (pictl, act_env) = prod_item_list univ env pitl None in
(pic :: pictl, act_env)
-let gram_rule univ etyp (name,pil,act) =
- let (pilc, act_env) = prod_item_list univ [] pil in
+let gram_rule univ (name,pil,act) =
+ let (pilc, act_env) = prod_item_list univ [] pil (Some true) in
let a = to_act_check_vars act_env act in
{ gr_name = name; gr_production = pilc; gr_action = a }
-let gram_entry univ (nt, etyp, ass, rl) =
- { ge_name = rename_command nt;
- ge_type = etyp;
+let gram_entry univ (nt, ass, rl) =
+ let name = rename_command nt in
+ { ge_name = name;
gl_assoc = ass;
- gl_rules = List.map (gram_rule univ etyp) rl }
+ gl_rules = List.map (gram_rule (univ,name,ass)) rl }
let interp_grammar_command univ ge entryl =
let univ = rename_command univ in
diff --git a/parsing/extend.mli b/parsing/extend.mli
index 13e3ee067..771434ea3 100644
--- a/parsing/extend.mli
+++ b/parsing/extend.mli
@@ -20,15 +20,17 @@ open Genarg
(*i*)
type entry_type = argument_type
-type constr_entry_type = ETConstr | ETIdent | ETReference
-
-val entry_type_of_constr_entry_type : constr_entry_type -> entry_type
+type constr_entry_type =
+ | ETIdent | ETReference
+ | ETConstr of (int * parenRelation) * int option
+ | ETPattern
+ | ETOther of string * string
type nonterm_prod =
| ProdList0 of nonterm_prod
| ProdList1 of nonterm_prod
| ProdOpt of nonterm_prod
- | ProdPrimitive of (string * string)
+ | ProdPrimitive of constr_entry_type
type prod_item =
| Term of Token.pattern
@@ -41,7 +43,6 @@ type grammar_rule = {
type grammar_entry = {
ge_name : string;
- ge_type : constr_entry_type;
gl_assoc : Gramext.g_assoc option;
gl_rules : grammar_rule list }
@@ -57,10 +58,11 @@ val to_act_check_vars : entry_context -> grammar_action -> aconstr
val set_ast_to_rawconstr : (entry_context -> constr_expr -> aconstr) -> unit
type syntax_modifier =
- | SetItemLevel of string * int
+ | SetItemLevel of string list * int
| SetLevel of int
| SetAssoc of Gramext.g_assoc
| SetEntryType of string * constr_entry_type
+ | SetOnlyParsing
type nonterm =
| NtShort of string
@@ -69,13 +71,14 @@ type grammar_production =
| VTerm of string
| VNonTerm of loc * nonterm * Names.identifier option
type raw_grammar_rule = string * grammar_production list * grammar_action
-type raw_grammar_entry =
- string * constr_entry_type * grammar_associativity * raw_grammar_rule list
+type raw_grammar_entry = string * grammar_associativity * raw_grammar_rule list
val terminal : string -> string * string
val rename_command : string -> string
+val explicitize_entry : string -> string -> constr_entry_type
+
val subst_grammar_command :
Names.substitution -> grammar_command -> grammar_command
@@ -90,10 +93,6 @@ type 'pat unparsing_hunk =
| UNP_TAB
| UNP_FNL
| UNP_SYMBOLIC of string * string * 'pat unparsing_hunk
-(*
- | UNP_INFIX of Libnames.extended_global_reference * string * string *
- (parenRelation * parenRelation)
-*)
(*val subst_unparsing_hunk :
Names.substitution -> (Names.substitution -> 'pat -> 'pat) ->
@@ -129,7 +128,7 @@ type syntax_rule = string * Coqast.t * Coqast.t unparsing_hunk list
type raw_syntax_entry = precedence * syntax_rule list
val interp_grammar_command :
- string -> (string * string -> Genarg.argument_type) ->
+ string -> (string * string -> unit) ->
raw_grammar_entry list -> grammar_command
val interp_syntax_entry :
diff --git a/parsing/g_basevernac.ml4 b/parsing/g_basevernac.ml4
index 77f587894..55a350447 100644
--- a/parsing/g_basevernac.ml4
+++ b/parsing/g_basevernac.ml4
@@ -153,7 +153,8 @@ GEXTEND Gram
VernacRemoveOption (PrimaryTable table, v) ] ]
;
printable:
- [ [ IDENT "All" -> PrintFullContext
+ [ [ IDENT "Term"; qid = global -> PrintName qid
+ | IDENT "All" -> PrintFullContext
| IDENT "Section"; s = global -> PrintSectionContext s
| "Grammar"; uni = IDENT; ent = IDENT ->
(* This should be in "syntax" section but is here for factorization*)
@@ -173,7 +174,8 @@ GEXTEND Gram
| IDENT "Hint" -> PrintHintGoal
| IDENT "Hint"; qid = global -> PrintHint qid
| IDENT "Hint"; "*" -> PrintHintDb
- | IDENT "HintDb"; s = IDENT -> PrintHintDbName s ] ]
+ | IDENT "HintDb"; s = IDENT -> PrintHintDbName s
+ | IDENT "Scope"; s = IDENT -> PrintScope s ] ]
;
option_value:
[ [ n = integer -> IntValue n
@@ -217,14 +219,14 @@ GEXTEND Gram
| "Syntax"; u = univ; el = LIST1 syntax_entry SEP ";" ->
VernacSyntax (u,el)
- | "Syntax"; IDENT "Extension"; s = STRING;
+ | "Uninterpreted"; IDENT "Notation"; s = STRING;
l = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ]
-> VernacSyntaxExtension (s,l)
| IDENT "Open"; IDENT "Scope"; sc = IDENT -> VernacOpenScope sc
- | IDENT "Delimiters"; left = STRING; sc = IDENT; right = STRING ->
- VernacDelimiters (sc,(left,right))
+ | 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)
@@ -233,23 +235,27 @@ GEXTEND Gram
sc = OPT [ ":"; sc = IDENT -> sc ] -> VernacInfix (a,n,op,p,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"; a = entry_prec; n = natural; s = STRING; c = constr;
+ | IDENT "Notation"; s = IDENT; ":="; c = constr ->
+ VernacNotation ("'"^s^"'",c,[],None)
+ | IDENT "Notation"; s = STRING; ":="; c = constr;
modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
- sc = OPT [ ":"; sc = IDENT -> sc ] ->
- let a = match a with None -> Gramext.LeftA | Some a -> a in
- VernacNotation (s,c,(SetAssoc a)::(SetLevel n)::modl,sc)
+ sc = OPT [ ":"; sc = IDENT -> sc ] -> VernacNotation (s,c,modl,sc)
(* "Print" "Grammar" should be here but is in "command" entry in order
to factorize with other "Print"-based vernac entries *)
] ]
;
syntax_modifier:
- [ [ x = IDENT; IDENT "at"; IDENT "level"; n = natural -> SetItemLevel (x,n)
+ [ [ 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) ] ]
+ | x = IDENT; typ = syntax_extension_type -> SetEntryType (x,typ)
+ | IDENT "only"; IDENT "parsing" -> SetOnlyParsing ] ]
;
syntax_extension_type:
[ [ IDENT "ident" -> ETIdent | IDENT "global" -> ETReference ] ]
@@ -259,9 +265,9 @@ GEXTEND Gram
;
(* Syntax entries for Grammar. Only grammar_entry is exported *)
grammar_entry:
- [[ nont = IDENT; etyp = set_entry_type; ":=";
+ [[ nont = IDENT; set_entry_type; ":=";
ep = entry_prec; OPT "|"; rl = LIST0 grammar_rule SEP "|" ->
- (nont,etyp,ep,rl) ]]
+ (nont,ep,rl) ]]
;
entry_prec:
[[ IDENT "LEFTA" -> Some Gramext.LeftA
@@ -366,13 +372,8 @@ GEXTEND Gram
| [ ":"; IDENT "ast" -> () | -> () ] -> Ast.ETast ]]
;
set_entry_type:
- [[ ":"; et = entry_type -> set_default_action_parser et;
- let a = match et with
- | ConstrParser -> ETConstr
- | CasesPatternParser ->
- failwith "entry_type_of_parser: cases_pattern, TODO" in
- a
- | -> ETConstr ]]
+ [[ ":"; et = entry_type -> set_default_action_parser et
+ | -> () ]]
;
entry_type:
[[ IDENT "ast"; IDENT "list" -> Util.error "type ast list no longer supported"
diff --git a/parsing/g_cases.ml4 b/parsing/g_cases.ml4
index 1b8be4f4f..a7b27de23 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: constr1 pattern;
+ GLOBAL: constr pattern;
pattern:
[ [ r = Prim.reference -> CPatAtom (loc,Some r)
@@ -52,8 +52,7 @@ GEXTEND Gram
ne_eqn_list:
[ [ leqn = LIST1 equation SEP "|" -> leqn ] ]
;
-
- constr1:
+ constr: LEVEL "1"
[ [ "<"; p = lconstr; ">"; "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 8644cb724..6476cec51 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -52,12 +52,23 @@ let test_int_rparen =
end
| _ -> raise Stream.Failure)
+(* Hack to parse "n" at level 0 without conflicting with "n!" at level 91 *)
+(* admissible notation "(n)" *)
+let test_int_bang =
+ Gram.Entry.of_parser "test_int_bang"
+ (fun strm ->
+ match Stream.npeek 1 strm with
+ | [("INT", n)] ->
+ begin match Stream.npeek 2 strm with
+ | [_; ("", "!")] -> ()
+ | _ -> raise Stream.Failure
+ end
+ | _ -> raise Stream.Failure)
+
GEXTEND Gram
- GLOBAL: constr0 constr1 constr2 constr3 lassoc_constr4 constr5
- constr6 constr7 constr8 constr9 constr10 lconstr constr
- ne_name_comma_list ne_constr_list sort
- global constr_pattern Constr.ident;
+ GLOBAL: constr9 lconstr constr sort global constr_pattern Constr.ident
+ (*ne_name_comma_list*);
Constr.ident:
[ [ id = Prim.ident -> id
@@ -70,12 +81,6 @@ GEXTEND Gram
(* This is used in quotations *)
| id = METAIDENT -> Ident (loc,id_of_string id) ] ]
;
- constr:
- [ [ c = constr8 -> c ] ]
- ;
- lconstr:
- [ [ c = constr10 -> c ] ]
- ;
constr_pattern:
[ [ c = constr -> c ] ]
;
@@ -87,10 +92,47 @@ GEXTEND Gram
| "Prop" -> RProp Null
| "Type" -> RType None ] ]
;
- constr0:
- [ [ "?" -> CHole loc
+ constr:
+ [ "top" RIGHTA
+ [ c1 = constr; "->"; c2 = constr -> CArrow (loc, c1, c2) ]
+ | "1"
+ [ "<"; p = lconstr; ">"; IDENT "Match"; c = constr; "with";
+ cl = LIST0 constr; "end" ->
+ COrderedCase (loc, MatchStyle, Some p, c, cl)
+ | "<"; p = lconstr; ">"; IDENT "Case"; c = constr; "of";
+ cl = LIST0 constr; "end" ->
+ COrderedCase (loc, RegularStyle, Some p, c, cl)
+ | IDENT "Case"; c = constr; "of"; cl = LIST0 constr; "end" ->
+ COrderedCase (loc, RegularStyle, None, c, cl)
+ | 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"->
+ (* 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" ->
+ CLetIn (loc, na, c, c1)
+ | IDENT "if"; c1 = constr;
+ IDENT "then"; c2 = constr;
+ IDENT "else"; c3 = constr LEVEL "top" ->
+ COrderedCase (loc, IfStyle, None, c1, [c2; c3])
+ | "<"; p = lconstr; ">";
+ IDENT "let"; "("; b = ne_name_comma_list; ")"; "="; c = constr;
+ "in"; c1 = constr LEVEL "top" ->
+ (* TODO: right loc *)
+ COrderedCase (loc, LetStyle, Some p, c,
+ [CLambdaN (loc, [b, CHole loc], c1)])
+ | "<"; p = lconstr; ">";
+ IDENT "if"; c1 = constr;
+ IDENT "then"; c2 = constr;
+ IDENT "else"; c3 = constr LEVEL "top" ->
+ COrderedCase (loc, IfStyle, Some p, c1, [c2; c3]) ]
+ | "0"
+ [ "?" -> CHole loc
| "?"; n = Prim.natural -> CMeta (loc, n)
- | bll = binders; c = constr -> abstract_constr loc c bll
+ | bll = binders; c = constr LEVEL "top" -> abstract_constr loc c bll
(* Hack to parse syntax "(n)" as a natural number *)
| "("; test_int_rparen; n = INT; ")" ->
let n = CNumeral (loc,Bignat.POS (Bignat.of_string n)) in
@@ -99,7 +141,7 @@ GEXTEND Gram
let id = coerce_to_name lc1 in
CProdN (loc, ([id], c)::bl, body)
(* TODO: Syntaxe (_:t...)t et (_,x...)t *)
- | "("; lc1 = lconstr; ","; lc2 = lconstr; ":"; c = constr;
+ | "("; lc1 = lconstr; ","; lc2 = lconstr; ":"; c = constr;
(bl,body) = product_tail ->
let id1 = coerce_to_name lc1 in
let id2 = coerce_to_name lc2 in
@@ -124,70 +166,11 @@ GEXTEND Gram
| v = global -> CRef v
| n = INT -> CNumeral (loc,Bignat.POS (Bignat.of_string n))
| "-"; n = INT -> CNumeral (loc,Bignat.NEG (Bignat.of_string n))
- | "!"; f = global -> CAppExpl (loc,f,[])
- ] ]
- ;
- constr1:
- [ [ "<"; p = lconstr; ">"; IDENT "Match"; c = constr; "with";
- cl = LIST0 constr; "end" ->
- COrderedCase (loc, MatchStyle, Some p, c, cl)
- | "<"; p = lconstr; ">"; IDENT "Case"; c = constr; "of";
- cl = LIST0 constr; "end" ->
- COrderedCase (loc, RegularStyle, Some p, c, cl)
- | IDENT "Case"; c = constr; "of"; cl = LIST0 constr; "end" ->
- COrderedCase (loc, RegularStyle, None, c, cl)
- | 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->
- (* 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
- -> CLetIn (loc, na, c, c1)
- | IDENT "if"; c1 = constr; IDENT "then"; c2 = constr;
- IDENT "else"; c3 = constr ->
- COrderedCase (loc, IfStyle, None, c1, [c2; c3])
- | "<"; p = lconstr; ">";
- IDENT "let"; "("; b = ne_name_comma_list; ")"; "=";
- c = constr; "in"; c1 = constr ->
- (* TODO: right loc *)
- COrderedCase (loc, LetStyle, Some p, c,
- [CLambdaN (loc, [b, CHole loc], c1)])
- | "<"; p = lconstr; ">";
- IDENT "if"; c1 = constr; IDENT "then";
- c2 = constr; IDENT "else"; c3 = constr ->
- COrderedCase (loc, IfStyle, Some p, c1, [c2; c3])
- | c = constr0 -> c ] ]
- ;
- constr2: (* ~ will be here *)
- [ [ c = constr1 -> c ] ]
+ | "!"; f = global -> CAppExpl (loc,f,[]) ] ]
;
- constr3:
- [ [ c1 = constr2 -> c1 ] ]
- ;
- lassoc_constr4:
- [ [ c1 = constr3 -> c1 ] ]
- ;
- constr5:
- [ [ c1 = lassoc_constr4 -> c1 ] ]
- ;
- constr6: (* /\ will be here *)
- [ [ c1 = constr5 -> c1 ] ]
- ;
- constr7: (* \/ will be here *)
- [ RIGHTA [ c1 = constr6 -> c1 ] ]
- ;
- constr8: (* <-> will be here *)
- [ [ c1 = constr7 -> c1
- | c1 = constr7; "->"; c2 = constr8 -> CArrow (loc, c1, c2) ] ]
- ;
- constr9:
- [ [ c1 = constr8 -> c1
- | c1 = constr8; "::"; c2 = constr8 -> CCast (loc, c1, c2) ] ]
- ;
- constr10:
- [ [ "!"; f = global; args = LIST0 constr9 -> CAppExpl (loc, f, args)
+ lconstr:
+ [ "10"
+ [ "!"; f = global; args = LIST0 constr9 -> CAppExpl (loc, f, args)
(*
| "!"; f = global; "with"; b = binding_list ->
<:ast< (APPLISTWITH $f $b) >>
@@ -195,11 +178,19 @@ GEXTEND Gram
| f = constr9; args = LIST1 constr91 -> CApp (loc, f, args)
| f = constr9 -> f ] ]
;
+ constr91:
+ [ [ test_int_bang; n = INT; "!"; c = constr9 ->
+ (c, Some (int_of_string n))
+ | c = constr9 -> (c, None) ] ]
+ ;
+ constr9:
+ [ [ c1 = constr -> c1
+ | c1 = constr; "::"; c2 = constr -> CCast (loc, c1, c2) ] ]
+ ;
ne_name_comma_list:
[ [ nal = LIST1 name SEP "," -> nal ] ]
;
name_comma_list_tail:
-
[ [ ","; idl = ne_name_comma_list -> idl
| -> [] ] ]
;
@@ -241,12 +232,6 @@ GEXTEND Gram
[ [ ":"; c = constr -> c
| -> CHole loc ] ]
;
- constr91:
- [ [ n = natural; "!"; c = constr9 -> (c, Some n)
- | n = natural ->
- (CNumeral (loc, Bignat.POS (Bignat.of_string (string_of_int n))), None)
- | c = constr9 -> (c, None) ] ]
- ;
fixbinder:
[ [ id = base_ident; "/"; recarg = natural; ":"; type_ = constr;
":="; def = constr ->
diff --git a/parsing/g_proofs.ml4 b/parsing/g_proofs.ml4
index 52100764d..951e75815 100644
--- a/parsing/g_proofs.ml4
+++ b/parsing/g_proofs.ml4
@@ -108,7 +108,7 @@ GEXTEND Gram
| 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.constr8 ; tac = tactic ->
+ | IDENT "Extern"; n = natural; c = Constr.constr ; tac = tactic ->
fun name -> HintsExtern (name,n,c,tac) ] ]
;
hints:
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 36619758a..7a8f82478 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -403,9 +403,19 @@ GEXTEND Gram
Pp.warning "Class is obsolete"; VernacNop
(* Implicit *)
+(*
| IDENT "Syntactic"; "Definition"; id = base_ident; ":="; 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,c,l)
+ | None -> c in
+ VernacNotation ("'"^id^"'",c,[],None)
| IDENT "Implicits"; qid = global; "["; l = LIST0 natural; "]" ->
VernacDeclareImplicits (qid,Some l)
diff --git a/parsing/pcoq.ml4 b/parsing/pcoq.ml4
index 6472dbaf5..fa0c3809e 100644
--- a/parsing/pcoq.ml4
+++ b/parsing/pcoq.ml4
@@ -69,6 +69,7 @@ type typed_entry = entry_type * grammar_object G.Entry.e
let in_typed_entry t e = (t,Gramobj.weaken_entry e)
let type_of_typed_entry (t,e) = t
let object_of_typed_entry (t,e) = e
+let weaken_entry x = Gramobj.weaken_entry x
module type Gramtypes =
sig
@@ -169,21 +170,6 @@ let map_entry f en =
let parse_string f x =
let strm = Stream.of_string x in Gram.Entry.parse f (Gram.parsable strm)
-(*
-let entry_type ast =
- match ast with
- | Coqast.Id (_, "LIST") -> ETastl
- | Coqast.Id (_, "AST") -> ETast
- | _ -> invalid_arg "Ast.entry_type"
-*)
-
-(*
-let entry_type ast =
- match ast with
- | AstListType -> ETastl
- | _ -> ETast
-*)
-
type gram_universe = (string, typed_entry) Hashtbl.t
let trace = ref false
@@ -353,27 +339,12 @@ module Constr =
(* Entries that can be refered via the string -> Gram.Entry.e table *)
let constr = gec_constr "constr"
- let constr0 = gec_constr "constr0"
- let constr1 = gec_constr "constr1"
- let constr2 = gec_constr "constr2"
- let constr3 = gec_constr "constr3"
- let lassoc_constr4 = gec_constr "lassoc_constr4"
- let constr5 = gec_constr "constr5"
- let constr6 = gec_constr "constr6"
- let constr7 = gec_constr "constr7"
- let constr8 = gec_constr "constr8"
let constr9 = gec_constr "constr9"
- let constr91 = gec_constr "constr91"
- let constr10 = gec_constr "constr10"
let constr_eoi = eoi_entry constr
let lconstr = gec_constr "lconstr"
- let sort = make_gen_entry uconstr rawwit_sort "sort"
-
let ident = make_gen_entry uconstr rawwit_ident "ident"
let global = make_gen_entry uconstr rawwit_ref "global"
-
- let ne_name_comma_list = Gram.Entry.create "constr:ne_name_comma_list"
- let ne_constr_list = gec_constr_list "ne_constr_list"
+ let sort = make_gen_entry uconstr rawwit_sort "sort"
let pattern = Gram.Entry.create "constr:pattern"
let constr_pattern = gec_constr "constr_pattern"
end
@@ -520,3 +491,17 @@ let set_default_action_parser = function
let default_action_parser =
Gram.Entry.of_parser "default_action_parser"
(fun strm -> Gram.Entry.parse_token (get_default_action_parser ()) strm)
+
+let entry_of_type allow_create = function
+ | ETConstr (_,Some 10) -> weaken_entry Constr.lconstr, None
+ | ETConstr (_,Some 9) -> weaken_entry Constr.constr9, None
+ | ETConstr (_,lev) -> weaken_entry Constr.constr, lev
+ | ETIdent -> weaken_entry Constr.ident, None
+ | ETReference -> weaken_entry Constr.global, None
+ | ETOther (u,n) ->
+ let u = get_univ u in
+ let e =
+ try get_entry u n
+ with e when allow_create -> create_entry u n ConstrArgType in
+ object_of_typed_entry e, None
+ | ETPattern -> weaken_entry Constr.pattern, None
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index a0f5a55c0..d46a245ce 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -30,6 +30,10 @@ type typed_entry
val type_of_typed_entry : typed_entry -> Extend.entry_type
val object_of_typed_entry : typed_entry -> grammar_object Gram.Entry.e
+val weaken_entry : 'a Gram.Entry.e -> grammar_object Gram.Entry.e
+
+val entry_of_type :
+ bool -> constr_entry_type -> grammar_object Gram.Entry.e * int option
val grammar_extend :
'a Gram.Entry.e -> Gramext.position option ->
@@ -56,6 +60,7 @@ val get_univ : string -> string * gram_universe
val get_entry : string * gram_universe -> string -> typed_entry
val entry_type : string * gram_universe -> string -> entry_type option
+
val get_entry_type : string * string -> entry_type
val create_entry_if_new :
string * gram_universe -> string -> entry_type -> unit
@@ -118,30 +123,14 @@ module Prim :
module Constr :
sig
val constr : constr_expr Gram.Entry.e
- val constr0 : constr_expr Gram.Entry.e
- val constr1 : constr_expr Gram.Entry.e
- val constr2 : constr_expr Gram.Entry.e
- val constr3 : constr_expr Gram.Entry.e
- val lassoc_constr4 : constr_expr Gram.Entry.e
- val constr5 : constr_expr Gram.Entry.e
- val constr6 : constr_expr Gram.Entry.e
- val constr7 : constr_expr Gram.Entry.e
- val constr8 : constr_expr Gram.Entry.e
val constr9 : constr_expr Gram.Entry.e
- val constr91 : constr_expr Gram.Entry.e
- val constr10 : constr_expr Gram.Entry.e
val constr_eoi : constr_expr Gram.Entry.e
val lconstr : constr_expr Gram.Entry.e
val ident : identifier Gram.Entry.e
val global : reference Gram.Entry.e
- val ne_name_comma_list : name located list Gram.Entry.e
- val ne_constr_list : constr_expr list Gram.Entry.e
val sort : rawsort Gram.Entry.e
val pattern : cases_pattern_expr Gram.Entry.e
val constr_pattern : constr_expr Gram.Entry.e
-(*
- val ne_binders_list : local_binder list Gram.Entry.e
-*)
end
module Module :
diff --git a/parsing/ppconstr.ml b/parsing/ppconstr.ml
index baac4a06d..e49f531f1 100644
--- a/parsing/ppconstr.ml
+++ b/parsing/ppconstr.ml
@@ -73,7 +73,12 @@ let wrap_exception = function
let latom = 0
let lannot = 1
-let lprod = 8
+let lprod = 1
+let llambda = 1
+let lif = 1
+let lletin = 1
+let lcases = 1
+let larrow = 8
let lcast = 9
let lapp = 10
let ltop = (8,E)
@@ -98,7 +103,17 @@ let pr_notation pr s env =
let unpl, level = find_notation_printing_rule s in
prlist (print_hunk pr env) unpl, level
-let pr_delimiters x = failwith "pr_delimiters: TODO"
+let pr_delimiters sc strm =
+ match find_delimiters sc with
+ | None -> anomaly "Delimiters without concrete syntax"
+ | Some (left,right) ->
+ assert (left <> "" && right <> "");
+ let lspace =
+ if is_letter (left.[String.length left -1]) then str " " else mt () in
+ let rspace =
+ let c = right.[0] in
+ if is_letter c or is_digit c or c = '\'' then str " " else mt () in
+ str left ++ lspace ++ strm ++ rspace ++ str right
open Rawterm
@@ -118,7 +133,7 @@ let pr_explicitation = function
| Some n -> int n ++ str "!"
let pr_expl_args pr (a,expl) =
- pr_explicitation expl ++ pr (latom,E) a
+ pr_explicitation expl ++ pr (lapp,L) a
let pr_opt_type pr = function
| CHole _ -> mt ()
@@ -197,8 +212,8 @@ let pr_fix pr = pr_recursive "Fix" (pr_fixdecl pr)
let pr_cofix pr = pr_recursive "Fix" (pr_cofixdecl pr)
let rec pr_arrow pr = function
- | CArrow (_,a,b) -> pr (lprod,L) a ++ cut () ++ str "->" ++ pr_arrow pr b
- | a -> pr (lprod,E) a
+ | CArrow (_,a,b) -> pr (larrow,L) a ++ cut () ++ str "->" ++ pr_arrow pr b
+ | a -> pr (larrow,E) a
let pr_annotation pr t = str "<" ++ pr ltop t ++ str ">"
@@ -209,25 +224,26 @@ let rec pr inherited a =
| CRef r -> pr_reference r, latom
| CFix (_,id,fix) -> pr_fix pr (snd id) fix, latom
| CCoFix (_,id,cofix) -> pr_cofix pr (snd id) cofix, latom
- | CArrow _ -> hv 0 (pr_arrow pr a), lprod
+ | CArrow _ -> hv 0 (pr_arrow pr a), larrow
| CProdN (_,bl,a) ->
hov 0 (
str "(" ++ pr_binders pr bl ++ str ")" ++ brk(0,1) ++ pr ltop a), lprod
| CLambdaN (_,bl,a) ->
hov 0 (
- str "[" ++ pr_binders pr bl ++ str "]" ++ brk(0,1) ++ pr ltop a), lprod
+ str "[" ++ pr_binders pr bl ++ str "]" ++ brk(0,1) ++ pr ltop a),
+ llambda
| CLetIn (_,x,a,b) ->
- hov 0 (pr_let_binder pr (snd x) a ++ cut () ++ pr ltop b), lprod
+ hov 0 (pr_let_binder pr (snd x) a ++ cut () ++ pr ltop b), lletin
| CAppExpl (_,f,l) ->
hov 0 (
- str "!" ++ pr_reference f ++
- prlist (fun a -> brk (1,1) ++ pr (latom,E) a) l), lapp
+ str "!" ++ pr_reference f ++
+ prlist (fun a -> brk (1,1) ++ pr (lapp,L) a) l), lapp
| CApp (_,a,l) ->
hov 0 (
pr (latom,E) a ++
prlist (fun a -> brk (1,1) ++ pr_expl_args pr a) l), lapp
| CCases (_,po,c,eqns) ->
- pr_cases po c eqns, lannot
+ pr_cases po c eqns, lcases
| COrderedCase (_,IfStyle,po,c,[b1;b2]) ->
(* On force les parenthèses autour d'un "if" sous-terme (même si le
parsing est lui plus tolérant) *)
@@ -236,7 +252,7 @@ let rec pr inherited a =
hv 0 (
str "if" ++ pr ltop c ++ spc () ++
hov 0 (str "then" ++ brk (1,1) ++ pr ltop b1) ++ spc () ++
- hov 0 (str "else" ++ brk (1,1) ++ pr ltop b2))), lapp
+ hov 0 (str "else" ++ brk (1,1) ++ pr ltop b2))), lif
| COrderedCase (_,LetStyle,po,c,[CLambdaN(_,[_,_ as bd],b)]) ->
hov 0 (
pr_opt (pr_annotation pr) po ++
@@ -245,7 +261,7 @@ let rec pr inherited a =
hov 0 (str "(" ++ pr_binder pr bd ++ str ")") ++
str "=" ++ brk (1,1) ++
pr ltop c ++ spc () ++
- str "in " ++ pr ltop b)), lapp
+ str "in " ++ pr ltop b)), lletin
| COrderedCase (_,(MatchStyle|RegularStyle as style),po,c,bl) ->
hov 0 (
hov 0 (
@@ -256,7 +272,7 @@ let rec pr inherited a =
str (if style=RegularStyle then "of" else "with") ++
brk (1,3) ++
hov 0 (prlist (fun b -> pr ltop b ++ fnl ()) bl)) ++
- str "end")), lannot
+ str "end")), lcases
| COrderedCase (_,_,_,_,_) ->
anomaly "malformed if or destructuring let"
| CHole _ -> str "?", latom
@@ -267,8 +283,7 @@ let rec pr inherited a =
| CNotation (_,s,env) -> pr_notation pr s env
| CGrammar _ -> failwith "CGrammar: TODO"
| CNumeral (_,p) -> Bignat.pr_bigint p, latom
- | CDelimiters (_,sc,a) -> failwith "pr_delim: TODO"
-(* pr_delimiters (find_delimiters) (pr_constr_expr a)*)
+ | CDelimiters (_,sc,a) -> pr_delimiters sc (pr ltop a), latom
| CDynamic _ -> str "<dynamic>", latom
in
if prec_less prec inherited then strm
@@ -352,8 +367,10 @@ let gentermpr gt =
(* [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/printer.ml b/parsing/printer.ml
index 6305cd650..7777ac540 100644
--- a/parsing/printer.ml
+++ b/parsing/printer.ml
@@ -76,7 +76,10 @@ let pr_ref_label = function (* On triche sur le contexte *)
| 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
diff --git a/theories/Reals/Rsyntax.v b/theories/Reals/Rsyntax.v
index 6cc0d71c4..77ecf144d 100644
--- a/theories/Reals/Rsyntax.v
+++ b/theories/Reals/Rsyntax.v
@@ -199,7 +199,7 @@ Syntax constr
(* For parsing/printing based on scopes *)
Module R_scope.
-Delimiters "'R:" R_scope "'".
+Delimits Scope R_scope with R.
Infix NONA 5 "<=" Rle : R_scope.
Infix NONA 5 "<" Rlt : R_scope.
Infix NONA 5 ">=" Rge : R_scope.
@@ -209,12 +209,17 @@ Infix 4 "-" Rminus : R_scope.
Infix 3 "*" Rmult : R_scope.
Infix LEFTA 3 "/" Rdiv : R_scope.
Distfix 0 "- _" Ropp : R_scope.
-Notation NONA 5 "x == y == z" (eqT R x y)/\(eqT R y z) (y at level 4): R_scope.
-Notation NONA 5 "x <= y <= z" (Rle x y)/\(Rle y z) (y at level 4) : R_scope.
-Notation NONA 5 "x <= y < z" (Rle x y)/\(Rlt y z) (y at level 4) : R_scope.
-Notation NONA 5 "x < y < z" (Rlt x y)/\(Rlt y z) (y at level 4) : R_scope.
-Notation NONA 5 "x < y <= z" (Rlt x y)/\(Rle y z) (y at level 4) : R_scope.
-Notation NONA 5 "x <> y" ~(eqT R x y) : R_scope.
+Notation "x == y == z" := (eqT R x y)/\(eqT R y z)
+ (at level 5, y at level 4): R_scope.
+Notation "x <= y <= z" := (Rle x y)/\(Rle y z)
+ (at level 5, y at level 4) : R_scope.
+Notation "x <= y < z" := (Rle x y)/\(Rlt y z)
+ (at level 5, y at level 4) : R_scope.
+Notation "x < y < z" := (Rlt x y)/\(Rlt y z)
+ (at level 5, y at level 4) : R_scope.
+Notation "x < y <= z" := (Rlt x y)/\(Rle y z)
+ (at level 5, y at level 4) : R_scope.
+Notation "x <> y" := ~(eqT R x y) (at level 5) : R_scope.
Distfix 0 "/ _" Rinv : R_scope.
(* Warning: this hides sum and prod and breaks sumor symbolic notation *)
diff --git a/theories/ZArith/Zsyntax.v b/theories/ZArith/Zsyntax.v
index ef9647413..760c1fc89 100644
--- a/theories/ZArith/Zsyntax.v
+++ b/theories/ZArith/Zsyntax.v
@@ -219,23 +219,34 @@ Syntax constr
(* For parsing/printing based on scopes *)
Module Z_scope.
-Delimiters "'Z:" Z_scope "'".
-Infix 4 "+" Zplus : Z_scope.
-Infix 4 "-" Zminus : Z_scope.
-Infix 3 "*" Zmult : Z_scope.
+(* Declare Scope positive_scope with Key P. *)
+
+Delimits Scope positive_scope with P.
+Delimits Scope Z_scope with Z.
+
+Infix LEFTA 4 "+" Zplus : Z_scope.
+Infix LEFTA 4 "-" Zminus : Z_scope.
+Infix LEFTA 3 "*" Zmult : Z_scope.
Distfix 0 "- _" Zopp : Z_scope.
-Infix NONA 5 "<=" Zle : Z_scope.
-Infix NONA 5 "<" Zlt : Z_scope.
-Infix NONA 5 ">=" Zge : Z_scope.
+Infix 5 "<=" Zle : Z_scope.
+Infix 5 "<" Zlt : Z_scope.
+Infix 5 ">=" Zge : Z_scope.
(*Infix NONA 5 ">" Zgt : Z_scope. (* Conflicts with "<..>Cases ... " *) *)
-Infix NONA 5 "?=" Zcompare : Z_scope.
-Notation NONA 5 "x <= y <= z" (Zle x y)/\(Zle y z) (y at level 4) : Z_scope.
-Notation NONA 5 "x <= y < z" (Zle x y)/\(Zlt y z) (y at level 4) : Z_scope.
-Notation NONA 5 "x < y < z" (Zlt x y)/\(Zlt y z) (y at level 4) : Z_scope.
-Notation NONA 5 "x < y <= z" (Zlt x y)/\(Zle y z) (y at level 4) : Z_scope.
-Notation NONA 5 "x <> y" ~(eq Z x y) : Z_scope.
-(* Notation NONA 1 "| x |" (Zabs x) : Z_scope.(* "|" conflicts with THENS *)*)
-Notation NONA 1 "|| x ||" (Zabs x) : Z_scope.
+Infix 5 "?=" Zcompare : Z_scope.
+Notation "x <= y <= z" := (Zle x y)/\(Zle y z)
+ (at level 5, y at level 4):Z_scope.
+Notation "x <= y < z" := (Zle x y)/\(Zlt y z)
+ (at level 5, y at level 4):Z_scope.
+Notation "x < y < z" := (Zlt x y)/\(Zlt y z)
+ (at level 5, y at level 4):Z_scope.
+Notation "x < y <= z" := (Zlt x y)/\(Zle y z)
+ (at level 5, y at level 4):Z_scope.
+Notation "x = y = z" := x=y/\y=z
+ (at level 5, y at level 4):Z_scope.
+
+Notation "x <> y" := ~(eq Z x y) (at level 5) : Z_scope.
+(* Notation "| x |" (Zabs x) : Z_scope.(* "|" conflicts with THENS *)*)
+Notation "|| x ||" := (Zabs x) (at level 1) : Z_scope.
(* Warning: this hides sum and prod and breaks sumor symbolic notation *)
Open Scope Z_scope.
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index 4da4a83bc..858add3c7 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -63,7 +63,7 @@ let make_aconstr vars a =
(idl,pat,aux rhs) in
ACases (option_app aux tyopt,List.map aux tml, List.map f eqnl)
| ROrderedCase (_,b,tyopt,tm,bv) ->
- AOldCase (b,option_app aux tyopt,aux tm, Array.map aux bv)
+ AOrderedCase (b,option_app aux tyopt,aux tm, Array.map aux bv)
| RCast (_,c,t) -> ACast (aux c,aux t)
| RSort (_,s) -> ASort s
| RHole (_,w) -> AHole w
@@ -76,7 +76,7 @@ allowed in abbreviatable expressions"
let a = aux a in
let find_type x =
if List.mem x !bound_binders then (x,ETIdent) else
- if List.mem x !bound_vars then (x,ETConstr) else
+ if List.mem x !bound_vars then (x,ETConstr ((10,E),None)) else
error ((string_of_id x)^" is unbound in the right-hand-side") in
let typs = List.map find_type vars in
(a, typs)
@@ -97,6 +97,8 @@ let _ = set_ast_to_rawconstr
*)
a)
+(** For old ast printer *)
+
(* Pretty-printer state summary *)
let _ =
declare_summary "syntax"
@@ -166,15 +168,17 @@ let (inGrammar, outGrammar) =
export_function = (fun x -> Some x)}
open Genarg
-let gram_define_entry (u,_ as univ) (nt,et,assoc,rl) =
+
+let check_entry_type (u,n) =
if u = "tactic" or u = "vernac" then error "tactic and vernac not supported";
- create_entry_if_new univ nt (entry_type_of_constr_entry_type et);
- (nt, et, assoc, rl)
+ match entry_type (get_univ u) n with
+ | None -> Pcoq.create_entry_if_new (get_univ u) n ConstrArgType
+ | Some (ConstrArgType | IdentArgType | RefArgType) -> ()
+ | _ -> error "Cannot arbitrarily extend non constr/ident/ref entries"
-let add_grammar_obj univ l =
+let add_grammar_obj univ entryl =
let u = create_univ_if_new univ in
- let entryl = List.map (gram_define_entry u) l in
- let g = interp_grammar_command univ get_entry_type entryl in
+ let g = interp_grammar_command univ check_entry_type entryl in
Lib.add_anonymous_leaf (inGrammar (Egrammar.Grammar g))
let add_tactic_grammar g =
@@ -183,33 +187,49 @@ let add_tactic_grammar g =
(* printing grammar entries *)
let print_grammar univ entry =
let u = get_univ univ in
- let te = get_entry u entry in
- Gram.Entry.print (object_of_typed_entry te)
+ let typ = explicitize_entry (fst u) entry in
+ let te,_ = entry_of_type false typ in
+ Gram.Entry.print te
(* Infix, distfix, notations *)
+type token = WhiteSpace of int | String of string
+
let split str =
+ let push_token beg i l =
+ if beg == i then l else String (String.sub str beg (i - beg)) :: l
+ in
+ let push_whitespace beg i l =
+ if beg = i then l else WhiteSpace (i-beg) :: l
+ in
let rec loop beg i =
if i < String.length str then
if str.[i] == ' ' then
- if beg == i then
- loop (succ beg) (succ i)
- else
- String.sub str beg (i - beg) :: loop (succ i) (succ i)
- else
+ push_token beg i (loop_on_whitespace (succ i) (succ i))
+ else
loop beg (succ i)
- else if beg == i then
- []
else
- [String.sub str beg (i - beg)]
+ push_token beg i []
+ and loop_on_whitespace beg i =
+ if i < String.length str then
+ if str.[i] <> ' ' then
+ push_whitespace beg i (loop i (succ i))
+ else
+ loop_on_whitespace beg (succ i)
+ else
+ push_whitespace beg i []
in
loop 0 0
(* Build the syntax and grammar rules *)
+type printing_precedence = int * parenRelation
+type parsing_precedence = int option
+
type symbol =
| Terminal of string
- | NonTerminal of (int * parenRelation) * identifier
+ | NonTerminal of identifier
+ | Break of int
let prec_assoc = function
| Some(Gramext.RightA) -> (L,E)
@@ -217,46 +237,67 @@ let prec_assoc = function
| Some(Gramext.NonA) -> (L,L)
| None -> (L,L) (* NONA by default *)
-let constr_tab =
- [| "constr0"; "constr1"; "constr2"; "constr3"; "lassoc_constr4";
- "constr5"; "constr6"; "constr7"; "constr"; "constr9"; "lconstr";
- "pattern" |]
-
let level_rule (n,p) = if p = E then n else max (n-1) 0
-let constr_rule np = constr_tab.(level_rule np)
+(* Find the digit code of the main entry of a sub-level and its associativity
+ (i.e. [9] means "constr9", [10] means "lconstr", [11] means "pattern",
+ otherwise "constr") *)
-let nonterm_meta nt var x =
- match x with
- | ETIdent -> NonTerm(ProdPrimitive ("constr","ident"), Some (var,x))
- | ETConstr -> NonTerm(ProdPrimitive ("constr",nt), Some (var,x))
- | ETReference -> NonTerm(ProdPrimitive ("constr","global"), Some (var,x))
+let constr_rule = function
+ | (9|10 as n,E) -> Some n
+ | (9,L) -> None
+ | (10,L) -> Some 9
+ | (11,E) -> Some 11
+ | _ -> None
(* For old ast printer *)
let meta_pattern m = Pmeta(m,Tany)
+open Symbols
+
+type white_status = NextMaybeLetter | NoSpace | AddBrk of int
+
+let add_break l = function
+ | AddBrk n -> UNP_BRK (n,1) :: l
+ | _ -> l
+
+let precedence_of_entry_type = function
+ | ETConstr (prec,_) -> prec
+ | _ -> 0,E
+
(* For old ast printer *)
-let make_hunks_ast symbols =
+let make_hunks_ast symbols etyps from =
+ let (_,l) =
List.fold_right
- (fun it l -> match it with
- | NonTerminal ((_,lp),m) -> PH (meta_pattern (string_of_id m), None, lp) :: l
+ (fun it (ws,l) -> match it with
+ | NonTerminal m ->
+ let (_,lp) = precedence_of_entry_type (List.assoc m etyps) in
+ let u = PH (meta_pattern (string_of_id m), None, lp) in
+ let l' = u :: (add_break l ws) in
+ ((if from = 10 (* lconstr *) then AddBrk 1 else NextMaybeLetter), l')
| Terminal s ->
- let n,s =
- if is_letter (s.[String.length s -1]) or is_letter (s.[0])
- then 1,s^" " else 0,s
- in
- UNP_BRK (n, 1) :: RO s :: l)
- symbols []
-
-open Symbols
-
-type white_status = NextMaybeLetter | NextIsNotLetter | AddBrk of int
+ let l' = add_break l ws in
+ if from = 10 (* lconstr *) then (AddBrk 1, RO s :: l')
+ else
+ let n = if is_letter (s.[0]) then 1 else 0 in
+ let s =
+ if (ws = NextMaybeLetter or ws = AddBrk 1)
+ & is_letter (s.[String.length s -1])
+ then s^" "
+ else s
+ in
+ (AddBrk n, RO s :: l')
+ | Break n ->
+ (NoSpace, UNP_BRK (n,1) :: l))
+ symbols (NoSpace,[])
+ in l
-let make_hunks symbols =
+let make_hunks etyps symbols =
let (_,l) =
List.fold_right
(fun it (ws,l) -> match it with
- | NonTerminal (prec,m) ->
+ | NonTerminal m ->
+ let prec = precedence_of_entry_type (List.assoc m etyps) in
let u = UnpMetaVar (m,prec) in
let l' = match ws with
| AddBrk n -> UnpCut (PpBrk(n,1)) :: u :: l
@@ -270,7 +311,9 @@ let make_hunks symbols =
then s^" "
else s
in
- (AddBrk n, UnpTerminal s :: l))
+ (AddBrk n, UnpTerminal s :: l)
+ | Break n ->
+ (NoSpace, UnpCut (PpBrk (n,1)) :: l))
symbols (NextMaybeLetter,[])
in l
@@ -278,49 +321,60 @@ let string_of_prec (n,p) =
(string_of_int n)^(match p with E -> "E" | L -> "L" | _ -> "")
let string_of_symbol = function
- | NonTerminal (lp,_) -> "_"
- | Terminal s -> s
+ | NonTerminal _ -> ["_"]
+ | Terminal s -> [s]
+ | Break _ -> []
-let assoc_of_symbol s l = match s with
- | NonTerminal (lp,_) -> level_rule lp :: l
- | Terminal _ -> l
+let assoc_of_type = function
+ | (_,ETConstr (lp,_)) -> level_rule lp
+ | _ -> 0
let string_of_assoc = function
| Some(Gramext.RightA) -> "RIGHTA"
| Some(Gramext.LeftA) | None -> "LEFTA"
| Some(Gramext.NonA) -> "NONA"
-let make_symbolic assoc n symbols =
- (n, List.fold_right assoc_of_symbol symbols []),
- (String.concat " " (List.map string_of_symbol symbols))
-
-let make_production typs =
- List.map (function
- | NonTerminal (lp,m) -> nonterm_meta (constr_rule lp) m (List.assoc m typs)
- | Terminal s -> Term (Extend.terminal s))
+let make_symbolic assoc n symbols etyps =
+ (n,List.map assoc_of_type etyps),
+ (String.concat " " (List.flatten (List.map string_of_symbol symbols)))
-(*
-let create_meta n = "$e"^(string_of_int n)
-*)
+let make_production etyps symbols =
+ List.fold_right
+ (fun t l -> match t with
+ | NonTerminal m ->
+ let typ = List.assoc m etyps in
+ NonTerm (ProdPrimitive typ, Some (m,typ)) :: l
+ | Terminal s ->
+ Term (Extend.terminal s) :: l
+ | Break _ ->
+ l)
+ symbols []
let strip s =
let n = String.length s in
if n > 2 & s.[0] = '\'' & s.[n-1] = '\'' then String.sub s 1 (n-2) else s
-let is_symbol s = not (is_letter s.[0])
-
-let rec find_symbols c_first c_next c_last vars varprecl = function
+(* To protect alphabetic tokens from being seen as variables *)
+let quote x =
+ let n = String.length x in
+ if n > 0 &
+ (is_letter x.[0] or is_letter x.[n-1] or is_digit x.[n-1] or x.[n-1]='\'')
+ then
+ "\'"^x^"\'"
+ else
+ x
+
+let is_symbol = function String s -> not (is_letter s.[0]) | _ -> false
+
+let rec find_symbols c_first c_last vars = function
| [] -> (vars, [])
- | x::sl when is_letter x.[0] ->
+ | String x :: sl when is_letter x.[0] ->
let id = Names.id_of_string x in
- if List.mem id vars then error ("Variable "^x^" occurs more than once");
- let prec =
- try (List.assoc x varprecl,E)
- with Not_found ->
- if List.exists is_symbol sl then c_first else c_last in
- let (vars,l) =
- find_symbols c_next c_next c_last vars varprecl sl in
- (id::vars, NonTerminal (prec,id) :: l)
+ if List.mem_assoc id vars then
+ error ("Variable "^x^" occurs more than once");
+ let prec = if List.exists is_symbol sl then c_first else c_last in
+ let (vars,l) = find_symbols None c_last vars sl in
+ ((id,prec)::vars, NonTerminal id :: l)
(*
| "_"::sl ->
warning "Found '_'";
@@ -330,19 +384,22 @@ let rec find_symbols c_first c_next c_last vars varprecl = function
let meta = create_meta new_var in
(vars, NonTerminal (prec, meta) :: l)
*)
- | s :: sl ->
- let (vars,l) = find_symbols c_next c_next c_last vars varprecl sl in
+ | String s :: sl ->
+ let (vars,l) = find_symbols None c_last vars sl in
(vars, Terminal (strip s) :: l)
+ | WhiteSpace n :: sl ->
+ let (vars,l) = find_symbols c_first c_last vars sl in
+ (vars, Break n :: l)
-let make_grammar_rule n typs symbols ntn =
+let make_grammar_rule n assoc typs symbols ntn =
let prod = make_production typs symbols in
- ((if n=8 then "constr8" else constr_rule (n,E)),ntn,prod)
+ (n,assoc,ntn,prod)
(* For old ast printer *)
let metas_of sl =
List.fold_right
(fun it metatl -> match it with
- | NonTerminal (_,m) -> m::metatl
+ | NonTerminal m -> m::metatl
| _ -> metatl)
sl []
@@ -352,31 +409,33 @@ let make_pattern symbols ast =
fst (to_pat env ast)
(* For old ast printer *)
-let make_syntax_rule n name symbols ast ntn sc =
+let make_syntax_rule n name symbols typs ast ntn sc =
[{syn_id = name;
syn_prec = n;
syn_astpat = make_pattern symbols ast;
- syn_hunks = [UNP_SYMBOLIC(sc,ntn,UNP_BOX (PpHOVB 1, make_hunks_ast symbols))]}]
+ syn_hunks =
+ [UNP_SYMBOLIC(sc,ntn,UNP_BOX (PpHOVB 1,make_hunks_ast symbols typs n))]}]
-let make_pp_rule symbols =
- [UnpBox (PpHOVB 1, make_hunks symbols)]
+let make_pp_rule symbols typs =
+ [UnpBox (PpHOVB 1, make_hunks symbols typs)]
(**************************************************************************)
(* Syntax extenstion: common parsing/printing rules and no interpretation *)
let cache_syntax_extension (_,(prec,ntn,gr,se)) =
- if not (Symbols.exists_notation prec ntn) then begin
- Egrammar.extend_grammar (Egrammar.Notation gr);
- Symbols.declare_printing_rule ntn (se,fst prec)
- end
+ Egrammar.extend_grammar (Egrammar.Notation gr);
+ if se<>None then
+ Symbols.declare_notation_printing_rule ntn (out_some se,fst prec)
let subst_notation_grammar subst x = x
let subst_printing_rule subst x = x
let subst_syntax_extension (_,subst,(prec,ntn,gr,se)) =
- (prec,ntn,subst_notation_grammar subst gr,subst_printing_rule subst se)
+ (prec,ntn,
+ subst_notation_grammar subst gr,
+ option_app (subst_printing_rule subst) se)
let (inSyntaxExtension, outSyntaxExtension) =
declare_object {(default_object "SYNTAX-EXTENSION") with
@@ -387,75 +446,100 @@ let (inSyntaxExtension, outSyntaxExtension) =
export_function = (fun x -> Some x)}
let interp_syntax_modifiers =
- let rec interp assoc precl level etyps = function
+ let onlyparsing = ref false in
+ let rec interp assoc level etyps = function
| [] ->
let n = match level with None -> 1 | Some n -> n in
- (assoc,precl,n,etyps)
- | SetItemLevel (id,n) :: l ->
- if List.mem_assoc id precl then error (id^"has already a precedence")
- else interp assoc ((id,n)::precl) level etyps l
+ (assoc,n,etyps,!onlyparsing)
+ | SetEntryType (s,typ) :: l ->
+ let id = id_of_string s in
+ if List.mem_assoc id etyps then
+ error (s^" is already assigned to an entry or constr level")
+ else interp assoc level ((id,typ)::etyps) l
+ | SetItemLevel ([],n) :: l ->
+ interp assoc level etyps l
+ | SetItemLevel (s::idl,n) :: l ->
+ let id = id_of_string s in
+ if List.mem_assoc id etyps then
+ error (s^" is already assigned to an entry or constr level")
+ else
+ let typ = ETConstr ((n,E), Some n) in
+ interp assoc level ((id,typ)::etyps) (SetItemLevel (idl,n)::l)
| SetLevel n :: l ->
- if level <> None then error "already a level"
- else interp assoc precl (Some n) etyps l
+ if level <> None then error "A level is mentioned more than twice"
+ else interp assoc (Some n) etyps l
| SetAssoc a :: l ->
if assoc <> None then error "already an associativity"
- else interp (Some a) precl level etyps l
- | SetEntryType (s,typ) :: l ->
- let id = id_of_string s in
- if List.mem_assoc id etyps then error (s^"has already an entry type")
- else interp assoc precl level ((id,typ)::etyps) l
- in interp None [] None []
+ else interp (Some a) level etyps l
+ | SetOnlyParsing :: l ->
+ onlyparsing := true;
+ interp assoc level etyps l
+ in interp None None []
+
+(* 2nd list of types has priority *)
+let rec merge_entry_types etyps' = function
+ | [] -> etyps'
+ | (x,_ as e)::etyps ->
+ e :: merge_entry_types (List.remove_assoc x etyps') etyps
+
+let set_entry_type etyps (x,typ) =
+ let typ = match typ with
+ | None ->
+ (try List.assoc x etyps
+ with Not_found -> ETConstr ((10,E), Some 10))
+ | Some typ ->
+ let typ = ETConstr (typ,constr_rule typ) in
+ try List.assoc x etyps
+ with Not_found -> typ in
+ (x,typ)
let add_syntax_extension df modifiers =
- let (assoc,varprecl,n,etyps) = interp_syntax_modifiers modifiers in
+ let (assoc,n,etyps,onlyparse) = interp_syntax_modifiers modifiers in
let (lp,rp) = prec_assoc assoc in
- let (ids,symbs) = find_symbols (n,lp) (10,E) (n,rp) [] varprecl (split df) in
- let (prec,notation) = make_symbolic assoc n symbs in
- let gram_rule = make_grammar_rule n etyps symbs notation in
- let pp_rule = make_pp_rule symbs in
- Lib.add_anonymous_leaf (inSyntaxExtension(prec,notation,gram_rule,pp_rule))
+ let (typs,symbs) = find_symbols (Some (n,lp)) (Some (n,rp)) [] (split df) in
+ let typs = List.map (set_entry_type etyps) typs in
+ let (prec,notation) = make_symbolic assoc n symbs typs in
+ let gram_rule = make_grammar_rule n assoc typs symbs notation in
+ let pp_rule = if onlyparse then None else Some (make_pp_rule typs symbs) in
+ if not (Symbols.exists_notation prec notation) then
+ Lib.add_anonymous_leaf (inSyntaxExtension(prec,notation,gram_rule,pp_rule))
(**********************************************************************)
(* Distfix, Infix, Notations *)
(* A notation comes with a grammar rule, a pretty-printing rule, an
identifiying pattern called notation and an associated scope *)
-let load_infix _ (_,(gr,_,se,prec,ntn,scope,pat)) =
+let load_notation _ (_,(_,prec,ntn,scope,_,pat,onlyparse,_)) =
Symbols.declare_scope scope
-let open_infix i (_,(gr,oldse,se,prec,ntn,scope,pat)) =
+let open_notation i (_,(oldse,prec,ntn,scope,metas,pat,onlyparse,df)) =
if i=1 then begin
let b = Symbols.exists_notation_in_scope scope prec ntn pat in
- (* Declare the printer rule and its interpretation *)
- if not b then Esyntax.add_ppobject {sc_univ="constr";sc_entries=oldse};
- (* Declare the grammar and printing rules ... *)
- if not (Symbols.exists_notation prec ntn) then begin
- Egrammar.extend_grammar (Egrammar.Notation gr);
- Symbols.declare_printing_rule ntn (se,fst prec)
- end;
- (* ... and their interpretation *)
+ (* Declare the old printer rule and its interpretation *)
+ if not b & oldse <> None then
+ Esyntax.add_ppobject {sc_univ="constr";sc_entries=out_some oldse};
+ (* Declare the interpretation *)
if not b then
- Symbols.declare_notation ntn scope (pat,prec);
+ Symbols.declare_notation ntn scope (metas,pat) prec df onlyparse;
end
-let cache_infix o =
- load_infix 1 o;
- open_infix 1 o
+let cache_notation o =
+ load_notation 1 o;
+ open_notation 1 o
-let subst_infix (_,subst,(gr,oldse,se,prec,ntn,scope,pat)) =
- (subst_notation_grammar subst gr,
- list_smartmap (Extend.subst_syntax_entry Ast.subst_astpat subst) oldse,
- subst_printing_rule subst se,
+let subst_notation (_,subst,(oldse,prec,ntn,scope,metas,pat,b,df)) =
+ (option_app
+ (list_smartmap (Extend.subst_syntax_entry Ast.subst_astpat subst)) oldse,
prec,ntn,
scope,
- subst_aconstr subst pat)
-
-let (inInfix, outInfix) =
- declare_object {(default_object "INFIX") with
- open_function = open_infix;
- cache_function = cache_infix;
- subst_function = subst_infix;
- load_function = load_infix;
+ metas,subst_aconstr subst pat, b, df)
+
+let (inNotation, outNotation) =
+ declare_object {(default_object "NOTATION") with
+ open_function = open_notation;
+ cache_function = cache_notation;
+ subst_function = subst_notation;
+ load_function = load_notation;
classify_function = (fun (_,o) -> Substitute o);
export_function = (fun x -> Some x)}
@@ -473,56 +557,71 @@ let rec reify_meta_ast vars = function
| Dynamic _ as a -> (* Hum... what to do here *) a
(* For old ast syntax *)
-let make_old_pp_rule n symbols r ntn scope vars =
+let make_old_pp_rule n symbols typs r ntn scope vars =
let ast = Termast.ast_of_rawconstr r in
let ast = reify_meta_ast vars ast in
let rule_name = ntn^"_"^scope^"_notation" in
- make_syntax_rule n rule_name symbols ast ntn scope
-
-let add_notation df ast modifiers sc =
- let (assoc,varprecl,n,_) = interp_syntax_modifiers modifiers in
+ make_syntax_rule n rule_name symbols typs ast ntn scope
+
+let add_notation df a modifiers sc =
+ let toks = split df in
+ let (assoc,n,etyps,onlyparse) =
+ if modifiers = [] &
+ match toks with [String x] when quote(strip x) = x -> true | _ -> false
+ then
+ (* Means a Syntactic Definition *)
+ (None,0,[],false)
+ else
+ interp_syntax_modifiers modifiers
+ in
let scope = match sc with None -> Symbols.default_scope | Some sc -> sc in
let (lp,rp) = prec_assoc assoc in
- let (vars,symbols) =
- find_symbols (n,lp) (10,E) (n,rp) [] varprecl (split df) in
- let (prec,notation) = make_symbolic assoc n symbols in
+ let (typs,symbols) = find_symbols (Some (n,lp)) (Some (n,rp)) [] toks in
+ let vars = List.map fst typs in
(* To globalize... *)
- let r = interp_rawconstr_gen Evd.empty (Global.env()) [] false vars ast in
- let a,typs = make_aconstr vars r in
- let typs =
- List.map (fun (x,t) ->
- (x,if List.mem_assoc (string_of_id x) varprecl then ETConstr else t))
- typs
- in
- let gram_rule = make_grammar_rule n typs symbols notation in
- let pp_rule = make_pp_rule symbols in
- let old_pp_rule = make_old_pp_rule n symbols r notation scope vars in
- Lib.add_anonymous_leaf (inInfix(gram_rule,old_pp_rule,pp_rule,prec,notation,scope,a))
+ let r = interp_rawconstr_gen Evd.empty (Global.env()) [] false vars a in
+ let a,_ = make_aconstr vars r in
+(*
+ let a,etyps' = make_aconstr vars r in
+ let etyps = merge_entry_types etyps' etyps in
+*)
+ let typs = List.map (set_entry_type etyps) typs in
+ (* Declare the parsing and printing rules if not already done *)
+ let (prec,notation) = make_symbolic assoc n symbols typs in
+ let gram_rule = make_grammar_rule n assoc typs symbols notation in
+ let pp_rule = if onlyparse then None else Some (make_pp_rule typs symbols) in
+ if not (Symbols.exists_notation prec notation) then
+ Lib.add_anonymous_leaf (inSyntaxExtension(prec,notation,gram_rule,pp_rule));
+ let old_pp_rule =
+ if onlyparse then None
+ else Some (make_old_pp_rule n symbols typs r notation scope vars) in
+ (* Declare the interpretation *)
+ Lib.add_anonymous_leaf
+ (inNotation(old_pp_rule,prec,notation,scope,vars,a,onlyparse,df))
(* TODO add boxes information in the expression *)
let inject_var x = CRef (Ident (dummy_loc, id_of_string x))
-(* To protect alphabetic tokens from being seen as variables *)
-let quote x = "\'"^x^"\'"
-
let rec rename x vars n = function
| [] ->
(vars,[])
- | "_"::l ->
+ | String "_"::l ->
let (vars,l) = rename x vars (n+1) l in
let xn = x^(string_of_int n) in
((inject_var xn)::vars,xn::l)
- | y::l ->
+ | String y::l ->
let (vars,l) = rename x vars n l in (vars,(quote y)::l)
+ | WhiteSpace _::l ->
+ rename x vars n l
let add_distfix assoc n df r sc =
- (* "x" cannot clash since ast is globalized (included section vars) *)
+ (* "x" cannot clash since r is globalized (included section vars) *)
let (vars,l) = rename "x" [] 1 (split df) in
let df = String.concat " " l in
- let ast = mkAppC (mkRefC r, vars) in
- let a = match assoc with None -> Gramext.LeftA | Some a -> a in
- add_notation df ast [SetAssoc a;SetLevel n] sc
+ let a = mkAppC (mkRefC r, vars) in
+ let assoc = match assoc with None -> [] | Some a -> [SetAssoc a] in
+ add_notation df a (SetLevel n :: assoc) sc
let add_infix assoc n inf pr sc =
(* let pr = Astterm.globalize_qualid pr in*)
@@ -536,9 +635,9 @@ let add_infix assoc n inf pr sc =
(str"Associativity Precedence must be 6,7,8 or 9.");
*)
let metas = [inject_var "x"; inject_var "y"] in
- let ast = mkAppC (mkRefC pr,metas) in
- let a = match assoc with None -> Gramext.LeftA | Some a -> a in
- add_notation ("x "^(quote inf)^" y") ast [SetAssoc a;SetLevel n] sc
+ let a = mkAppC (mkRefC pr,metas) in
+ let assoc = match assoc with None -> [] | Some a -> [SetAssoc a] in
+ add_notation ("x "^(quote inf)^" y") a (SetLevel n :: assoc) sc
(* Delimiters *)
let load_delimiters _ (_,(_,_,scope,dlm)) =
@@ -563,13 +662,13 @@ let (inDelim,outDelim) =
load_function = load_delimiters;
export_function = (fun x -> Some x) }
-let make_delimiter_rule (l,r) inlevel =
+let make_delimiter_rule (l,r) typ =
let e = Nameops.make_ident "e" None in
- let symbols = [Terminal l; NonTerminal ((inlevel,E),e); Terminal r] in
- make_production [e,ETConstr] symbols
+ let symbols = [Terminal l; NonTerminal e; Terminal r] in
+ make_production [e,typ] symbols
let add_delimiters scope (l,r as dlms) =
if l = "" or r = "" then error "Delimiters cannot be empty";
- let gram_rule = make_delimiter_rule dlms 0 (* constr0 *) in
- let pat_gram_rule = make_delimiter_rule dlms 11 (* "pattern" *) in
+ let gram_rule = make_delimiter_rule dlms (ETConstr ((0,E),Some 0)) in
+ let pat_gram_rule = make_delimiter_rule dlms ETPattern in
Lib.add_anonymous_leaf (inDelim(gram_rule,pat_gram_rule,scope,dlms))
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index 0506dd2da..35ef1e620 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -42,7 +42,8 @@ type pcoq_hook = {
search : searchable -> dir_path list * bool -> unit;
print_name : reference -> unit;
print_check : Environ.unsafe_judgment -> unit;
- print_eval : (constr -> constr) -> Environ.env -> constr_expr -> Environ.unsafe_judgment -> unit;
+ print_eval : (constr -> constr) -> Environ.env -> constr_expr ->
+ Environ.unsafe_judgment -> unit;
show_goal : int option -> unit
}
@@ -783,6 +784,7 @@ let vernac_print = function
| PrintHintGoal -> Auto.print_applicable_hint ()
| PrintHintDbName s -> Auto.print_hint_db_by_name s
| PrintHintDb -> Auto.print_searchtable ()
+ | PrintScope s -> pp (Symbols.pr_scope (Constrextern.without_symbols pr_rawterm) s)
let global_loaded_library r =
let (loc,qid) = qualid_of_reference r in
diff --git a/toplevel/vernacexpr.ml b/toplevel/vernacexpr.ml
index be0f4d678..050ac58d1 100644
--- a/toplevel/vernacexpr.ml
+++ b/toplevel/vernacexpr.ml
@@ -56,6 +56,7 @@ type printable =
| PrintHintGoal
| PrintHintDbName of string
| PrintHintDb
+ | PrintScope of string
type searchable =
| SearchPattern of pattern_expr