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

Diff of /driver/cduce.ml

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

revision 233 by abate, Tue Jul 10 17:17:31 2007 UTC revision 698 by abate, Tue Jul 10 17:56:40 2007 UTC
# Line 2  Line 2 
2  open Ident  open Ident
3    
4  let quiet = ref false  let quiet = ref false
5    let toplevel = ref false
6    
7  let typing_env = State.ref "Cduce.typing_env" Typer.Env.empty  let typing_env = State.ref "Cduce.typing_env" Builtin.env
8  let glb_env = State.ref "Cduce.glb_env" Typer.TypeEnv.empty  let eval_env = State.ref "Cduce.eval_env" Eval.empty
9  let eval_env = Eval.global_env  let compile_env = State.ref "Cduce.compile_env" Compile.empty
10    
11    let do_compile = ref false
12    
13    let get_global_value v =
14      if !do_compile
15      then Eval.L.var (Compile.find v !compile_env)
16      else Eval.find_value v !eval_env
17    
18    let get_global_type v =
19      Typer.find_value v !typing_env
20    
21    let enter_global_value x v t =
22      typing_env := Typer.enter_value x t !typing_env;
23    
24      if !do_compile
25      then (compile_env := Compile.enter_global !compile_env x; Eval.L.push v)
26      else eval_env := Eval.enter_value x v !eval_env
27    
28    let rec is_abstraction = function
29      | Ast.Abstraction _ -> true
30      | Ast.LocatedExpr (_,e) -> is_abstraction e
31      | _ -> false
32    
33  let print_norm ppf d =  let print_norm ppf d =
34    Location.protect ppf    Location.protect ppf
35      (fun ppf -> Types.Print.print_descr ppf ((*Types.normalize*) d))      (fun ppf -> Types.Print.print ppf ((*Types.normalize*) d))
36    
37    let print_sample ppf s =
38      Location.protect ppf
39        (fun ppf -> Sample.print ppf s)
40    
41    let print_protect ppf s =
42      Location.protect ppf (fun ppf -> Format.fprintf ppf "%s" s)
43    
44  let print_value ppf v =  let print_value ppf v =
45    Location.protect ppf (fun ppf -> Value.print ppf v)    Location.protect ppf (fun ppf -> Value.print ppf v)
46    
47  let dump_env ppf =  let dump_value ppf x t v =
48    Format.fprintf ppf "Global types:";    Format.fprintf ppf "@[val %a : @[%a = %a@]@]@."
49    Typer.TypeEnv.iter (fun x _ -> Format.fprintf ppf " %s" x) !glb_env;      U.print (Id.value x) print_norm t print_value v
   Format.fprintf ppf ".@\n";  
   Eval.Env.iter  
     (fun x v ->  
        let t = Typer.Env.find x !typing_env in  
        Format.fprintf ppf "@[|- %s : %a@ => %a@]@\n"  
          (Id.value x)  
          print_norm t  
          print_value v  
     )  
     !eval_env  
