/[svn]/driver/cduce.ml
ViewVC logotype

Diff of /driver/cduce.ml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 70 by abate, Tue Jul 10 17:03:19 2007 UTC revision 1105 by abate, Tue Jul 10 18:23:04 2007 UTC
# Line 1  Line 1 
1  open Location  open Location
2  exception Usage  open Ident
3    
4  let () =  ifdef ML_INTERFACE then module ML = Ml_ocaml;;
   List.iter  
     (fun (n,t) -> Typer.register_global_types [n, mk noloc (Ast.Internal t)])  
     Builtin.types  
5    
6    exception InvalidInputFilename of string
7    exception InvalidObjectFilename of string
8    
9  let (source,input_channel) =  (* if set to false toplevel exception aren't cought.
10    match Array.length Sys.argv with   * Useful for debugging with OCAMLRUNPARAM="b" *)
11      | 1 -> ("",stdin)  let catch_exceptions = true
     | 2 -> let s = Sys.argv.(1) in (s, open_in s)  
     | _ -> raise Usage  
12    
13  let () = Location.set_source source  (* retuns a filename without the suffix suff if any *)
14    let prefix filename suff =
15  let input = Stream.of_channel input_channel    if Filename.check_suffix filename suff then
16        try
17  let ppf = Format.std_formatter        Filename.chop_extension filename
18  let prog () =      with Invalid_argument filename -> failwith "Not a point in the suffix?"
19    try Parser.prog input    else filename
20    with  
21      | Stdpp.Exc_located (loc, e) -> raise (Location (loc, e))  let toplevel = ref false
22    let verbose = ref false
23    
24    let typing_env = State.ref "Cduce.typing_env" Builtin.env
25    let compile_env = State.ref "Cduce.compile_env" Compile.empty_toplevel
26    
27    let get_global_value cenv v =
28      Eval.var (Compile.find v !compile_env)
29    
30    let get_global_type v =
31      Typer.find_value v !typing_env
32    
33    let rec is_abstraction = function
34      | Ast.Abstraction _ -> true
35      | Ast.LocatedExpr (_,e) -> is_abstraction e
36      | _ -> false
37    
38  let print_norm ppf d =  let print_norm ppf d =
39    Types.Print.print_descr ppf ((*Types.normalize*) d)    Location.protect ppf
40        (fun ppf -> Types.Print.print ppf ((*Types.normalize*) d))
41    
42    let print_sample ppf s =
43      Location.protect ppf
44        (fun ppf -> Sample.print ppf s)
45    
46    let print_protect ppf s =
47      Location.protect ppf (fun ppf -> Format.fprintf ppf "%s" s)
48    
49    let print_value ppf v =
50      Location.protect ppf (fun ppf -> Value.print ppf v)
51    
52    let dump_value ppf x t v =
53      Format.fprintf ppf "@[val %a : @[%a = %a@]@]@."
54        U.print (Id.value x) print_norm t print_value v
55    
56    let dump_env ppf tenv cenv =
57      Format.fprintf ppf "Types:%a@." Typer.dump_types tenv;
58      Format.fprintf ppf "Namespace prefixes:@\n%a" Typer.dump_ns tenv;
59      Format.fprintf ppf "Namespace prefixes used for pretty-printing:@.%t"
60        Ns.InternalPrinter.dump;
61      Format.fprintf ppf "Schemas: %s@."
62        (String.concat " " (List.map U.get_str (Typer.get_schema_names ())));
63      Format.fprintf ppf "Values:@.";
64      Typer.iter_values tenv
65        (fun x t -> dump_value ppf x t (get_global_value cenv x))
66    
67    let directive_help ppf =
68      Format.fprintf ppf
69    "Toplevel directives:
70      #quit;;                 quit the interpreter
71      #env;;                  dump current environment
72      #reinit_ns;;            reinitialize namespace processing
73      #help;;                 shows this help message
74      #dump_value <expr>;;    dump an XML-ish representation of the resulting
75                              value of a given expression
76      #print_schema <name>;;
77      #print_type <name>;;
78    "
79    
80  let rec print_exn ppf = function  let rec print_exn ppf = function
81    | Location (loc, exn) ->    | Location (loc, w, exn) ->
82        Format.fprintf ppf "Error %a:@\n%a" Location.print_loc loc print_exn exn        Format.fprintf ppf "Error %a:@." Location.print_loc (loc,w);
83          Format.fprintf ppf "%a" Location.html_hilight (loc,w);
84          print_exn ppf exn
85    | Value.CDuceExn v ->    | Value.CDuceExn v ->
86        Format.fprintf ppf "Uncaught CDuce exception: @[%a@]@\n"        Format.fprintf ppf "Uncaught CDuce exception: @[%a@]@."
87          Value.print v          print_value v
88    | Typer.WrongLabel (t,l) ->    | Typer.WrongLabel (t,l) ->
89        Format.fprintf ppf "Wrong record selection: the label %s@\n"        Format.fprintf ppf "Wrong record selection; field %a "
90          (Types.label_name l);          Label.print (LabelPool.value l);
91        Format.fprintf ppf "applied to an expression of type %a@\n"        Format.fprintf ppf "not present in an expression of type:@.%a@."
92          print_norm t          print_norm t
   | Typer.MultipleLabel l ->  
       Format.fprintf ppf "Multiple occurences for the record label %s@\n"  
         (Types.label_name l);  
