summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/camlp4/Camlp4Top/Top.ml
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/camlp4/Camlp4Top/Top.ml')
-rw-r--r--ocaml-binary-annot/camlp4/Camlp4Top/Top.ml147
1 files changed, 147 insertions, 0 deletions
diff --git a/ocaml-binary-annot/camlp4/Camlp4Top/Top.ml b/ocaml-binary-annot/camlp4/Camlp4Top/Top.ml
new file mode 100644
index 0000000000..dcd3aa4607
--- /dev/null
+++ b/ocaml-binary-annot/camlp4/Camlp4Top/Top.ml
@@ -0,0 +1,147 @@
+(* camlp4r q_MLast.cmo *)
+(****************************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* INRIA Rocquencourt *)
+(* *)
+(* Copyright 2002-2006 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed under *)
+(* the terms of the GNU Library General Public License, with the special *)
+(* exception on linking described in LICENSE at the top of the Objective *)
+(* Caml source tree. *)
+(* *)
+(****************************************************************************)
+
+(* Authors:
+ * - Daniel de Rauglaudre: initial version
+ * - Nicolas Pouillard: refactoring
+ *)
+
+
+
+(* There is a few Obj.magic due to the fact that we no longer have compiler
+ files like Parsetree, Location, Longident but Camlp4_import that wrap them to
+ avoid name clashing. *)
+module Toploop : sig
+ value print_location :
+ Format.formatter -> Camlp4_import.Location.t -> unit;
+ value print_warning :
+ Camlp4_import.Location.t -> Format.formatter -> Camlp4_import.Warnings.t -> unit;
+ value parse_toplevel_phrase :
+ ref (Lexing.lexbuf -> Camlp4_import.Parsetree.toplevel_phrase);
+ value parse_use_file :
+ ref (Lexing.lexbuf -> list Camlp4_import.Parsetree.toplevel_phrase);
+end = struct
+ value print_location fmt loc =
+ Toploop.print_location fmt (Obj.magic loc);
+ value parse_toplevel_phrase =
+ Obj.magic Toploop.parse_toplevel_phrase;
+ value parse_use_file =
+ Obj.magic Toploop.parse_use_file;
+ value print_warning loc fmt w =
+ Toploop.print_warning (Obj.magic loc) fmt (Obj.magic w);
+end;
+
+open Camlp4_import.Parsetree;
+open Lexing;
+open Camlp4;
+open PreCast;
+open Syntax;
+open Camlp4.Sig;
+module Ast2pt = Camlp4.Struct.Camlp4Ast2OCamlAst.Make Ast;
+module Lexer = Camlp4.Struct.Lexer.Make Token;
+
+external not_filtered : 'a -> Gram.not_filtered 'a = "%identity";
+
+value initialization = lazy begin
+ if Sys.interactive.val
+ then Format.printf "\tCamlp4 Parsing version %s\n@." Camlp4_config.version
+ else ()
+end;
+
+value lookup x xs = try Some (List.assq x xs) with [ Not_found -> None ];
+
+value wrap parse_fun =
+ let token_streams = ref [] in
+ let cleanup lb =
+ try token_streams.val := List.remove_assq lb token_streams.val
+ with [ Not_found -> () ]
+ in
+ fun lb ->
+ let () = Lazy.force initialization in
+ let () = Register.iter_and_take_callbacks (fun (_, f) -> f ()) in
+ let token_stream =
+ match lookup lb token_streams.val with
+ [ None ->
+ let not_filtered_token_stream = Lexer.from_lexbuf lb in
+ let token_stream = Gram.filter (not_filtered not_filtered_token_stream) in
+ do { token_streams.val := [ (lb,token_stream) :: token_streams.val ]; token_stream }
+ | Some token_stream -> token_stream ]
+ in try
+ match token_stream with parser
+ [ [: `(EOI, _) :] -> raise End_of_file
+ | [: :] -> parse_fun token_stream ]
+ with
+ [ End_of_file | Sys.Break | (Loc.Exc_located _ (End_of_file | Sys.Break))
+ as x -> (cleanup lb; raise x)
+ | x ->
+ let x =
+ match x with
+ [ Loc.Exc_located loc x -> do {
+ Toploop.print_location Format.err_formatter
+ (Loc.to_ocaml_location loc);
+ x }
+ | x -> x ]
+ in
+ do {
+ cleanup lb;
+ Format.eprintf "@[<0>%a@]@." Camlp4.ErrorHandler.print x;
+ raise Exit
+ } ];
+
+value toplevel_phrase token_stream =
+ match Gram.parse_tokens_after_filter Syntax.top_phrase token_stream with
+ [ Some str_item ->
+ let str_item =
+ AstFilters.fold_topphrase_filters (fun t filter -> filter t) str_item
+ in
+ Ast2pt.phrase str_item
+
+ | None -> raise End_of_file ];
+
+value use_file token_stream =
+ let (pl0, eoi) =
+ loop () where rec loop () =
+ let (pl, stopped_at_directive) =
+ Gram.parse_tokens_after_filter Syntax.use_file token_stream
+ in
+ if stopped_at_directive <> None then
+ match pl with
+ [ [ <:str_item< #load $str:s$ >> ] ->
+ do { Topdirs.dir_load Format.std_formatter s; loop () }
+ | [ <:str_item< #directory $str:s$ >> ] ->
+ do { Topdirs.dir_directory s; loop () }
+ | _ -> (pl, False) ]
+ else (pl, True)
+ in
+ let pl =
+ if eoi then []
+ else
+ loop () where rec loop () =
+ let (pl, stopped_at_directive) =
+ Gram.parse_tokens_after_filter Syntax.use_file token_stream
+ in
+ if stopped_at_directive <> None then pl @ loop () else pl
+ in List.map Ast2pt.phrase (pl0 @ pl);
+
+Toploop.parse_toplevel_phrase.val := wrap toplevel_phrase;
+
+Toploop.parse_use_file.val := wrap use_file;
+
+current_warning.val :=
+ fun loc txt ->
+ Toploop.print_warning (Loc.to_ocaml_location loc) Format.err_formatter
+ (Camlp4_import.Warnings.Camlp4 txt);
+
+Register.iter_and_take_callbacks (fun (_, f) -> f ());