50    
51    let dump_env ppf =
52      Format.fprintf ppf "Types:%a@." Typer.dump_types !typing_env;
53      Format.fprintf ppf "Namespace prefixes:@\n%a" Typer.dump_ns !typing_env;
54      Format.fprintf ppf "Namespace prefixes used for pretty-printing:@.%t"
55        Ns.InternalPrinter.dump;
56      Format.fprintf ppf "Values:@.";
57      Typer.iter_values !typing_env
58        (fun x t -> dump_value ppf x t (get_global_value x))
59    
60  let rec print_exn ppf = function  let rec print_exn ppf = function
61    | Location (loc, exn) ->    | Location (loc, w, exn) ->
62        Format.fprintf ppf "Error %a:@\n" Location.print_loc loc;        Format.fprintf ppf "Error %a:@." Location.print_loc (loc,w);
63        Format.fprintf ppf "%a" Location.html_hilight loc;        Format.fprintf ppf "%a" Location.html_hilight (loc,w);
64        print_exn ppf exn        print_exn ppf exn
65    | Value.CDuceExn v ->    | Value.CDuceExn v ->
66        Format.fprintf ppf "Uncaught CDuce exception: @[%a@]@\n"        Format.fprintf ppf "Uncaught CDuce exception: @[%a@]@."
67          print_value v          print_value v
68      | Eval.MultipleDeclaration v ->
69          Format.fprintf ppf "Multiple declaration for global value %a@."
70            U.print (Id.value v)
71    | Typer.WrongLabel (t,l) ->    | Typer.WrongLabel (t,l) ->
72        Format.fprintf ppf "Wrong record selection: the label %s@\n"        Format.fprintf ppf "Wrong record selection; field %a "
73          (LabelPool.value l);          Label.print (LabelPool.value l);
74        Format.fprintf ppf "applied to an expression of type %a@\n"        Format.fprintf ppf "not present in an expression of type:@.%a@."
75          print_norm t          print_norm t
76    | Typer.ShouldHave (t,msg) ->    | Typer.ShouldHave (t,msg) ->
77        Format.fprintf ppf "This expression should have type %a@\n%s@\n"        Format.fprintf ppf "This expression should have type:@.%a@.%a@."
78          print_norm t          print_norm t
79          msg          print_protect msg
80    | Typer.Constraint (s,t,msg) ->    | Typer.ShouldHave2 (t1,msg,t2) ->
81        Format.fprintf ppf "This expression should have type %a@\n"        Format.fprintf ppf "This expression should have type:@.%a@.%a %a@."
82            print_norm t1
83            print_protect msg
84            print_norm t2
85      | Typer.Error s ->
86          Format.fprintf ppf "%a@." print_protect s
87      | Typer.Constraint (s,t) ->
88          Format.fprintf ppf "This expression should have type:@.%a@."
89          print_norm t;          print_norm t;
90        Format.fprintf ppf "but its infered type is: %a@\n"        Format.fprintf ppf "but its inferred type is:@.%a@."
91          print_norm s;          print_norm s;
92        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@."
93          Types.Sample.print (Types.Sample.get (Types.diff s t));          print_sample (Sample.get (Types.diff s t))
       Format.fprintf ppf "%s@\n" msg  