93    | Typer.ShouldHave (t,msg) ->    | Typer.ShouldHave (t,msg) ->
94        Format.fprintf ppf "This expression should have type %a@\n%s@\n"        Format.fprintf ppf "This expression should have type:@.%a@.%a@."
95          print_norm t          print_norm t
96          msg          print_protect msg
97    | Typer.Constraint (s,t,msg) ->    | Typer.ShouldHave2 (t1,msg,t2) ->
98        Format.fprintf ppf "This expression should have type %a@\n"        Format.fprintf ppf "This expression should have type:@.%a@.%a %a@."
99            print_norm t1
100            print_protect msg
101            print_norm t2
102      | Typer.Error s ->
103          Format.fprintf ppf "%a@." print_protect s
104      | Typer.Constraint (s,t) ->
105          Format.fprintf ppf "This expression should have type:@.%a@."
106          print_norm t;          print_norm t;
107        Format.fprintf ppf "but its infered type is: %a@\n"        Format.fprintf ppf "but its inferred type is:@.%a@."
108          print_norm s;          print_norm s;
109        Format.fprintf ppf "which is not a subtype, as shown by the value %a@\n"        Format.fprintf ppf "which is not a subtype, as shown by the sample:@.%a@."
110          Types.Print.print_sample (Types.Sample.get (Types.diff s t));          print_sample (Sample.get (Types.diff s t))
       Format.fprintf ppf "%s@\n" msg  
