run.ml 2.79 KB
Newer Older
1
2
open Ident

3
let () = State.close ();;
4

5
6
let dump = ref None
let src  = ref []
7
let args = ref []
8

9
10
11
12
13
14
15
let version () =
  Printf.eprintf "CDuce, version %s\n" Cduce_config.version;
  Printf.eprintf "built on %s\n" Cduce_config.build_date;
  Printf.eprintf "using OCaml %s compiler\n" 
    (if Cduce_config.native then "native" else "bytecode");
  exit 0

16
let specs =
17
18
19
20
  [ "--dump", Arg.String (fun s -> dump := Some s), 
          "   specify filename for persistency";
    "--quiet", Arg.Set Cduce.quiet, 
           "  suppress normal output (typing, results)";
21
    "-v", Arg.Unit version,
22
      "       print CDuce version";
23
    "--version", Arg.Unit version,
24
      "print CDuce version";
25
    "--license", Arg.Unit (fun () -> 
26
27
28
29
30
		      Printf.eprintf "\n\
The CDuce interpreter is distributed under the terms of the Q Public \n\
License version 1.0 (included in the sources). The Choice of Law section\n\
been modified from the original Q Public.\n\n
"; exit 0),
31
      "print CDuce license";
32
33
34
   "--arg", Arg.Rest (fun s -> args := s :: !args),
       "    the arguments that follow are passed to the CDuce program (in argv)";  

35
 ]
36

37
38
let () =
  Arg.parse specs (fun s -> src := s :: !src) 
39
    "\nUsage:\ncduce [OPTIONS ...] [FILE ...] [--arg argument ...]\n\nOptions:"
40

41
let ppf = 
42
  if !Cduce.quiet then Format.formatter_of_buffer (Buffer.create 1023)
43
44
  else Format.std_formatter
let ppf_err = Format.err_formatter
45
46
47
48

let do_file s =
  let (src, chan) = 
    if s = "" then (`Stream, stdin) else (`File s, open_in s) in
49
  Location.push_source src;
50
  let input = Stream.of_channel chan in
51
52
53
54
55
56
57
58
  if Stream.peek input = Some '#' then
    (
      let rec count n =
	match Stream.next input with
	  | '\n' -> n
	  | _ -> count (n + 1) in
      Wlexer.set_delta_loc (count 1)
    );
59
  let ok = Cduce.run ppf ppf_err input in
60
  if s <> "" then close_in chan;
61
  if not ok then (Format.fprintf ppf_err "@."; exit 1)
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

  

let main () =
  (match !dump with
     | Some f ->
	 (try 
	    Format.fprintf ppf "Restoring state: ";
	    let chan = open_in_bin f in
	    let s = Marshal.from_channel chan in
	    close_in chan;
	    State.set s;
	    Format.fprintf ppf "done ...@."
	  with Sys_error _ ->  
	    Format.fprintf ppf "failed ...@.")
77
78
79
80
     | None -> 
	 let l = List.rev_map Value.string_latin1 !args in
	 let l = Value.sequence l in
	 let t = Sequence.star Sequence.string in
81
	 Cduce.enter_global_value (ident (U.mk "argv")) l t
82
  );
83
84
  (match !src with
     | [] -> 
85
	 Format.fprintf ppf 
86
87
	   "CDuce version %s\nNo script specified; using stdin ...@."
	   Cduce_config.version;
88
89
90
91
92
93
94
95
96
97
98
99
100
	 do_file ""
     | l -> List.iter do_file l);
  (match !dump with
     | Some f ->
	 Format.fprintf ppf "Saving state ...@\n";
	 let s = State.get () in
	 let chan = open_out_bin f in
	 Marshal.to_channel chan s [ Marshal.Closures ];
	 close_out chan
     | None -> ())



101
102
let () = main ()