94    | Typer.NonExhaustive t ->    | Typer.NonExhaustive t ->
95        Format.fprintf ppf "This pattern matching is not exhaustive@\n";        Format.fprintf ppf "This pattern matching is not exhaustive@.";
96        Format.fprintf ppf "Residual type: %a@\n"        Format.fprintf ppf "Residual type:@.%a@."
97          print_norm t;          print_norm t;
98        Format.fprintf ppf "Sample value: %a@\n"        Format.fprintf ppf "Sample:@.%a@." print_sample (Sample.get t)
99          Types.Sample.print (Types.Sample.get t)    | Typer.UnboundId (x,tn) ->
100    | Typer.UnboundId x ->        Format.fprintf ppf "Unbound identifier %a%s@." U.print (Id.value x)
101        Format.fprintf ppf "Unbound identifier %s@\n" x          (if tn then " (it is a type name)" else "")
102    | Wlexer.Illegal_character c ->    | Ulexer.Error (i,j,s) ->
103        Format.fprintf ppf "Illegal character (%s)@\n" (Char.escaped c)        let loc = Location.loc_of_pos (i,j), `Full in
104    | Wlexer.Unterminated_comment ->        Format.fprintf ppf "Error %a:@." Location.print_loc loc;
105        Format.fprintf ppf "Comment not terminated@\n"        Format.fprintf ppf "%a%s" Location.html_hilight loc s
   | Wlexer.Unterminated_string ->  
       Format.fprintf ppf "String literal not terminated@\n"  
   | Wlexer.Unterminated_string_in_comment ->  
       Format.fprintf ppf "This comment contains an unterminated string literal@\n"  
106    | Parser.Error s | Stream.Error s ->    | Parser.Error s | Stream.Error s ->
107        Format.fprintf ppf "Parsing error: %s@\n" s        Format.fprintf ppf "Parsing error: %a@." print_protect s
108    | Location.Generic s ->    | Location.Generic s ->
109        Format.fprintf ppf "%s@\n" s        Format.fprintf ppf "%a@." print_protect s
110    | exn ->    | exn ->
111        raise exn  (*      raise exn *)
112  (*        Format.fprintf ppf "%a@." print_protect (Printexc.to_string exn)
113        Format.fprintf ppf "%s@\n" (Printexc.to_string exn)  
114  *)  
115    let display ppf l =
116      if not !quiet then
117        List.iter
118          (fun (x,t) -> dump_value ppf x t (get_global_value x))
119          l
120    
121    let eval ppf e =
122      let (e,t) = Typer.type_expr !typing_env e in
123    
124      if not !quiet then
125        Location.dump_loc ppf (e.Typed.exp_loc,`Full);
126    
127      let v =
128        if !do_compile then
129          let e = Compile.compile_eval !compile_env e in
130          Eval.L.expr e
131        else
132          Eval.eval !eval_env e
133      in
134      if not !quiet then
135        Format.fprintf ppf "- : @[@[%a@] =@ @[%a@]@]@."
136          print_norm t print_value v;
137      v
138    
139    let let_decl ppf p e =
140      let (tenv,decl,typs) = Typer.type_let_decl !typing_env p e in
141    
142      let () =
143        if !do_compile then
144          let (env,decl) = Compile.compile_let_decl !compile_env decl in
145          Eval.L.eval decl;
146          compile_env := env
147        else
148          eval_env := Eval.eval_let_decl !eval_env decl
149      in
150      typing_env := tenv;
151      display ppf typs
152    
153    
154    let let_funs ppf funs =
155      let (tenv,funs,typs) = Typer.type_let_funs !typing_env funs in
156    
157      let () =
158        if !do_compile then
159          let (env,funs) = Compile.compile_rec_funs !compile_env funs in
160          Eval.L.eval funs;
161          compile_env := env;
162        else
163          eval_env := Eval.eval_rec_funs !eval_env funs
164      in
165      typing_env := tenv;
166      display ppf typs
167    
168    
169  let debug ppf = function  let debug ppf = function
170    | `Subtype (t1,t2) ->    | `Subtype (t1,t2) ->
171        Format.fprintf ppf "[DEBUG:subtype]@\n";        Format.fprintf ppf "[DEBUG:subtype]@.";
172        let t1 = Types.descr (Typer.typ !glb_env t1)        let t1 = Types.descr (Typer.typ !typing_env t1)
173        and t2 = Types.descr (Typer.typ !glb_env t2) in        and t2 = Types.descr (Typer.typ !typing_env t2) in
174        Format.fprintf ppf "%a <= %a : %b@\n" print_norm t1 print_norm t2        let s = Types.subtype t1 t2 in
175          (Types.subtype t1 t2)        Format.fprintf ppf "%a %a %a : %b@." print_norm t1 print_protect "<=" print_norm t2 s
176      | `Sample t ->
177          Format.fprintf ppf "[DEBUG:sample]@.";
178          (try
179             let t = Types.descr (Typer.typ !typing_env t) in
180             Format.fprintf ppf "%a@." print_sample (Sample.get t)
181           with Not_found ->
182             Format.fprintf ppf "Empty type : no sample !@.")
183    | `Filter (t,p) ->    | `Filter (t,p) ->
184        Format.fprintf ppf "[DEBUG:filter]@\n";        Format.fprintf ppf "[DEBUG:filter]@.";
185        let t = Typer.typ !glb_env t        let t = Typer.typ !typing_env t
186        and p = Typer.pat !glb_env p in        and p = Typer.pat !typing_env p in
187        let f = Patterns.filter (Types.descr t) p in        let f = Patterns.filter (Types.descr t) p in
188        List.iter (fun (x,t) ->        List.iter (fun (x,t) ->
189                     Format.fprintf ppf " %s:%a@\n" (Id.value x)                     Format.fprintf ppf " %a:%a@." U.print (Id.value x)
190                       print_norm (Types.descr t)) f                       print_norm (Types.descr t)) f
   | `Compile2 (t,pl) ->  
       Format.fprintf ppf "[DEBUG:compile2]@\n";  
 (*      let t = Types.descr (Typer.typ !glb_env t) in  
       let pl = List.map (fun p ->  
                            let p = Typer.pat !glb_env p in  
                            let a = Types.descr (Patterns.accept p) in  
                            (Some p, Types.cap a t)) pl in  
       let d = Patterns.Compiler.make_dispatcher t pl in  
       Patterns.Compiler.print_disp ppf d *)  
       ()  
   