111    | Typer.NonExhaustive t ->    | Typer.NonExhaustive t ->
112        Format.fprintf ppf "This pattern matching is not exhaustive@\n";        Format.fprintf ppf "This pattern matching is not exhaustive@.";
113        Format.fprintf ppf "Residual type: %a@\n"        Format.fprintf ppf "Residual type:@.%a@."
114          print_norm t;          print_norm t;
115        Format.fprintf ppf "Sample value: %a@\n"        Format.fprintf ppf "Sample:@.%a@." print_sample (Sample.get t)
116          Types.Print.print_sample (Types.Sample.get t)    | Typer.UnboundId (x,tn) ->
117    | Typer.UnboundId x ->        Format.fprintf ppf "Unbound identifier %a%s@." U.print (Id.value x)
118        Format.fprintf ppf "Unbound identifier %s@\n" x          (if tn then " (it is a type name)" else "")
119      | Typer.UnboundExtId (cu,x) ->
120          Format.fprintf ppf "Unbound external identifier %a:%a@."
121            U.print (Types.CompUnit.value cu)
122            U.print (Id.value x)
123      | Ulexer.Error (i,j,s) ->
124          let loc = Location.loc_of_pos (i,j), `Full in
125          Format.fprintf ppf "Error %a:@." Location.print_loc loc;
126          Format.fprintf ppf "%a%s" Location.html_hilight loc s
127      | Parser.Error s | Stream.Error s ->
128          Format.fprintf ppf "Parsing error: %a@." print_protect s
129      | Librarian.InconsistentCrc id ->
130          Format.fprintf ppf "Link error:@.";
131          let name = Encodings.Utf8.to_string (Types.CompUnit.value id) in
132          Format.fprintf ppf "Inconsistent checksum (compilation unit: %s)@."
133            name
134      | Librarian.NoImplementation id ->
135          Format.fprintf ppf "Link error:@.";
136          let name = Encodings.Utf8.to_string (Types.CompUnit.value id) in
137          Format.fprintf ppf "No implementation found for compilation unit: %s@."
138            name
139      | Librarian.Loop id ->
140          Format.fprintf ppf "Compilation error:@.";
141          let name = Encodings.Utf8.to_string (Types.CompUnit.value id) in
142          Format.fprintf ppf "Loop between compilation unit (compilation unit: %s)@."
143            name
144      | InvalidInputFilename f ->
145          Format.fprintf ppf "Compilation error:@.";
146          Format.fprintf ppf "Source filename must have extension .cd@.";
147      | InvalidObjectFilename f ->
148          Format.fprintf ppf "Compilation error:@.";
149          Format.fprintf ppf "Object filename must have extension .cdo and no path@.";
150      | Librarian.InvalidObject f ->
151          Format.fprintf ppf "Invalid object file %s@." f
152      | Librarian.CannotOpen f ->
153          Format.fprintf ppf "Cannot open file %s@." f
154      | Location.Generic s ->
155          Format.fprintf ppf "%a@." print_protect s
156    | exn ->    | exn ->
157        Format.fprintf ppf "%s@\n" (Printexc.to_string exn)  (*      raise exn *)
158          Format.fprintf ppf "%a@." print_protect (Printexc.to_string exn)
159    
160  let debug = function  
161    let eval_quiet tenv cenv e =
162      let (e,_) = Typer.type_expr tenv e in
163      let e = Compile.compile_expr cenv e in
164      Eval.expr e
165    
166    let debug ppf tenv cenv = function
167      | `Subtype (t1,t2) ->
168          Format.fprintf ppf "[DEBUG:subtype]@.";
169          let t1 = Types.descr (Typer.typ tenv t1)
170          and t2 = Types.descr (Typer.typ tenv t2) in
171          let s = Types.subtype t1 t2 in
172          Format.fprintf ppf "%a %a %a : %b@." print_norm t1 print_protect "<=" print_norm t2 s
173      | `Sample t ->
174          Format.fprintf ppf "[DEBUG:sample]@.";
175          (try
176             let t = Types.descr (Typer.typ tenv t) in
177             Format.fprintf ppf "%a@." print_sample (Sample.get t)
178           with Not_found ->
179             Format.fprintf ppf "Empty type : no sample !@.")
180    | `Filter (t,p) ->    | `Filter (t,p) ->
181        Format.fprintf ppf "[DEBUG:filter]@\n";        Format.fprintf ppf "[DEBUG:filter]@.";
182        let t = Typer.typ t        let t = Typer.typ tenv t
183        and p = Typer.pat p in        and p = Typer.pat tenv p in
184        let f = Patterns.filter (Types.descr t) p in        let f = Patterns.filter (Types.descr t) p in
185        List.iter (fun (x,t) ->        List.iter (fun (x,t) ->
186                     Format.fprintf ppf " x:%a@\n"                     Format.fprintf ppf " %a:%a@." U.print (Id.value x)
187                       print_norm (Types.descr t)) f                       print_norm (Types.descr t)) f
188    | `Accept p ->    | `Accept p ->
189        Format.fprintf ppf "[DEBUG:accept]@\n";        Format.fprintf ppf "[DEBUG:accept]@.";
190        let p = Typer.pat p in        let p = Typer.pat tenv p in
191        let t = Patterns.accept p in        let t = Patterns.accept p in
192        Format.fprintf ppf " %a@\n" Types.Print.print t        Format.fprintf ppf " %a@." Types.Print.print (Types.descr t)
193    | `Compile (t,pl) ->    | `Compile (t,pl) ->
194        Format.fprintf ppf "[DEBUG:compile]@\n";        Format.fprintf ppf "[DEBUG:compile]@.";
195        let t = Typer.typ t        let t = Typer.typ tenv t
196        and pl = List.map Typer.pat pl in        and pl = List.map (Typer.pat tenv) pl in
197        let pl = Array.of_list        Patterns.Compile.debug_compile ppf t pl
198                   (List.map (fun p -> Patterns.Compile.normal    | `Explain (t,e) ->
199                                (Patterns.descr p)) pl) in        Format.fprintf ppf "[DEBUG:explain]@.";
200        Patterns.Compile.show ppf (Types.descr t) pl        let t = Typer.typ tenv t in
201    | _ -> Format.fprintf ppf "Unknown or ill-formed debugging directive !! @\n"        (match Explain.explain (Types.descr t) (eval_quiet tenv cenv e) with
202             | Some p ->
203  let typing_env = ref Typer.Env.empty               Format.fprintf ppf "Explanation: @[%a@]@."
204  let eval_env = ref Eval.Env.empty                 Explain.print_path p
205             | None ->
206  let insert_type_bindings =               Format.fprintf ppf "Explanation: value has given type@.")
207    List.iter (fun (x,t) ->  
208                 typing_env := Typer.Env.add x t !typing_env;  
209                 Format.fprintf ppf "|- %s : %a@\n" x print_norm t)  let flush_ppf ppf = Format.fprintf ppf "@."
210    
211  let type_decl decl =  let directive ppf tenv cenv = function
212    insert_type_bindings (Typer.type_let_decl !typing_env decl)    | `Debug d ->
213          debug ppf tenv cenv d
214  let eval_decl decl =    | `Quit ->
215    let bindings = Eval.eval_let_decl !eval_env decl in        (if !toplevel then raise End_of_file)
216    List.iter    | `Env ->
217      (fun (x,v) ->        dump_env ppf tenv cenv
218         Eval.enter_global x v;    | `Print_schema schema ->
219         Format.fprintf ppf "=> %s : @[%a@]@\n" x Value.print v        Schema_common.print_schema ppf (Typer.get_schema schema);
220      ) bindings        flush_ppf ppf
221      | `Print_type name ->
222  let phrase ph =        Typer.dump_type ppf tenv name;
223    match ph.descr with        flush_ppf ppf
224      | Ast.EvalStatement e ->    | `Print_schema_type schema_ref ->
225          let (fv,e) = Typer.expr e in        Typer.dump_schema_type ppf schema_ref;
226          let t = Typer.type_check !typing_env e Types.any true in        flush_ppf ppf
227          Format.fprintf ppf "|- %a@\n" print_norm t;    | `Reinit_ns ->
228          let v = Eval.eval !eval_env e in        Typer.set_ns_table_for_printer tenv
229          Format.fprintf ppf "=> @[%a@]@\n" Value.print v    | `Help ->
230      | Ast.LetDecl (p,{descr=Ast.Abstraction _}) -> ()        directive_help ppf
231      | Ast.LetDecl (p,e) ->    | `Dump pexpr ->
232          let decl = Typer.let_decl p e in        Value.dump_xml ppf (eval_quiet tenv cenv pexpr);
233          type_decl decl;        flush_ppf ppf
234          eval_decl decl  
235      | Ast.TypeDecl _ -> ()  let print_id_opt ppf = function
236      | Ast.Debug l -> debug l    | None -> Format.fprintf ppf "-"
237      | _ -> assert false    | Some id -> Format.fprintf ppf "val %a" U.print (Id.value id)
238    
239  let do_fun_decls decls =  let print_value_opt ppf = function
240    let decls = List.map (fun (p,e) -> Typer.let_decl p e) decls in    | None -> ()
241    insert_type_bindings (Typer.type_rec_funs !typing_env decls);    | Some v -> Format.fprintf ppf " = %a" print_value v
242    List.iter eval_decl decls  
243    let show ppf id t v =
244      Format.fprintf ppf "@[%a : @[%a%a@]@]@."
245        print_id_opt id
246        print_norm t
247        print_value_opt v
248    
249    let phrases ppf phs =
250      let (tenv,cenv,_) =
251        Compile.comp_unit
252          ~run:true ~show:(show ppf)
253          ~loading:Librarian.import_and_run
254          ~directive:(directive ppf)
255          !typing_env !compile_env phs in
256      typing_env := tenv;
257      compile_env := cenv
258    
259    let catch_exn ppf_err exn =
260      if not catch_exceptions then raise exn;
261      match exn with
262      | (End_of_file | Failure _ | Not_found | Invalid_argument _ | Sys.Break)
263          as e ->
264          raise e
265      | exn ->
266          print_exn ppf_err exn;
267          Format.fprintf ppf_err "@."
268    
269  let () =  let parse rule input =
270      try Parser.localize_exn (fun () -> rule input)
271      with e -> Parser.sync (); raise e
272    
273    let run rule ppf ppf_err input =
274      try phrases ppf (parse rule input); true
275      with exn -> catch_exn ppf_err exn; false
276    
277    let topinput = run Parser.top_phrases
278    
279    ifdef ML_INTERFACE then
280      let check_ml cu id out_dir out =
281        let fnam = String.copy cu in
282        String.set fnam 0 ( Char.lowercase ( String.get fnam 0 ) );
283    try    try
284      let p = prog () in        let name = fnam ^ ".cmi" in
285      let (type_decls,fun_decls) =        let file = List.find (
286        List.fold_left          fun dir -> Sys.file_exists ( Filename.concat dir name )
287          (fun ((typs,funs) as accu) ph -> match ph.descr with        ) !Librarian.obj_path in
288             | Ast.TypeDecl (x,t) -> ((x,t) :: typs,funs)        if file = "" then raise Not_found;
289             | Ast.LetDecl (p,({descr=Ast.Abstraction _} as e)) ->        let file = Filename.concat file name in
290                 (typs, (p,e)::funs)        let ml_cu = ML.CompUnit.from_bytecode file cu
291             | _ -> accu        and cd_cu = Ml_cduce.CompUnit.from_types_cu cu id in
292          ) ([],[]) p in        Ml_checker.run ml_cu cd_cu;
293      Typer.register_global_types type_decls;        let out = open_out ( Filename.concat out_dir (cu ^ ".ml") ) in
294      do_fun_decls fun_decls;        let fmt = Format.formatter_of_out_channel out in
295      List.iter phrase p        Ml_generator.ML.generate fmt cu ml_cu cd_cu;
296    with        close_out out;
297      | (Failure _ | Not_found | Invalid_argument _) as e ->      with Not_found -> (
298          raise e  (* To get the ocamlrun stack trace *)        let name = fnam ^ ".mli" in
299      | exn -> print_exn ppf exn        let has_cmi = List.exists (
300            fun dir -> Sys.file_exists ( Filename.concat dir name )
301          ) !Librarian.obj_path in
302          if has_cmi then
303            Format.eprintf
304              "Warning: found %s.mli but no %s.cmi: forgotten compilation?@."
305              fnam fnam;
306        )
307    else
308      let check_ml cu id out_dir out = ();;
309    
310    let compile src out_dir =
311      try
312        if not (Filename.check_suffix src ".cd")
313        then raise (InvalidInputFilename src);
314        let cu = Filename.chop_suffix (Filename.basename src) ".cd" in
315        let out_dir =
316          match out_dir with
317            | None -> Filename.dirname src
318            | Some x -> x in
319        let out = Filename.concat out_dir (cu ^ ".cdo") in
320        let id = Types.CompUnit.mk (U.mk_latin1 cu) in
321        Librarian.compile !verbose id src;
322        Librarian.save id out;
323        check_ml cu id out_dir out;
324        exit 0
325      with exn -> catch_exn Format.err_formatter exn; exit 1
326    
327    let compile_run src =
328      try
329        if not (Filename.check_suffix src ".cd")
330        then raise (InvalidInputFilename src);
331        let cu = Filename.chop_suffix (Filename.basename src) ".cd" in
332        let id = Types.CompUnit.mk (U.mk_latin1 cu) in
333        Librarian.compile !verbose id src;
334        Librarian.run id
335      with exn -> catch_exn Format.err_formatter exn; exit 1
336    
337    let run obj =
338      try
339        if not (Filename.check_suffix obj ".cdo") || (Filename.basename obj <> obj)
340        then raise (InvalidObjectFilename obj);
341        let cu = Filename.chop_suffix (Filename.basename obj) ".cdo" in
342        let id = Types.CompUnit.mk (U.mk_latin1 cu) in
343        Librarian.import_and_run id
344      with exn -> catch_exn Format.err_formatter exn; exit 1
345    
346    
347    let dump_env ppf = dump_env ppf !typing_env !compile_env

Legend:
Removed from v.70  
changed lines
  Added in v.1105

CVS Admin">CVS Admin
ViewVC Help
Powered by ViewVC 1.1.5