/[svn]/typing/typer.ml
ViewVC logotype

Diff of /typing/typer.ml

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

revision 5 by abate, Tue Jul 10 16:57:03 2007 UTC revision 6 by abate, Tue Jul 10 16:57:08 2007 UTC
# Line 253  Line 253 
253    
254  (* II. Build skeleton *)  (* II. Build skeleton *)
255    
256    module Fv = StringSet
257    
258  let rec expr { loc = loc; descr = d } =  let rec expr { loc = loc; descr = d } =
259    let td =    let (fv,td) =
260      match d with      match d with
261        | Var s -> Typed.Var s        | Var s -> (Fv.singleton s, Typed.Var s)
262        | Apply (e1,e2) -> Typed.Apply (expr e1, expr e2)        | Apply (e1,e2) ->
263              let (fv1,e1) = expr e1 and (fv2,e2) = expr e2 in
264              (Fv.union fv1 fv2, Typed.Apply (e1,e2))
265        | Abstraction a ->        | Abstraction a ->
266              let iface = List.map (fun (t1,t2) -> (typ t1, typ t2)) a.fun_iface in
267              let t = List.fold_left
268                        (fun accu (t1,t2) -> Types.cap accu (Types.arrow t1 t2))
269                        Types.any iface in
270              let (fv0,body) = branches a.fun_body in
271              let fv = match a.fun_name with
272                | None -> fv0
273                | Some f -> Fv.remove f fv0 in
274              (fv,
275            Typed.Abstraction            Typed.Abstraction
276              { Typed.fun_name = a.fun_name;              { Typed.fun_name = a.fun_name;
277                Typed.fun_iface =                 Typed.fun_iface = iface;
278                  List.map (fun (t1,t2) -> (typ t1, typ t2)) a.fun_iface;                 Typed.fun_body = body;
279                Typed.fun_body =                 Typed.fun_typ = t;
280                  branches a.fun_body                 Typed.fun_fv = Fv.elements fv0
281              }              }
282        | Cst c -> Typed.Cst c            )
283        | Pair (e1,e2) -> Typed.Pair (expr e1, expr e2)        | Cst c -> (Fv.empty, Typed.Cst c)
284        | RecordLitt r -> Typed.RecordLitt (List.map (fun (l,e) -> (l, expr e)) r)        | Pair (e1,e2) ->
285        | Op (o,e) -> Typed.Op (o, expr e)            let (fv1,e1) = expr e1 and (fv2,e2) = expr e2 in
286        | Match (e,b) -> Typed.Match (expr e, branches b)            (Fv.union fv1 fv2, Typed.Pair (e1,e2))
287        | Map (e,b) -> Typed.Map (expr e, branches b)        | RecordLitt r ->
288              (* XXX TODO: check that no label appears twice *)
289              let fv = ref Fv.empty in
290              let r = List.map
291                        (fun (l,e) ->
292                           let (fv2,e) = expr e in
293                           fv := Fv.union !fv fv2;
294                           (l,e)
295                        ) r in
296              (!fv, Typed.RecordLitt r)
297          | Op (o,e) ->
298              let (fv,e) = expr e in (fv, Typed.Op (o,e))
299          | Match (e,b) ->
300              let (fv1,e) = expr e
301              and (fv2,b) = branches b in
302              (Fv.union fv1 fv2, Typed.Match (e, b))
303          | Map (e,b) ->
304              let (fv1,e) = expr e
305              and (fv2,b) = branches b in
306              (Fv.union fv1 fv2, Typed.Map (e, b))
307    in    in
308    { Typed.loc = loc;    fv,
309      { Typed.exp_loc = loc;
310      Typed.exp_typ = Types.empty;      Typed.exp_typ = Types.empty;
311      Typed.exp_descr = td;      Typed.exp_descr = td;
     Typed.fv = []  (* XXX TODO *)  
312    }    }
313    
314    and branches b = List.map branch b    and branches b =
315    and branch (p,e) =      let fv = ref Fv.empty in
316      { Typed.used = false;      let b = List.map
317                  (fun (p,e) ->
318                     let (fv2,e) = expr e in
319                     fv := Fv.union !fv fv2;
320                     { Typed.br_used = false;
321        Typed.br_typ = Types.empty;        Typed.br_typ = Types.empty;
322        Typed.br_pat = pat p;        Typed.br_pat = pat p;
323        Typed.br_body = expr e }                     Typed.br_body = e }
324                  ) b in
325        (!fv,b)
326    
327    module Env = StringMap
328    
329    open Typed
330    
331    let rec compute_type env e =
332      let d = compute_type' e.exp_loc env e.exp_descr in
333      e.exp_typ <- Types.cup e.exp_typ d;
334      d
335    
336    and compute_type' loc env = function
337      | Var s -> Env.find s env
338      | Apply (e1,e2) ->
339          let t1 = compute_type env e1 and t2 = compute_type env e2 in
340          Types.apply t1 t2
341      | Abstraction a ->
342          let env = match a.fun_name with
343            | None -> env
344            | Some f -> Env.add f a.fun_typ env in
345          List.iter (fun (t1,t2) ->
346                       let t = type_branches env (Types.descr t1) a.fun_body in
347                       if not (Types.subtype t (Types.descr t2)) then
348                         failwith "Constraint not satisfied"
349                    ) a.fun_iface;
350          a.fun_typ
351      | Cst c -> Types.constant c
352      | Pair (e1,e2) ->
353          let t1 = compute_type env e1 and t2 = compute_type env e2 in
354          let t1 = Types.cons t1 and t2 = Types.cons t2 in
355          Types.times t1 t2
356      | RecordLitt r ->
357          List.fold_left
358            (fun accu (l,e) ->
359               let t = compute_type env e in
360               let t = Types.record l false (Types.cons t) in
361               Types.cap accu t
362            ) Types.Record.any r
363      | Op (op,e) -> assert false
364      | Match (e,b) ->
365          let t = compute_type env e in
366          type_branches env t b
367      | Map (e,b) -> assert false
368    
369    and type_branches env targ branches =
370      if Types.is_empty targ then Types.empty
371      else branches_aux env targ Types.empty branches
372    
373    and branches_aux env targ tres = function
374      | [] -> failwith "Non-exhaustive pattern matching"
375      | b :: rem ->
376          let p = b.br_pat in
377          let acc = Types.descr (Patterns.accept p) in
378    
379          let targ' = Types.cap targ acc in
380          if Types.is_empty targ'
381          then branches_aux env targ tres rem
382          else
383            ( b.br_used <- true;
384              let res = Patterns.filter targ' p in
385              let env' = List.fold_left
386                           (fun env (x,t) -> Env.add x (Types.descr t) env)
387                           env res in
388              let t = compute_type env' b.br_body in
389              branches_aux env (Types.diff targ acc) (Types.cup t tres) rem
390            )
391    
392    
 let compute_type t = failwith "Not yet implemented"  

Legend:
Removed from v.5  
changed lines
  Added in v.6

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