191    | `Accept p ->    | `Accept p ->
192        Format.fprintf ppf "[DEBUG:accept]@\n";        Format.fprintf ppf "[DEBUG:accept]@.";
193        let p = Typer.pat !glb_env p in        let p = Typer.pat !typing_env p in
194        let t = Patterns.accept p in        let t = Patterns.accept p in
195        Format.fprintf ppf " %a@\n" Types.Print.print t        Format.fprintf ppf " %a@." Types.Print.print (Types.descr t)
196    | `Compile (t,pl) ->    | `Compile (t,pl) ->
197        Format.fprintf ppf "[DEBUG:compile]@\n";        Format.fprintf ppf "[DEBUG:compile]@.";
198        let t = Typer.typ !glb_env t        let t = Typer.typ !typing_env t
199        and pl = List.map (Typer.pat !glb_env) pl in        and pl = List.map (Typer.pat !typing_env) pl in
200        Patterns.Compile.debug_compile ppf t pl        Patterns.Compile.debug_compile ppf t pl
201    | `Normal_record p -> assert false    | `Explain (t,e) ->
202          Format.fprintf ppf "[DEBUG:explain]@.";
203          let t = Typer.typ !typing_env t in
204          (match Explain.explain (Types.descr t) (eval ppf e) with
205  let mk_builtin () =           | Some p ->
206    let bi = List.map (fun (n,t) -> [n, mk noloc (Ast.Internal t)])               Format.fprintf ppf "Explanation: @[%a@]@."
207               Builtin.types in                 Explain.print_path p
208    glb_env := List.fold_left Typer.register_global_types !glb_env bi           | None ->
209                 Format.fprintf ppf "Explanation: value has given type@.")
210  let () = mk_builtin ()  
211    
212    let rec collect_funs ppf accu = function
213      | { descr = Ast.FunDecl e } :: rest -> collect_funs ppf (e::accu) rest
214      | rest -> let_funs ppf accu; rest
215    
216    let rec collect_types ppf accu = function
217      | { descr = Ast.TypeDecl (x,t) } :: rest ->
218          collect_types ppf ((x,t) :: accu) rest
219      | rest ->
220          typing_env :=
221            Typer.enter_types (Typer.type_defs !typing_env accu) !typing_env;
222          rest
223    
224    
225    let rec phrases ppf phs = match phs with
226      | { descr = Ast.FunDecl _ } :: _ ->
227          phrases ppf (collect_funs ppf [] phs)
228      | { descr = Ast.TypeDecl (_,_) } :: _ ->
229          phrases ppf (collect_types ppf [] phs)
230      | { descr = Ast.SchemaDecl (name, schema) } :: rest ->
231          Typer.register_schema name schema;
232          phrases ppf rest
233      | { descr = Ast.Namespace (pr,ns) } :: rest ->
234          typing_env := Typer.enter_ns pr ns !typing_env;
235          phrases ppf rest
236      | { descr = Ast.EvalStatement e } :: rest ->
237          ignore (eval ppf e);
238          phrases ppf rest
239      | { descr = Ast.LetDecl (p,e) } :: rest ->
240          let_decl ppf p e;
241          phrases ppf rest
242      | { descr = Ast.Debug l } :: rest ->
243          debug ppf l;
244          phrases ppf rest
245      | { descr = Ast.Directive `Quit } :: rest ->
246          if !toplevel then raise End_of_file;
247          phrases ppf rest
248      | { descr = Ast.Directive `Env } :: rest ->
249          dump_env ppf;
250          phrases ppf rest
251      | { descr = Ast.Directive `Reinit_ns } :: rest ->
252          Typer.set_ns_table_for_printer !typing_env;
253          phrases ppf rest
254      | [] -> ()
255    
256    let catch_exn ppf_err = function
257      | (End_of_file | Failure _ | Not_found | Invalid_argument _ | Sys.Break)
258          as e ->
259          raise e
260      | exn ->
261          print_exn ppf_err exn;
262          Format.fprintf ppf_err "@."
263    
264  let run ppf ppf_err input =  let parse rule input =
265    let insert_type_bindings =    try Some (rule input)
266      List.iter (fun (x,t) ->    with
267                   typing_env := Typer.Env.add x t !typing_env;        | Stdpp.Exc_located (_, (Location _ as e)) ->
268                   if not !quiet then            Parser.sync (); raise e
269                     Format.fprintf ppf "|- %s : %a@\n@." (Id.value x) print_norm t)        | Stdpp.Exc_located ((i,j), e) ->
270    in            Parser.sync (); raise_loc i j e
271    
272    let run rule ppf ppf_err input =
273      try match parse rule input with
274        | Some phs -> phrases ppf phs; true
275        | None -> false
276      with exn -> catch_exn ppf_err exn; false
277    
278    let type_decl decl =  let script = run Parser.prog
279      insert_type_bindings (Typer.type_let_decl !typing_env decl)  let topinput = run Parser.top_phrases
   in  
280    
281    let eval_decl decl =  let comp_unit src =
282      let bindings = Eval.eval_let_decl Eval.Env.empty decl in    try
283      List.iter      let ic = open_in src in
284        (fun (x,v) ->      Location.push_source (`File src);
285           Eval.enter_global x v;      let input = Stream.of_channel ic in
286           if not !quiet then      match parse Parser.prog input with
287             Format.fprintf ppf "=> %s : @[%a@]@\n@." (Id.value x) print_value v        | Some p ->
288        ) bindings            close_in ic;
289    in            let argv = ident (U.mk "argv") in
290              let (tenv,cenv,codes) =
291    let phrase ph =              Compile.comp_unit
292      match ph.descr with                (Typer.enter_value argv (Sequence.star Sequence.string)
293        | Ast.EvalStatement e ->                   Builtin.env)
294            let (fv,e) = Typer.expr !glb_env e in                (Compile.enter_global Compile.empty argv)
295            let t = Typer.type_check !typing_env e Types.any true in                p in
296            Location.dump_loc ppf e.Typed.exp_loc;            codes
297            if not !quiet then        | None -> exit 1
298              Format.fprintf ppf "|- %a@\n@." print_norm t;      with exn -> catch_exn Format.err_formatter exn; exit 1
           let v = Eval.eval Eval.Env.empty e in  
           if not !quiet then  
             Format.fprintf ppf "=> @[%a@]@\n@." print_value v  
       | Ast.LetDecl (p,{descr=Ast.Abstraction _}) -> ()  
       | Ast.LetDecl (p,e) ->  
           let decl = Typer.let_decl !glb_env p e in  
           type_decl decl;  
           eval_decl decl  
       | Ast.TypeDecl _ -> ()  
       | Ast.Debug l -> debug ppf l  
       | _ -> assert false  
   in  
