summaryrefslogtreecommitdiff
path: root/parsing/compat.ml4
diff options
context:
space:
mode:
Diffstat (limited to 'parsing/compat.ml4')
-rw-r--r--parsing/compat.ml4325
1 files changed, 325 insertions, 0 deletions
diff --git a/parsing/compat.ml4 b/parsing/compat.ml4
new file mode 100644
index 00000000..eba1d2b8
--- /dev/null
+++ b/parsing/compat.ml4
@@ -0,0 +1,325 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Compatibility file depending on ocaml/camlp4 version *)
+
+(** Locations *)
+
+IFDEF CAMLP5 THEN
+
+module CompatLoc = struct
+ include Ploc
+ let ghost = dummy
+ let merge = encl
+end
+
+exception Exc_located = Ploc.Exc
+
+IFDEF CAMLP5_6_00 THEN
+let ploc_make_loc fname lnb pos bpep = Ploc.make_loc fname lnb pos bpep ""
+let ploc_file_name = Ploc.file_name
+ELSE
+let ploc_make_loc fname lnb pos bpep = Ploc.make lnb pos bpep
+let ploc_file_name _ = ""
+END
+
+let of_coqloc loc =
+ let (fname, lnb, pos, bp, ep) = Loc.represent loc in
+ ploc_make_loc fname lnb pos (bp,ep)
+
+let to_coqloc loc =
+ Loc.create (ploc_file_name loc) (Ploc.line_nb loc)
+ (Ploc.bol_pos loc) (Ploc.first_pos loc, Ploc.last_pos loc)
+
+let make_loc = Ploc.make_unlined
+
+ELSE
+
+module CompatLoc = Camlp4.PreCast.Loc
+
+exception Exc_located = CompatLoc.Exc_located
+
+let of_coqloc loc =
+ let (fname, lnb, pos, bp, ep) = Loc.represent loc in
+ CompatLoc.of_tuple (fname, 0, 0, bp, 0, 0, ep, false)
+
+let to_coqloc loc =
+ Loc.create (CompatLoc.file_name loc) (CompatLoc.start_line loc)
+ (CompatLoc.start_bol loc) (CompatLoc.start_off loc, CompatLoc.stop_off loc)
+
+let make_loc (start, stop) =
+ CompatLoc.of_tuple ("", 0, 0, start, 0, 0, stop, false)
+
+END
+
+let (!@) = to_coqloc
+
+(** Misc module emulation *)
+
+IFDEF CAMLP5 THEN
+
+module PcamlSig = struct end
+module Token = Token
+
+ELSE
+
+module PcamlSig = Camlp4.Sig
+module Ast = Camlp4.PreCast.Ast
+module Pcaml = Camlp4.PreCast.Syntax
+module MLast = Ast
+module Token = struct exception Error of string end
+
+END
+
+
+(** Grammar auxiliary types *)
+
+IFDEF CAMLP5 THEN
+
+let to_coq_assoc = function
+| Gramext.RightA -> Extend.RightA
+| Gramext.LeftA -> Extend.LeftA
+| Gramext.NonA -> Extend.NonA
+
+let of_coq_assoc = function
+| Extend.RightA -> Gramext.RightA
+| Extend.LeftA -> Gramext.LeftA
+| Extend.NonA -> Gramext.NonA
+
+let of_coq_position = function
+| Extend.First -> Gramext.First
+| Extend.Last -> Gramext.Last
+| Extend.Before s -> Gramext.Before s
+| Extend.After s -> Gramext.After s
+| Extend.Level s -> Gramext.Level s
+
+let to_coq_position = function
+| Gramext.First -> Extend.First
+| Gramext.Last -> Extend.Last
+| Gramext.Before s -> Extend.Before s
+| Gramext.After s -> Extend.After s
+| Gramext.Level s -> Extend.Level s
+| Gramext.Like _ -> assert false (** dont use it, not in camlp4 *)
+
+ELSE
+
+let to_coq_assoc = function
+| PcamlSig.Grammar.RightA -> Extend.RightA
+| PcamlSig.Grammar.LeftA -> Extend.LeftA
+| PcamlSig.Grammar.NonA -> Extend.NonA
+
+let of_coq_assoc = function
+| Extend.RightA -> PcamlSig.Grammar.RightA
+| Extend.LeftA -> PcamlSig.Grammar.LeftA
+| Extend.NonA -> PcamlSig.Grammar.NonA
+
+let of_coq_position = function
+| Extend.First -> PcamlSig.Grammar.First
+| Extend.Last -> PcamlSig.Grammar.Last
+| Extend.Before s -> PcamlSig.Grammar.Before s
+| Extend.After s -> PcamlSig.Grammar.After s
+| Extend.Level s -> PcamlSig.Grammar.Level s
+
+let to_coq_position = function
+| PcamlSig.Grammar.First -> Extend.First
+| PcamlSig.Grammar.Last -> Extend.Last
+| PcamlSig.Grammar.Before s -> Extend.Before s
+| PcamlSig.Grammar.After s -> Extend.After s
+| PcamlSig.Grammar.Level s -> Extend.Level s
+
+END
+
+
+(** Signature of Lexer *)
+
+IFDEF CAMLP5 THEN
+
+module type LexerSig = sig
+ include Grammar.GLexerType with type te = Tok.t
+ module Error : sig
+ type t
+ exception E of t
+ val to_string : t -> string
+ end
+end
+
+ELSE
+
+module type LexerSig =
+ Camlp4.Sig.Lexer with module Loc = CompatLoc and type Token.t = Tok.t
+
+END
+
+(** Signature and implementation of grammars *)
+
+IFDEF CAMLP5 THEN
+
+module type GrammarSig = sig
+ include Grammar.S with type te = Tok.t
+ type 'a entry = 'a Entry.e
+ type internal_entry = Tok.t Gramext.g_entry
+ type symbol = Tok.t Gramext.g_symbol
+ type action = Gramext.g_action
+ type production_rule = symbol list * action
+ type single_extend_statment =
+ string option * Gramext.g_assoc option * production_rule list
+ type extend_statment =
+ Gramext.position option * single_extend_statment list
+ val action : 'a -> action
+ val entry_create : string -> 'a entry
+ val entry_parse : 'a entry -> parsable -> 'a
+ val entry_print : Format.formatter -> 'a entry -> unit
+ val srules' : production_rule list -> symbol
+ val parse_tokens_after_filter : 'a entry -> Tok.t Stream.t -> 'a
+end
+
+module GrammarMake (L:LexerSig) : GrammarSig = struct
+ include Grammar.GMake (L)
+ type 'a entry = 'a Entry.e
+ type internal_entry = Tok.t Gramext.g_entry
+ type symbol = Tok.t Gramext.g_symbol
+ type action = Gramext.g_action
+ type production_rule = symbol list * action
+ type single_extend_statment =
+ string option * Gramext.g_assoc option * production_rule list
+ type extend_statment =
+ Gramext.position option * single_extend_statment list
+ let action = Gramext.action
+ let entry_create = Entry.create
+ let entry_parse e p =
+ try Entry.parse e p
+ with Exc_located (loc,e) -> Loc.raise (to_coqloc loc) e
+IFDEF CAMLP5_6_02_1 THEN
+ let entry_print ft x = Entry.print ft x
+ELSE
+ let entry_print _ x = Entry.print x
+END
+ let srules' = Gramext.srules
+ let parse_tokens_after_filter = Entry.parse_token
+end
+
+ELSE
+
+module type GrammarSig = sig
+ include Camlp4.Sig.Grammar.Static
+ with module Loc = CompatLoc and type Token.t = Tok.t
+ type 'a entry = 'a Entry.t
+ type action = Action.t
+ type parsable
+ val parsable : char Stream.t -> parsable
+ val action : 'a -> action
+ val entry_create : string -> 'a entry
+ val entry_parse : 'a entry -> parsable -> 'a
+ val entry_print : Format.formatter -> 'a entry -> unit
+ val srules' : production_rule list -> symbol
+end
+
+module GrammarMake (L:LexerSig) : GrammarSig = struct
+ (* We need to refer to Coq's module Loc before it is hidden by include *)
+ let raise_coq_loc loc e = Loc.raise (to_coqloc loc) e
+ include Camlp4.Struct.Grammar.Static.Make (L)
+ type 'a entry = 'a Entry.t
+ type action = Action.t
+ type parsable = char Stream.t
+ let parsable s = s
+ let action = Action.mk
+ let entry_create = Entry.mk
+ let entry_parse e s =
+ try parse e (*FIXME*)CompatLoc.ghost s
+ with Exc_located (loc,e) -> raise_coq_loc loc e
+ let entry_print ft x = Entry.print ft x
+ let srules' = srules (entry_create "dummy")
+end
+
+END
+
+
+(** Misc functional adjustments *)
+
+(** - The lexer produces streams made of pairs in camlp4 *)
+
+let get_tok = IFDEF CAMLP5 THEN fun x -> x ELSE fst END
+
+(** - Gram.extend is more currified in camlp5 than in camlp4 *)
+
+IFDEF CAMLP5 THEN
+let maybe_curry f x y = f (x,y)
+let maybe_uncurry f (x,y) = f x y
+ELSE
+let maybe_curry f = f
+let maybe_uncurry f = f
+END
+
+(** Compatibility with camlp5 strict mode *)
+IFDEF CAMLP5 THEN
+ IFDEF STRICT THEN
+ let vala x = Ploc.VaVal x
+ ELSE
+ let vala x = x
+ END
+ELSE
+ let vala x = x
+END
+
+(** Fix a quotation difference in [str_item] *)
+
+let declare_str_items loc l =
+IFDEF CAMLP5 THEN
+ MLast.StDcl (loc, vala l) (* correspond to <:str_item< declare $list:l'$ end >> *)
+ELSE
+ Ast.stSem_of_list l
+END
+
+(** Quotation difference for match clauses *)
+
+let default_patt loc =
+ (<:patt< _ >>, vala None, <:expr< failwith "Extension: cannot occur" >>)
+
+IFDEF CAMLP5 THEN
+
+let make_fun loc cl =
+ let l = cl @ [default_patt loc] in
+ MLast.ExFun (loc, vala l) (* correspond to <:expr< fun [ $list:l$ ] >> *)
+
+ELSE
+
+let make_fun loc cl =
+ let mk_when = function
+ | Some w -> w
+ | None -> Ast.ExNil loc
+ in
+ let mk_clause (patt,optwhen,expr) =
+ (* correspond to <:match_case< ... when ... -> ... >> *)
+ Ast.McArr (loc, patt, mk_when optwhen, expr) in
+ let init = mk_clause (default_patt loc) in
+ let add_clause x acc = Ast.McOr (loc, mk_clause x, acc) in
+ let l = List.fold_right add_clause cl init in
+ Ast.ExFun (loc,l) (* correspond to <:expr< fun [ $l$ ] >> *)
+
+END
+
+(** Explicit antiquotation $anti:... $ *)
+
+IFDEF CAMLP5 THEN
+let expl_anti loc e = <:expr< $anti:e$ >>
+ELSE
+let expl_anti _loc e = e (* FIXME: understand someday if we can do better *)
+END
+
+(** Qualified names in OCaml *)
+
+IFDEF CAMLP5 THEN
+let qualified_name loc path name =
+ let fold dir accu = <:expr< $uid:dir$.$accu$ >> in
+ List.fold_right fold path <:expr< $lid:name$ >>
+ELSE
+let qualified_name loc path name =
+ let fold dir accu = Ast.IdAcc (loc, Ast.IdUid (loc, dir), accu) in
+ let path = List.fold_right fold path (Ast.IdLid (loc, name)) in
+ Ast.ExId (loc, path)
+END