/[svn]/types/patterns.ml
ViewVC logotype

Contents of /types/patterns.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (hide annotations)
Tue Jul 10 17:00:17 2007 UTC (5 years, 10 months ago) by abate
File size: 40791 byte(s)
[r2002-10-25 19:16:26 by cvscast] Empty log message

Original author: cvscast
Date: 2002-10-25 19:16:27+00:00
1 abate 1 type capture = string
2     type fv = capture SortedList.t
3    
4     exception IllFormedCup of fv * fv
5     exception IllFormedCap of fv * fv
6    
7     (* Syntactic algebra *)
8    
9     type d =
10     | Constr of Types.node
11     | Cup of descr * descr
12     | Cap of descr * descr
13     | Times of node * node
14     | Record of Types.label * node
15     | Capture of capture
16     | Constant of capture * Types.const
17     and node = {
18     id : int;
19     mutable descr : descr option;
20     accept : Types.node;
21     fv : fv
22     } and descr = Types.descr * fv * d
23    
24     let make =
25     let counter = ref 0 in
26     fun fv ->
27     incr counter;
28     { id = !counter; descr = None; accept = Types.make (); fv = fv }
29    
30     let define x ((accept,fv,_) as d) =
31     assert (x.fv = fv);
32     Types.define x.accept accept;
33     x.descr <- Some d
34    
35     let constr x = (Types.descr x,[],Constr x)
36     let cup ((acc1,fv1,_) as x1) ((acc2,fv2,_) as x2) =
37     if fv1 <> fv2 then raise (IllFormedCup (fv1,fv2));
38     (Types.cup acc1 acc2, SortedList.cup fv1 fv2, Cup (x1,x2))
39     let cap ((acc1,fv1,_) as x1) ((acc2,fv2,_) as x2) =
40     if not (SortedList.disjoint fv1 fv2) then raise (IllFormedCap (fv1,fv2));
41     (Types.cap acc1 acc2, SortedList.cup fv1 fv2, Cap (x1,x2))
42     let times x y =
43     (Types.times x.accept y.accept, SortedList.cup x.fv y.fv, Times (x,y))
44     let record l x =
45     (Types.record l false x.accept, x.fv, Record (l,x))
46     let capture x = (Types.any, [x], Capture x)
47     let constant x c = (Types.any, [x], Constant (x,c))
48    
49    
50     let id x = x.id
51     let descr x = match x.descr with Some d -> d | None -> failwith "Patterns.descr"
52     let fv x = x.fv
53     let accept x = Types.internalize x.accept
54    
55    
56     (* Static semantics *)
57    
58     let cup_res v1 v2 = Types.Positive.cup [v1;v2]
59     let empty_res fv = List.map (fun v -> (v, Types.Positive.ty Types.empty)) fv
60     let times_res v1 v2 = Types.Positive.times v1 v2
61    
62     module MemoFilter = Map.Make
63     (struct type t = Types.descr * node let compare = compare end)
64    
65     let memo_filter = ref MemoFilter.empty
66    
67     let rec filter_descr t (_,fv,d) : (capture, Types.Positive.v) SortedMap.t =
68     if Types.is_empty t
69     then empty_res fv
70     else
71     match d with
72     | Constr _ -> []
73     | Cup ((a,_,_) as d1,d2) ->
74     SortedMap.union cup_res
75     (filter_descr (Types.cap t a) d1)
76     (filter_descr (Types.diff t a) d2)
77     | Cap (d1,d2) ->
78     SortedMap.union cup_res (filter_descr t d1) (filter_descr t d2)
79     | Times (p1,p2) ->
80     List.fold_left
81     (fun accu (d1,d2) ->
82     let term =
83     SortedMap.union times_res
84     (filter_node d1 p1)
85     (filter_node d2 p2)
86     in
87     SortedMap.union cup_res accu term
88     )
89     (empty_res fv)
90     (Types.Product.normal t)
91     | Record (l,p) ->
92     filter_node (Types.Record.project t l) p
93     | Capture c ->
94     [(c, Types.Positive.ty t)]
95     | Constant (c, cst) ->
96     [(c, Types.Positive.ty (Types.constant cst))]
97    
98     and filter_node t p : (capture, Types.Positive.v) SortedMap.t =
99     try MemoFilter.find (t,p) !memo_filter
100     with Not_found ->
101     let (_,fv,_) as d = descr p in
102     let res = List.map (fun v -> (v,Types.Positive.forward ())) fv in
103     memo_filter := MemoFilter.add (t,p) res !memo_filter;
104     let r = filter_descr t (descr p) in
105     List.iter2 (fun (_,r) (_,v) -> Types.Positive.define v r) r res;
106     r
107    
108     let filter t p =
109     let r = filter_node t p in
110     memo_filter := MemoFilter.empty;
111     List.map (fun (c,v) -> (c,Types.Positive.solve v)) r
112    
113    
114    
115     (* Normal forms for patterns and compilation *)
116    
117     module NF =
118     struct
119    
120     type 'a sl = 'a SortedList.t
121     type ('a,'b) sm = ('a,'b) SortedMap.t
122    
123     type source =
124     [ `Catch | `Const of Types.const
125     | `Left | `Right | `Recompose
126     | `Field of Types.label
127     ]
128     type result = (capture, source) sm
129    
130 abate 39 type 'a line = (result * 'a, Types.descr) sm
131 abate 1 type nf = {
132     v : fv;
133     a : Types.descr;
134 abate 39 basic : unit line;
135     prod : (node sl * node sl) line;
136     record: ((Types.label, node sl) sm) line
137 abate 1 }
138    
139 abate 39 type 'a nline = (result * 'a) list
140     type record =
141     [ `Success
142     | `Fail
143     | `Dispatch of (nf * record) list
144     | `Label of Types.label * (nf * record) list * record ]
145     type normal = {
146 abate 42 nfv : fv;
147     na : Types.descr;
148 abate 39 nbasic : Types.descr nline;
149     nprod : (nf * nf) nline;
150     nrecord: record nline
151     }
152    
153 abate 1 let empty = { v = []; a = Types.empty; basic = []; prod = []; record = [] }
154     let any_basic = Types.neg (Types.cup Types.Product.any Types.Record.any)
155    
156    
157     let restrict t nf =
158 abate 39 let rec filter = function
159     | (key,acc) :: rem ->
160     let acc = Types.cap t acc in
161     if Types.is_empty acc then filter rem else (key,acc) :: (filter rem)
162     | [] -> []
163     in
164 abate 1 { v = nf.v;
165     a = Types.cap t nf.a;
166 abate 39 basic = filter nf.basic;
167     prod = filter nf.prod;
168     record = filter nf.record;
169 abate 1 }
170    
171     let fus = SortedMap.union_disj
172     let slcup = SortedList.cup
173    
174     let cap nf1 nf2 =
175 abate 39 let merge f lines1 lines2 =
176     let m =
177     List.fold_left
178     (fun accu ((res1,x1),acc1) ->
179     List.fold_left
180     (fun accu ((res2,x2),acc2) ->
181     let acc = Types.cap acc1 acc2 in
182     if Types.is_empty acc then accu
183     else ((fus res1 res2, f x1 x2),acc) :: accu
184     ) accu lines2
185     ) [] lines1 in
186     SortedMap.from_list Types.cup m
187     in
188     let merge_basic () () = ()
189 abate 42 and merge_prod (p1,q1) (p2,q2) = slcup p1 p2, slcup q1 q2
190 abate 39 and merge_record r1 r2 = SortedMap.union slcup r1 r2 in
191 abate 1 { v = SortedList.cup nf1.v nf2.v;
192     a = Types.cap nf1.a nf2.a;
193 abate 39 basic = merge merge_basic nf1.basic nf2.basic;
194     prod = merge merge_prod nf1.prod nf2.prod;
195     record = merge merge_record nf1.record nf2.record;
196 abate 1 }
197    
198    
199    
200     let cup acc1 nf1 nf2 =
201     let nf2 = restrict (Types.neg acc1) nf2 in
202 abate 39 { v = nf1.v; (* = nf2.v *)
203 abate 1 a = Types.cup nf1.a nf2.a;
204     basic = SortedMap.union Types.cup nf1.basic nf2.basic;
205 abate 39 prod = SortedMap.union Types.cup nf1.prod nf2.prod;
206     record = SortedMap.union Types.cup nf1.record nf2.record;
207 abate 1 }
208    
209     let times acc p q =
210     let src_p = List.map (fun v -> (v,`Left)) p.fv
211     and src_q = List.map (fun v -> (v,`Right)) q.fv in
212     let src = SortedMap.union (fun _ _ -> `Recompose) src_p src_q in
213     { empty with
214     v = SortedList.cup p.fv q.fv;
215     a = acc;
216 abate 39 prod = [ (src, ([p], [q])), acc ] }
217 abate 1
218     let record acc l p =
219     let src = List.map (fun v -> (v, `Field l)) p.fv in
220     { empty with
221     v = p.fv;
222     a = acc;
223 abate 39 record = [ (src, [l,[p]]), acc ] }
224 abate 1
225     let any =
226     { v = [];
227     a = Types.any;
228 abate 39 basic = [ ([],()), any_basic ];
229     prod = [ ([],([],[])), Types.Product.any ];
230     record = [ ([],[]), Types.Record.any ];
231 abate 1 }
232    
233     let capture x =
234     let l = [x,`Catch] in
235     { v = [x];
236     a = Types.any;
237 abate 39 basic = [ (l,()), any_basic ];
238     prod = [ (l,([],[])), Types.Product.any ];
239     record = [ (l,[]), Types.Record.any ];
240 abate 1 }
241    
242     let constant x c =
243     let l = [x,`Const c] in
244     { v = [x];
245     a = Types.any;
246 abate 39 basic = [ (l,()), any_basic ];
247     prod = [ (l,([],[])), Types.Product.any ];
248     record = [ (l,[]), Types.Record.any ];
249 abate 1 }
250    
251     let constr t =
252     { v = [];
253     a = t;
254 abate 39 basic = [ ([],()), Types.cap t any_basic ];
255     prod = [ ([],([],[])), Types.cap t Types.Product.any ];
256     record = [ ([],[]), Types.cap t Types.Record.any ];
257 abate 1 }
258    
259     (* Put a pattern in normal form *)
260     let rec nf (acc,fv,d) =
261     if Types.is_empty acc
262     then empty
263     else match d with
264     | Constr t -> constr (Types.descr t)
265     | Cap (p,q) -> cap (nf p) (nf q)
266     | Cup ((acc1,_,_) as p,q) -> cup acc1 (nf p) (nf q)
267     | Times (p,q) -> times acc p q
268     | Capture x -> capture x
269     | Constant (x,c) -> constant x c
270     | Record (l,p) -> record acc l p
271    
272     let bigcap = List.fold_left (fun a p -> cap a (nf (descr p))) any
273    
274     let rec num i = function [] -> [] | h::t -> (h,i)::(num (i+1) t)
275    
276 abate 39 let normal nf =
277     let basic =
278     List.map (fun ((res,()),acc) -> (res,acc))
279    
280     and prod =
281     let line accu (((res,(pl,ql)),acc)) =
282     let p = bigcap pl and q = bigcap ql in
283     let aux accu (t1,t2) = (res,(restrict t1 p,restrict t2 q))::accu in
284     List.fold_left aux accu (Types.Product.normal acc) in
285     List.fold_left line []
286    
287     and record =
288     let rec aux nr fields =
289     match (nr,fields) with
290     | (`Success, []) -> `Success
291     | (`Fail,_) -> `Fail
292     | (`Success, (l2,pl)::fields) ->
293     `Label (l2, [bigcap pl, aux nr fields], `Fail)
294     | (`Label (l1, _, _), (l2,pl)::fields) when l2 < l1 ->
295     `Label (l2, [bigcap pl, aux nr fields], `Fail)
296     | (`Label (l1, pr, _), (l2,pl)::fields) when l1 = l2 ->
297     let p = bigcap pl in
298     let pr =
299     List.map (fun (t,x) -> (restrict t p, aux x fields)) pr in
300     `Label (l1, pr, `Fail)
301     | (`Label (l1, pr, ab),_) ->
302     let pr =
303     List.map (fun (t,x) -> (constr t, aux x fields)) pr in
304     `Label (l1, pr, aux ab fields)
305     in
306    
307     let line accu ((res,fields),acc) =
308     let nr = Types.Record.normal acc in
309     let x = aux nr fields in
310     match x with
311     | `Fail -> accu
312     | x -> (res,x) :: accu in
313     List.fold_left line []
314     in
315 abate 42 { nfv = nf.v;
316     na = nf.a;
317     nbasic = basic nf.basic;
318 abate 39 nprod = prod nf.prod;
319     nrecord = record nf.record;
320     }
321    
322 abate 42
323     module Disp = struct
324    
325     type actions = {
326     basic: (Types.descr * result) list;
327     prod: result dispatch dispatch;
328     record: record option;
329     }
330     and record =
331     [ `Label of Types.label * record dispatch * record option
332     | `Result of result ]
333    
334     and 'a dispatch = dispatcher * 'a array
335     and result = int * source list
336     and source =
337     [ `Catch | `Const of Types.const
338     | `Left of int | `Right of int | `Recompose of int * int
339     | `Field of Types.label * int
340     ]
341    
342     and dispatcher = {
343     id : int;
344     t : Types.descr;
345     pl : normal array;
346     interface : (Types.descr * int * (capture, int) sm option array) array;
347     mutable actions : actions option
348     }
349    
350     let cur_id = ref 0
351    
352     module DispMap = Map.Make(
353     struct
354     type t = Types.descr * normal array
355     let compare = compare
356     end
357     )
358    
359     let dispatchers = ref DispMap.empty
360    
361     let dispatcher t pl : dispatcher =
362     try DispMap.find (t,pl) !dispatchers
363     with Not_found ->
364     let res = ref [] in
365     let rec aux t bindings arity i =
366     if Types.non_empty t
367     then
368     if i = Array.length pl
369     then res := (t, arity, Array.of_list (List.rev bindings)) :: !res
370     else
371     let p = pl.(i) in
372     aux (Types.cap t p.na) (Some (num arity p.nfv) :: bindings)
373     (arity + (List.length p.nfv)) (i+1);
374     aux (Types.diff t p.na) (None :: bindings) arity (i+1)
375     in
376     aux t [] 0 0;
377     let res = { id = !cur_id;
378     t = t;
379     pl = pl;
380     interface = Array.of_list !res;
381     actions = None } in
382     incr cur_id;
383     dispatchers := DispMap.add (t,pl) res !dispatchers;
384     res
385    
386     let flatten pl =
387     let accu = ref [] and idx = ref [] in
388     let aux i x = accu := x :: !accu; idx := i :: !idx in
389     Array.iteri (fun i -> List.iter (aux i)) pl;
390     Array.of_list !idx,
391     Array.of_list !accu
392    
393     let collect f pl =
394     let accu = ref [] in
395     let aux (res,x) = try accu := (f x) :: !accu with Exit -> () in
396     Array.iter (List.iter aux) pl;
397     SortedList.from_list (!accu)
398    
399    
400     let rec find_uniq f = function
401     | [] -> None
402     | (res,x) :: rem -> if (f x) then Some res else find_uniq f rem
403    
404     let compare_masks a1 a2 =
405     try
406     for i = 0 to Array.length a1 - 1 do
407     match a1.(i),a2.(i) with
408     | None,Some _| Some _, None -> raise Exit
409     | _ -> ()
410     done;
411     true
412     with Exit -> false
413    
414     let find_code (d : dispatcher) a =
415     let rec aux i =
416     if i = Array.length d.interface
417     then raise Not_found
418     else
419     match d.interface.(i) with
420     | (_,_,m) when compare_masks m a -> i
421     | _ -> aux (i + 1) in
422     aux 0
423    
424     let conv_source_basic = function
425     | (`Catch | `Const _) as x -> x
426     | _ -> assert false
427    
428     let create_result f pl =
429     let res = ref [] in
430     Array.iter
431     (function
432     | Some b -> List.iter (fun x -> res := f x :: !res) b
433     | None -> ()
434     ) pl;
435     List.rev !res
436    
437     let filter f = Array.map (find_uniq f)
438    
439     let dispatch_basic d : (Types.descr * result) list =
440     let pl = Array.map (fun p -> p.nbasic) d.pl in
441     let tests = collect (fun x -> x) pl in
442     let t = Types.cap any_basic d.t in
443     let accu = ref [] in
444     let rec aux t l =
445     if Types.non_empty t
446     then match l with
447     | [] ->
448     let pl = filter (Types.subtype t) pl in
449     let code = find_code d pl in
450     let res = create_result (fun (v,s) -> conv_source_basic s) pl in
451     accu := (t, (code,res)) :: !accu
452     | ty :: rem -> aux (Types.cap t ty) rem; aux (Types.diff t ty) rem
453     in
454     aux t tests;
455     !accu
456    
457    
458     let get_tests pl f t d =
459     let accu = ref [] in
460     let unselect = Array.create (Array.length pl) [] in
461     let aux i x =
462     let yes, no = f x in
463     List.iter (fun (p,info) ->
464     let p = normal (restrict t p) in
465     accu := (p,[i, info]) :: !accu
466     ) yes;
467     unselect.(i) <- no @ unselect.(i) in
468     Array.iteri (fun i -> List.iter (aux i)) pl;
469     let sorted = Array.of_list (SortedMap.from_list SortedList.cup !accu) in
470     let infos = Array.map snd sorted in
471     let disp = dispatcher t (Array.map fst sorted) in
472     let result (t,arity,m) =
473     let selected = Array.create (Array.length pl) [] in
474     let add r (i,inf) = selected.(i) <- (r,inf) :: selected.(i) in
475     Array.iteri
476     (fun j -> function Some r -> List.iter (add r) infos.(j) | None -> ())
477     m;
478     d t selected unselect
479     in
480     let res = Array.map result disp.interface in
481     (disp,res)
482    
483    
484     let conv_source_prod left right (v,s) = match s with
485     | (`Catch | `Const _) as x -> x
486     | `Left ->
487     (*
488     Printf.eprintf "Left %s\n" v;
489     List.iter (fun (v,i) -> Printf.eprintf " LEFT(%s => %i)\n" v i) left;
490     List.iter (fun (v,i) -> Printf.eprintf " RIGHT(%s => %i)\n" v i) right;
491     flush stderr;
492     *)
493     `Left (List.assoc v left)
494     | `Right -> `Right (List.assoc v right)
495     | `Recompose -> `Recompose (List.assoc v left, List.assoc v right)
496     | _ -> assert false
497    
498     let rec dispatch_prod disp : (result dispatch dispatch) =
499     (*
500     Printf.eprintf "dispatch_prod %i: " disp.id;
501     Array.iteri (fun i p ->
502     Printf.eprintf "(%i:" i;
503     List.iter (fun v -> Printf.eprintf "%s" v) p.nfv;
504     Printf.eprintf ")";
505     ) disp.pl;
506     Printf.eprintf "\n";
507     flush stderr;
508     *)
509     let pl = Array.map (fun p -> p.nprod) disp.pl in
510     let t = Types.Product.get disp.t in
511     get_tests pl
512     (fun (res,(p,q)) -> [p, (res,q)], [])
513     (Types.Product.pi1 t)
514     (dispatch_prod1 disp t)
515     and dispatch_prod1 disp t t1 pl _ =
516     let t = Types.Product.restrict_1 t t1 in
517     get_tests pl
518     (fun (ret1, (res,q)) -> [q, (ret1,res)], [] )
519     (Types.Product.pi2 t)
520     (dispatch_prod2 disp t)
521     and dispatch_prod2 disp t t2 pl _ =
522     let aux_final = function
523     | [] -> None
524     | [(ret2, (ret1, res))] ->
525     Some (List.map (conv_source_prod ret1 ret2) res)
526     | _ -> assert false in
527     let final = Array.map aux_final pl in
528     let code = find_code disp final in
529     let ret = create_result (fun s -> s) final in
530     (code,ret)
531    
532    
533     let dummy_label = Types.label ""
534    
535     let collect_first_label pl =
536     let f = ref true and m = ref dummy_label in
537     let aux = function
538     | (res, _, `Label (l, _, _)) ->
539     if (!f) then (f := false; m := l) else if (l < !m) then m:= l;
540     | _ -> () in
541     Array.iter (List.iter aux) pl;
542     if !f then None else Some !m
543    
544     let map_record f =
545     let rec aux = function
546     | [] -> []
547     | h::t -> (match f h with (_,_,`Fail) -> aux t | x -> x :: (aux t)) in
548     Array.map aux
549    
550     let label_found l =
551     map_record
552     (function
553     | (res, catch, `Label (l1, pr, _)) when l1 = l ->
554     (res, catch, `Dispatch pr)
555     | x -> x)
556    
557     let label_not_found l =
558     map_record
559     (function
560     | (res, catch, `Label (l1, _, ab)) when l1 = l -> (res, catch, ab)
561     | x -> x)
562    
563     let conv_source_record catch (v,s) = match s with
564     | (`Catch | `Const _) as x -> x
565     | `Field l -> `Field (l, List.assoc v (List.assoc l catch))
566     | _ -> assert false
567    
568     let rec dispatch_record disp : record option =
569     let prep p = List.map (fun (res,r) -> (res,[],r)) p.nrecord in
570     let pl0 = Array.map prep disp.pl in
571     let t = Types.Record.get disp.t in
572     dispatch_record_opt disp t pl0
573     and dispatch_record_opt disp t pl =
574     if Types.Record.is_empty t then None
575     else Some (dispatch_record_label disp t pl)
576     and dispatch_record_label disp t pl =
577     match collect_first_label pl with
578     | None ->
579     let aux_final = function
580     | [(res, catch, `Success)] ->
581     Some (List.map (conv_source_record catch) res)
582     | [] -> None
583     | _ -> assert false in
584     let final = Array.map aux_final pl in
585     let code = find_code disp final in
586     let ret = create_result (fun s -> s) final in
587     `Result (code,ret)
588     | Some l ->
589     let present =
590     let pl = label_found l pl in
591     let t = Types.Record.restrict_label_present t l in
592     get_tests pl
593     (function
594     | (res,catch, `Dispatch d) ->
595     List.map (fun (p, r) -> p, (res, catch, r)) d, []
596     | x -> [],[x])
597     (Types.Record.project_field t l)
598     (dispatch_record_field l disp t)
599     in
600     let absent =
601     let pl = label_not_found l pl in
602     let t = Types.Record.restrict_label_absent t l in
603     dispatch_record_opt disp t pl
604     in
605     `Label (l, present, absent)
606     and dispatch_record_field l disp t tfield pl others =
607     let t = Types.Record.restrict_field t l tfield in
608     let aux (ret, (res, catch, rem)) = (res, (l,ret) :: catch, rem) in
609     let pl = Array.map (List.map aux) pl in
610     Array.iteri (fun i o -> pl.(i) <- pl.(i) @ o) others;
611     dispatch_record_label disp t pl
612    
613    
614     let actions disp =
615     match disp.actions with
616     | Some a -> a
617     | None ->
618     let a = {
619     basic = dispatch_basic disp;
620     prod = dispatch_prod disp;
621     record = dispatch_record disp;
622     } in
623     disp.actions <- Some a;
624     a
625    
626     let to_print = ref []
627     let printed = ref []
628    
629     let queue d =
630     if not (List.mem d.id !printed) then (
631     printed := d.id :: !printed;
632     to_print := d :: !to_print
633     )
634    
635     let print_actions ppf actions =
636     let print_source ppf = function
637     | `Catch -> Format.fprintf ppf "v"
638     | `Const c -> Types.Print.print_const ppf c
639     | `Left i -> Format.fprintf ppf "l%i" i
640     | `Right j -> Format.fprintf ppf "r%i" j
641     | `Recompose (i,j) -> Format.fprintf ppf "(l%i,r%i)" i j
642     | `Field (l,i) -> Format.fprintf ppf "%s%i" (Types.label_name l) i
643     in
644     let rec print_result ppf = function
645     | [] -> ()
646     | [s] -> print_source ppf s
647     | s::rem -> Format.fprintf ppf "%a," print_source s; print_result ppf rem
648     in
649     let print_ret ppf (code,ret) =
650     Format.fprintf ppf "$%i(%a)" code print_result ret in
651     let print_lhs ppf (code,prefix,d) =
652     let arity = match d.interface.(code) with (_,a,_) -> a in
653     Format.fprintf ppf "$%i(" code;
654     for i = 0 to arity - 1 do
655     if i > 0 then Format.fprintf ppf ",";
656     Format.fprintf ppf "%s%i" prefix i;
657     done;
658     Format.fprintf ppf ")" in
659     let print_basic (t,ret) =
660     Format.fprintf ppf " | %a ->%a@\n"
661     Types.Print.print_descr t
662     print_ret ret
663     in
664     let print_prod2 (d,rem) =
665     queue d;
666     Format.fprintf ppf " match v2 with disp_%i@\n" d.id;
667     Array.iteri
668     (fun code r ->
669     Format.fprintf ppf " | %a -> %a\n"
670     print_lhs (code, "r", d)
671     print_ret r;
672     )
673     rem
674     in
675     let print_prod (d,rem) =
676     if Array.length rem > 0 then (
677     queue d;
678     Format.fprintf ppf " | (v1,v2) -> @\n";
679     Format.fprintf ppf " match v1 with disp_%i@\n" d.id;
680     Array.iteri
681     (fun code d2 ->
682     Format.fprintf ppf " | %a -> @\n"
683     print_lhs (code, "l", d);
684     print_prod2 d2;
685     )
686     rem
687     )
688     in
689     let rec print_record_opt ppf = function
690     | None -> ()
691     | Some r ->
692     Format.fprintf ppf " | Record -> @\n";
693     Format.fprintf ppf " @[%a@]@\n" print_record r
694     and print_record ppf = function
695     | `Result r -> print_ret ppf r
696     | `Label (l, (d,present), absent) ->
697     let l = Types.label_name l in
698     queue d;
699     Format.fprintf ppf " check label %s:@\n" l;
700     Format.fprintf ppf " Present => match with disp_%i@\n" d.id;
701     Array.iteri
702     (fun code r ->
703     Format.fprintf ppf " | %a -> @\n"
704     print_lhs (code, l, d);
705     Format.fprintf ppf " @[%a@]@\n"
706     print_record r
707     ) present;
708     match absent with
709     | Some r ->
710     Format.fprintf ppf " Absent => @[%a@]@\n"
711     print_record r
712     | None -> ()
713     in
714    
715     List.iter print_basic actions.basic;
716     print_prod actions.prod;
717     print_record_opt ppf actions.record
718    
719     let rec print_dispatchers ppf =
720     match !to_print with
721     | [] -> ()
722     | d :: rem ->
723     to_print := rem;
724     Format.fprintf ppf "Dispatcher %i accepts [%a]@\n"
725     d.id Types.Print.print_descr d.t;
726     (*
727     Array.iteri
728     (fun code (t, arity, m) ->
729     Format.fprintf ppf " $%i(arity=%i) accepts [%a]"
730     code arity
731     Types.Print.print_descr t;
732     Array.iter
733     (function
734     | None -> Format.fprintf ppf " None"
735     | Some b ->
736     Format.fprintf ppf " Some(";
737     List.iter
738     (fun (v,i) -> Format.fprintf ppf "%s=>%i;" v i)
739     b;
740     Format.fprintf ppf ")"
741     ) m;
742     Format.fprintf ppf "@\n";
743     )
744     d.interface;
745     *)
746     Format.fprintf ppf "disp_%i = function@\n" d.id;
747     print_actions ppf (actions d);
748     print_dispatchers ppf
749    
750     let show ppf t pl =
751     let disp = dispatcher t pl in
752     queue disp;
753     print_dispatchers ppf
754    
755     end
756    
757    
758     (***************************************************************
759    
760    
761 abate 1 let collect f pp =
762     let aux accu (res,x) = (f x) :: accu in
763     SortedList.from_list (List.fold_left (List.fold_left aux) [] pp)
764    
765     let rec map_map f = function
766     | [] -> []
767     | x::l ->
768     try let y = f x in y::(map_map f l)
769     with Not_found -> map_map f l
770    
771     let get_option = function [x] -> Some x | [] -> None | _ -> assert false
772     let extract_unique f l = get_option (map_map f l)
773     (* Could optimize to extract directly the first (and single) *)
774    
775 abate 42 module Dispatch = struct
776     type t = {
777     id : int;
778     fv : fv list;
779     masks : (mask * (int * int * (capture, int) sm option array)) list;
780     basic : (Types.descr * (result option list)) list;
781     prod : prod;
782     record: record option;
783    
784     mutable basic' : (Types.descr * result') list option;
785     mutable prod' : result' disp' disp' option
786     }
787     and prod = prod_result disp disp
788     and prod_result = (result * (int * int)) option list
789    
790     and record =
791     [ `Label of Types.label * record disp * record option
792     | `Result of record_result ]
793     and record_result = (result * (Types.label * int) list) option list
794    
795     and mask = bool list
796     and 'a disp = (Types.descr * nf SortedList.t) * (mask * 'a) list
797     and 'a disp' = t * (int * 'a) list
798    
799     and result' = int * source' list
800     and source' =
801     [ `Catch | `Const of Types.const
802     | `Left of int | `Right of int | `Recompose of int * int
803     | `Field of Types.label * int
804     ]
805     end
806    
807    
808    
809 abate 1 (* Basic (and arrow) types *)
810    
811     let filter_basic ty =
812     let aux (k,t) = if Types.subtype ty t then k else raise Not_found in
813     List.map (extract_unique aux)
814    
815     let dispatch_basic t pl =
816     let rec aux pl accu t l =
817     if Types.is_empty t then accu
818     else match l with
819     | [] ->
820     let pl = filter_basic t pl in
821     (t, pl) :: accu
822     | ty :: rem ->
823     let accu = aux pl accu (Types.cap t ty) rem in
824     let accu = aux pl accu (Types.diff t ty) rem in
825     accu
826     in
827 abate 39 let pl = List.map (fun p -> p.nbasic) pl in
828 abate 1 let tests = collect (fun x -> x) pl in
829     let t = Types.cap any_basic t in
830     aux pl [] t tests
831    
832     (* Product types *)
833    
834     let filter_prod1 success =
835     let aux (res,(p,q)) = (res,(List.assoc p success,q)) in
836     List.map (map_map aux)
837    
838     let filter_prod2 success =
839     let aux (res,(i,q)) = (res,(i,List.assoc q success)) in
840     List.map (extract_unique aux)
841    
842     let rec dispatch_prod t pl =
843 abate 39 let pl = List.map (fun p -> p.nprod) pl in
844 abate 1 let tests = collect (fun (p,_) -> p) pl in
845     let t = Types.Product.get t in
846     let disp = aux_prod1 t pl [] [] [] 0 tests in
847     let pi1 = Types.Product.pi1 t in
848     ((pi1,tests),disp)
849    
850     and aux_prod2 t pl accu mask success j tests =
851     if Types.is_empty t then accu
852     else match tests with
853     | [] ->
854     let pl = filter_prod2 success pl in
855     (List.rev mask, pl) :: accu
856     | p :: rem ->
857     let accu =
858     let t = Types.cap t p.a in
859     aux_prod2 t pl accu (true::mask) ((p,j)::success) (j+1) rem in
860     let accu =
861     let t = Types.diff t p.a in
862     aux_prod2 t pl accu (false::mask) success (j+1) rem in
863     accu
864    
865     and aux_prod1 t pl accu mask success i tests =
866     if t = [] then accu
867     else match tests with
868     | [] ->
869     let pl = filter_prod1 success pl in
870     let t = Types.Product.pi2 t in
871     let tests = collect (fun (_,q)-> q) pl in
872     let disp = aux_prod2 t pl [] [] [] 0 tests in
873     let mask = List.rev mask in
874 abate 42 (mask, ((t,tests), disp)) :: accu
875 abate 1 | p :: rem ->
876     let accu =
877     let t = Types.Product.restrict_1 t p.a in
878     aux_prod1 t pl accu (true::mask) ((p,i)::success) (i+1) rem in
879     let accu =
880     let t = Types.Product.restrict_1 t (Types.neg p.a) in
881     aux_prod1 t pl accu (false::mask) success (i+1) rem in
882     accu
883    
884     (* Record types *)
885    
886    
887     let map_record f =
888     let rec aux = function
889     | [] -> []
890     | h::t -> (match f h with (_,_,`Fail) -> aux t | x -> x :: (aux t)) in
891     List.map aux
892    
893     let label_found l =
894     map_record
895     (function
896     | (res, catch, `Label (l1, pr, _)) when l1 = l ->
897     (res, catch, `Dispatch pr)
898     | x -> x)
899    
900     let label_disp l success =
901     map_record
902     (function
903     | (res, catch, `Dispatch disp) ->
904     let aux (p,rem) = (List.assoc p success, rem) in
905     (match extract_unique aux disp with
906     | None -> (res, catch, `Fail)
907     | Some (i,rem) -> (res, (l, i)::catch, rem))
908     | x -> x)
909    
910     let label_not_found l =
911     map_record
912     (function
913     | (res, catch, `Label (l1, _, ab)) when l1 = l -> (res, catch, ab)
914     | x -> x)
915    
916    
917     let dummy_label = Types.label ""
918    
919     let collect_first_label pp =
920     let f = ref true and m = ref dummy_label in
921     let aux = function
922     | (_, _, `Label (l, _, _)) ->
923     if (!f) then (f := false; m := l) else if (l < !m) then m:= l;
924     | _ -> () in
925     List.iter (List.iter aux) pp;
926     if !f then None else Some !m
927    
928     let collect_record pp =
929     let aux accu = function
930     | (res,catch,`Dispatch disp) ->
931     List.fold_left (fun accu (p,_) -> p :: accu) accu disp
932     | _ -> accu in
933     SortedList.from_list (List.fold_left (List.fold_left aux) [] pp)
934    
935     let final_record =
936     let aux = function
937     | [(res, catch, `Success)] -> Some (res, catch)
938     | [] -> None
939     | _ -> assert false in
940     List.map aux
941    
942     (* combiner les restrict field, ... *)
943     let rec dispatch_record t pl =
944 abate 39 let pl = List.map
945     (fun p -> List.map (fun (res,r) -> (res,[],r)) p.nrecord
946     ) pl in
947 abate 1 let t = Types.Record.get t in
948 abate 39 if Types.Record.is_empty t then None else Some (aux_record1 t pl)
949 abate 1
950     and aux_record1 t pl =
951     match collect_first_label pl with
952     | None -> `Result (final_record pl)
953     | Some l ->
954     let (disp,pr) =
955     let pl = label_found l pl in
956     let tests = collect_record pl in
957     let t = Types.Record.restrict_label_present t l in
958     let disp = aux_record2 t pl l [] [] [] 0 tests in
959     ((Types.Record.project_field t l, tests),disp)
960     in
961     let ab =
962     let pl = label_not_found l pl in
963     let t = Types.Record.restrict_label_absent t l in
964     if Types.Record.is_empty t then None
965     else Some (aux_record1 t pl)
966     in
967 abate 42 `Label (l, (disp, pr), ab)
968 abate 1
969     and aux_record2 t pl l accu mask success i tests =
970     if Types.Record.is_empty t then accu
971     else match tests with
972     | [] ->
973     let pl = label_disp l success pl in
974     let disp = aux_record1 t pl in
975     (List.rev mask, disp) :: accu
976     | p :: rem ->
977     let accu =
978     let t = Types.Record.restrict_field t l p.a in
979     aux_record2 t pl l accu (true::mask) ((p,i)::success) (i+1) rem in
980     let accu =
981     let t = Types.Record.restrict_field t l (Types.neg p.a) in
982     aux_record2 t pl l accu (false::mask) success (i+1) rem in
983     accu
984 abate 39
985 abate 1 let mask l = List.map (function None -> false | Some _ -> true) l
986    
987 abate 42 module D = Map.Make(
988     struct
989     type t = Types.descr * normal list
990     let compare = compare
991     end
992     )
993 abate 1
994 abate 42 let dispatchers = ref D.empty
995     let id = ref 0
996 abate 1
997 abate 42 let rec dispatch (t : Types.descr) (pl : normal list) =
998     try D.find (t,pl) !dispatchers
999     with Not_found ->
1000     let basic = dispatch_basic t pl
1001     and prod = dispatch_prod t pl
1002     and record = dispatch_record t pl in
1003 abate 1
1004 abate 42 let alloc mask =
1005     let arity = ref 0 in
1006     let rec aux pl mask =
1007     match (pl,mask) with
1008     | ([],[]) -> []
1009     | (p :: pl, true :: mask) ->
1010     let l =
1011     List.map (fun v -> incr arity; (v,!arity-1)) p.nfv in
1012     Some l :: aux pl mask
1013     | (_ :: pl, false :: mask) -> None :: aux pl mask
1014     | _ -> assert false
1015     in
1016     let r = aux pl mask in
1017     !arity, Array.of_list r
1018     in
1019 abate 1
1020 abate 42 let map_disp f ((t,pl),l) =
1021     let pl = List.map (fun p -> normal (restrict t p)) pl in
1022     let d = dispatch t pl in
1023     let r = List.map
1024     (fun (m,r) ->
1025     let (code,_,res) =
1026     try List.assoc m d.Dispatch.masks
1027     with Not_found -> assert false
1028     in
1029     (code, f res r)) l
1030     in
1031     (d, r)
1032     in
1033    
1034     let map_basic masks =
1035     let source : source -> Dispatch.source' = function
1036     | `Catch -> `Catch
1037     | `Const c -> `Const c
1038     | _ -> assert false
1039     in
1040     let result rhs res =
1041     List.fold_left (fun rhs (v,src) -> source src :: rhs) rhs res
1042     in
1043     List.map
1044     (fun (t, ret) ->
1045     let m = mask ret in
1046     let (code,_,_) = try List.assoc m masks with Not_found -> assert false in
1047     let rhs =
1048     List.fold_left
1049     (fun rhs ->
1050     function
1051     | Some x -> result rhs x
1052     | None -> rhs
1053     ) [] ret in
1054     (t,(code,List.rev rhs))
1055     )
1056     in
1057    
1058     let map_prod masks =
1059     let source res1 res2 v : source -> Dispatch.source' = function
1060     | `Catch -> `Catch
1061     | `Const c -> `Const c
1062     | `Left ->
1063     let v1 = try List.assoc v res1 with Not_found -> assert false in
1064     `Left v1
1065     | `Right ->
1066     let v2 = try List.assoc v res2 with Not_found -> assert false in
1067     `Right v2
1068     | `Recompose ->
1069     Printf.eprintf "res1:\n";
1070     List.iter (fun (v,i) -> Printf.eprintf "v=%s;i=%i\n" v i) res1;
1071     Printf.eprintf "res2:\n";
1072     List.iter (fun (v,i) -> Printf.eprintf "v=%s;i=%i\n" v i) res2;
1073     flush stderr;
1074    
1075     let v1 = try List.assoc v res1 with Not_found -> assert false in
1076     let v2 = try List.assoc v res2 with Not_found -> assert false in
1077     `Recompose (v1,v2)
1078     | _ -> assert false
1079     in
1080     let result rhs res1 res2 (res,(i,j)) =
1081     let res1 = match res1.(i) with Some r -> r | None -> assert false in
1082     let res2 = match res2.(j) with Some r -> r | None -> assert false in
1083     List.fold_left
1084     (fun rhs (v,src) -> source res1 res2 v src :: rhs) rhs res
1085     in
1086     map_disp
1087     (fun res1 ->
1088     map_disp
1089     (fun res2 ret ->
1090     let m = mask ret in
1091     let (code,_,_) = List.assoc m masks in
1092     let rhs =
1093     List.fold_left
1094     (fun rhs ->
1095     function
1096     | Some x -> result rhs res1 res2 x
1097     | None -> rhs
1098     ) [] ret in
1099     (code,List.rev rhs)
1100     )
1101     )
1102     in
1103    
1104     let masks =
1105     let accu = ref [] in
1106     let acc r = accu := (mask r) :: !accu in
1107     List.iter (fun (_,r) -> acc r) basic;
1108     List.iter
1109     (fun (_,(_,l)) -> List.iter (fun (_,r) -> acc r) l)
1110     (snd prod);
1111    
1112     let rec it_record_opt : Dispatch.record option -> unit =
1113     function None -> () | Some r -> it_record r
1114     and it_record : Dispatch.record -> unit = function
1115     | `Result r -> acc r
1116     | `Label (_,d,ro) -> it_record_disp d; it_record_opt ro
1117     and it_record_disp (_,l) = List.iter (fun (_,r) -> it_record r) l
1118     in
1119     it_record_opt record;
1120     List.map
1121     (fun (m,i) -> let (arity,r) = alloc m in (m,(i,arity,r)))
1122     (num 0 (SortedList.from_list !accu))
1123     in
1124     incr id;
1125     let disp =
1126     {
1127     Dispatch.id = !id;
1128     Dispatch.fv = List.map (fun p -> p.nfv) pl;
1129     Dispatch.masks = masks;
1130     Dispatch.basic = basic;
1131     Dispatch.prod = prod;
1132     Dispatch.record = record;
1133     Dispatch.basic' = None;
1134     Dispatch.prod' = None;
1135     }
1136     in
1137     dispatchers := D.add (t,pl) disp !dispatchers;
1138     disp.Dispatch.basic' <- Some (map_basic masks basic);
1139     disp.Dispatch.prod' <- Some (map_prod masks prod);
1140     disp
1141    
1142    
1143 abate 1 let to_print = ref []
1144     let memo = ref []
1145     let count = ref 0
1146    
1147     let print_fv ppf fv =
1148     List.iter (fun x -> Format.fprintf ppf "{%s}" x) fv
1149    
1150     let res_basic x = function
1151     | `Catch -> "v"
1152 abate 42 | `Const c ->
1153     Types.Print.print_const Format.str_formatter c;
1154     Format.flush_str_formatter ()
1155 abate 1 | _ -> assert false
1156    
1157     let res_prod i j x res =
1158     match res with
1159     | `Left -> Printf.sprintf "l%i_%s" i x
1160     | `Right -> Printf.sprintf "r%i_%s" j x
1161     | `Recompose -> Printf.sprintf "(l%i_%s,r%i_%s)" i x j x
1162     | _ -> res_basic x res
1163    
1164     let res_record m x res =
1165     match res with
1166     | `Field l ->
1167     Printf.sprintf "f%s_%i_%s" (Types.label_name l) (List.assoc l m) x
1168     | _ -> res_basic x res
1169    
1170    
1171     let print_mask ppf =
1172     List.iter (fun b -> Format.fprintf ppf "%i" (if b then 1 else 0))
1173    
1174     let compute_vars mask pl =
1175     List.fold_right2
1176     (fun (b,i) p acc ->
1177     if b then List.fold_right (fun v acc -> (i,v)::acc) p.v acc
1178     else acc
1179     )
1180     (num 0 mask) pl []
1181    
1182     let compute_result f result =
1183     List.fold_right
1184     (function
1185     | None -> (fun acc -> acc)
1186     | Some x ->
1187     let (r,res) = f x in
1188     List.fold_right (fun (x,s) acc -> res x s :: acc) r
1189     )
1190     result []
1191    
1192     let print_success ppf (mask,pl,pr) =
1193     let vars =
1194     let v = compute_vars mask pl in
1195     if v = [] then "" else
1196     let v = List.map (fun (i,v) -> Format.sprintf "%s%i_%s" pr i v) v in
1197     " (" ^ String.concat ", " v ^ ")" in
1198     Format.fprintf ppf "`S%a%s" print_mask mask vars
1199    
1200     let print_result f ppf result =
1201     let res = compute_result f result in
1202     let res = if res = [] then "" else " (" ^ String.concat ", " res ^ ")" in
1203     Format.fprintf ppf "`S%a%s" print_mask (mask result) res
1204    
1205    
1206 abate 42 let print_source' ppf = function
1207     | `Catch -> Format.fprintf ppf "v"
1208     | `Const c -> Types.Print.print_const ppf c
1209     | `Left i -> Format.fprintf ppf "l%i" i
1210     | `Right j -> Format.fprintf ppf "r%i" j
1211     | `Recompose (i,j) -> Format.fprintf ppf "(l%i,r%i)" i j
1212     | `Field (l,i) -> Format.fprintf ppf "%s%i" (Types.label_name l) i
1213    
1214     let print_result' ppf (code,bindings) =
1215     Format.fprintf ppf "C%i ( " code;
1216     List.iter (print_source' ppf) bindings;
1217     Format.fprintf ppf ")"
1218    
1219     let no t pl =
1220     let pl = List.map (fun p -> normal (restrict t p)) pl in
1221 abate 1 try List.assoc (t,pl) !memo
1222     with Not_found ->
1223     incr count;
1224     let d = dispatch t pl in
1225     memo := ((t,pl),!count) :: !memo;
1226     to_print := (!count, d) :: !to_print;
1227     !count
1228    
1229     let rec show ppf num d =
1230 abate 42 List.iter
1231     (fun (m,(i,arity,res)) ->
1232     Format.fprintf ppf "[%i] arity=%i" i arity;
1233     Array.iter (function
1234     | None -> Format.fprintf ppf " O"
1235     | Some r ->
1236     Format.fprintf ppf " ( ";
1237     List.iter (fun (v,i) ->
1238     Format.fprintf ppf "%s " v)
1239     r;
1240     Format.fprintf ppf ")"
1241     ) res;
1242     Format.fprintf ppf "@\n"
1243     )
1244     d.Dispatch.masks;
1245    
1246 abate 1 Format.fprintf ppf "let matcher_%i v = match v with@\n" num;
1247 abate 42 (match d.Dispatch.prod' with Some p -> show_prod ppf p | None -> assert false);
1248     (match d.Dispatch.basic' with Some p -> show_basic ppf p | None -> assert false);
1249 abate 1 show_record ppf d.Dispatch.record;
1250     Format.fprintf ppf "@\n"
1251    
1252 abate 42 (*
1253 abate 1 and show_basic ppf =
1254     let pr_basic ppf t =
1255     if Types.subtype any_basic t then Format.fprintf ppf "AnyBasic"
1256     else Types.Print.print_descr ppf t in
1257     let case (t,result) =
1258     Format.fprintf ppf " | @[%a@] -> %a@\n"
1259     pr_basic t
1260     (print_result (fun res -> (res,res_basic))) result in
1261     List.iter case
1262    
1263     and show_prod ppf = function
1264     | (_, []) -> ()
1265     | ((t1,pl1), cases1) ->
1266     Format.fprintf ppf
1267     " | (v1,v2) -> match matcher_%i v1 with@\n" (no t1 pl1);
1268     List.iter (case_prod1 ppf pl1) cases1
1269     and case_prod2 ppf pl2 (mask2, result) =
1270     Format.fprintf ppf " | %a -> %a@\n"
1271     print_success (mask2,pl2,"r")
1272     (print_result (fun (res,(i,j)) -> (res,res_prod i j))) result
1273 abate 42 and case_prod1 ppf pl1 (mask1, ((t2,pl2), cases2)) =
1274 abate 1 Format.fprintf ppf " | %a -> match matcher_%i v2 with@\n"
1275     print_success (mask1,pl1,"l")
1276     (no t2 pl2);
1277     List.iter (case_prod2 ppf pl2) cases2
1278 abate 42 *)
1279     and show_basic ppf =
1280     let pr_basic ppf t =
1281     if Types.subtype any_basic t then Format.fprintf ppf "AnyBasic"
1282     else Types.Print.print_descr ppf t in
1283     let case (t,result) =
1284     Format.fprintf ppf " | @[%a@] -> %a@\n"
1285     pr_basic t
1286     print_result' result in
1287     List.iter case
1288 abate 1
1289 abate 42 and show_prod ppf = function
1290     | (_, []) -> ()
1291     | (disp1, cases1) ->
1292     Format.fprintf ppf
1293     " | (v1,v2) -> match matcher_%i v1 with@\n" disp1.Dispatch.id;
1294     List.iter (case_prod1 ppf) cases1
1295     and case_prod2 ppf (code2, result) =
1296     Format.fprintf ppf " | %i -> %a@\n"
1297     code2
1298     print_result' result
1299     and case_prod1 ppf (code1, (disp2,cases2)) =
1300     Format.fprintf ppf " | %i -> match matcher_%i v2 with@\n"
1301     code1
1302     disp2.Dispatch.id;
1303     List.iter (case_prod2 ppf) cases2
1304    
1305 abate 39 and show_record ppf = function
1306     | None -> ()
1307     | Some r ->
1308     Format.fprintf ppf " | Record r -> @\n";
1309     Format.fprintf ppf " @[%a@]@\n" show_record_aux r
1310 abate 1
1311     and show_record_aux ppf = function
1312     | `Result r ->
1313     print_result (fun (res,m) -> (res, res_record m)) ppf r
1314 abate 42 | `Label (l, ((t,pl), cases), ab) ->
1315 abate 1 let ln = Types.label_name l in
1316     Format.fprintf ppf "match matcher_%i r.%s with@\n" (no t pl) ln;
1317     if cases <> [] then
1318     (
1319     let case (mask, rem) =
1320     Format.fprintf ppf " | %a -> @\n @[%a@]@\n"
1321     print_success (mask, pl, Printf.sprintf "f%s_" ln)
1322     show_record_aux rem
1323     in
1324     List.iter case cases;
1325     );
1326     (match ab with
1327     | Some ab ->
1328     Format.fprintf ppf
1329     " | absent -> @\n @[%a@]@\n" show_record_aux ab
1330     | None -> ()
1331     )
1332    
1333    
1334    
1335     let show ppf t pl =
1336     ignore (no t pl);
1337     let rec loop () =
1338     match !to_print with
1339     | (n,d)::r -> to_print:=r; show ppf n d; loop ()
1340     | [] -> ()
1341     in
1342     loop ()
1343    
1344     let get i =
1345     fst (List.find (fun (_,j) -> i = j) !memo)
1346    
1347 abate 42 ***************************************************************)
1348    
1349 abate 1 end
1350    
1351     (*
1352     let test_filter t p =
1353     let t = Syntax.make_type (Syntax.parse t)
1354     and p = Syntax.make_pat (Syntax.parse p) in
1355     let r = Patterns.filter (Types.descr t) p in
1356     List.iter (fun (v,t) ->
1357     let t = Types.normalize t in
1358     Format.fprintf Format.std_formatter "@[%s => %a@]@\n"
1359     v Types.Print.print t) r;;
1360     test_filter "[ (1 2 3?)* ]" "[ (x::(1 2) 3?)* ]";;
1361     *)
1362    
1363     (*
1364 abate 19 let pat s = Patterns.descr (Typer.pat (Parser.From_string.pat s));;
1365     let typ s = Types.descr (Typer.typ (Parser.From_string.pat s));;
1366 abate 1 let f s = Patterns.NF.nf (pat s);;
1367     let show' t l = Patterns.NF.show Format.std_formatter t (List.map f l);;
1368     let show l = show' Types.any l;;
1369     let showt t l = show' (typ t) l;;
1370    
1371 abate 19 showt " [(`A `B `C?)*] " [" [ (((x::`A) `B (x::`C))|_)* ] "];;
1372 abate 42 showt " [(`A)*] " [" [ (x::`A)* ] "];;
1373 abate 19
1374 abate 1 show ["{x=2;y=3}"];;
1375     show [" [((x::1)|(y::2))*] "];;
1376    
1377     let g s =
1378     Patterns.NF.ProdMap.fold (fun k x acc -> (k,x)::acc) (Patterns.NF.left (f s)) [];;
1379    
1380     Patterns.NF.dispatch Types.any [ f "(x,y)" ];;
1381     Patterns.NF.show Format.std_formatter 0 Types.any [ f "(x,y)" ];;
1382     Patterns.NF.show Format.std_formatter 0 Types.any [ f "(0--100,x) | (_,(x:=10))" ];;
1383    
1384     let t = Types.descr (Syntax.make_type (Syntax.parse "[_*]")) in
1385     Patterns.NF.show Format.std_formatter 0 t [ f "[((x::5)|_)*]" ];;
1386    
1387    
1388     Patterns.NF.show Format.std_formatter 0 Types.any [ f "(x,y)"; f "(x,y)"];;
1389     Patterns.NF.show Format.std_formatter 0 Types.any [ f "x"; f "y"];;
1390    
1391     show [ "((x,_),_)"; "((_,x),_)" ];;
1392     showt " [ (1 3?)* ]" [ " [(x::1 3?)*] " ];;
1393     showt " [ (1 3?)* ]" [ " [(1 (x::3)?)*] " ];;
1394     #install_printer Types.Print.print;;
1395     #install_printer Types.Print.print_descr;;
1396     let (t,[p1;p2]) = Patterns.NF.get 5;;
1397     *)
1398 abate 39
1399    
1400 abate 42
1401     (*
1402     #install_printer Types.Print.print_descr;;
1403     let pat s = Patterns.descr (Typer.pat (Parser.From_string.pat s));;
1404     let typ s = Types.descr (Typer.typ (Parser.From_string.pat s));;
1405    
1406     let disp t l =
1407     let l = Array.of_list (
1408     List.map (fun p -> Patterns.NF.normal (Patterns.NF.nf (pat p))) l) in
1409     let t = typ t in
1410     Patterns.NF.Disp.show Format.std_formatter t l;;
1411    
1412     let () = disp "_" ["(x,y,z)"];;
1413    
1414     disp "_" ["`A"];;
1415     disp "_" ["((x,y),z) | ((x := 1) & (y := 2), z)"];;
1416     *)

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