299    
300    let do_fun_decls decls =  let run_code argv codes =
     let decls = List.map (fun (p,e) -> Typer.let_decl !glb_env p e) decls in  
     insert_type_bindings (Typer.type_rec_funs !typing_env decls);  
     List.iter eval_decl decls  
   in  
   let rec phrases funs = function  
     | { descr = Ast.LetDecl (p,({descr=Ast.Abstraction _} as e))} :: phs ->  
         phrases ((p,e)::funs) phs  
     | ph :: phs ->  
         do_fun_decls funs;  
         phrase ph;  
         phrases [] phs  
     | _ ->  
         do_fun_decls funs  
   in  
301    try    try
302      let p =      Eval.L.push argv;
303        try Parser.prog input      List.iter Eval.L.eval codes
304        with    with exn -> catch_exn Format.err_formatter exn; exit 1
305          | Stdpp.Exc_located (_, (Location _ as e)) -> raise e  
306          | Stdpp.Exc_located (loc, e) -> raise (Location (loc, e))  
307      in  let compile src =
308      let (type_decls,fun_decls) =    let codes = comp_unit src in
309        List.fold_left    let oc = open_out (src ^ ".out") in
310          (fun ((typs,funs) as accu) ph -> match ph.descr with    let codes_s = Serialize.Put.run Lambda.Put.compunit codes in
311             | Ast.TypeDecl (x,t) -> ((x,t) :: typs,funs)    output_string oc codes_s;
312             | Ast.LetDecl (p,({descr=Ast.Abstraction _} as e)) ->    close_out oc;
313                 (typs, (p,e)::funs)    exit 0
314             | _ -> accu  
315          ) ([],[]) p in  let compile_run src argv =
316      glb_env := Typer.register_global_types !glb_env type_decls;    run_code argv (comp_unit src)
317      phrases [] p;  
318      true  let run obj argv =
319    with    let ic = open_in obj in
320      | (Failure _ | Not_found | Invalid_argument _) as e ->    let len = in_channel_length ic in
321          raise e  (* To get ocamlrun stack trace *)    let codes = String.create len in
322      | exn -> print_exn ppf_err exn; false    really_input ic codes 0 len;
323      close_in ic;
324      let codes = Serialize.Get.run Lambda.Get.compunit codes in
325      run_code argv codes
326    
327    
328    let serialize_typing_env t () =
329      Typer.serialize t !typing_env
330    
331    let deserialize_typing_env t =
332      typing_env := Typer.deserialize t

Legend:
Removed from v.233  
changed lines
  Added in v.698

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