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

Contents of /typing/typer.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 516 - (hide annotations)
Tue Jul 10 17:40:48 2007 UTC (5 years, 10 months ago) by abate
File size: 36748 byte(s)
[r2003-06-15 21:46:12 by cvscast] - added support for xsd:all term

- bugfix: empty content model now supported

- bugfix: reference to global attributes works zack

Original author: cvscast
Date: 2003-06-15 21:46:12+00:00
1 abate 237 (* TODO:
2 abate 276 - rewrite type-checking of operators to propagate constraint
3 abate 278 - optimize computation of pattern free variables
4     - check whether it is worth using recursive hash-consing internally
5 abate 276 *)
6 abate 237
7 abate 276
8 abate 320 let warning loc msg =
9     Format.fprintf !Location.warning_ppf "Warning %a:@\n%a%s@\n"
10     Location.print_loc loc
11     Location.html_hilight loc
12     msg
13    
14 abate 5 (* I. Transform the abstract syntax of types and patterns into
15     the internal form *)
16    
17     open Location
18     open Ast
19 abate 225 open Ident
20 abate 5
21 abate 140 module S = struct type t = string let compare = compare end
22 abate 225 module TypeEnv = Map.Make(S)
23 abate 140
24 abate 9 exception NonExhaustive of Types.descr
25 abate 421 exception Constraint of Types.descr * Types.descr
26 abate 19 exception ShouldHave of Types.descr * string
27 abate 355 exception ShouldHave2 of Types.descr * string * Types.descr
28 abate 233 exception WrongLabel of Types.descr * label
29 abate 374 exception UnboundId of id
30 abate 421 exception Error of string
31 abate 5
32 abate 9 let raise_loc loc exn = raise (Location (loc,exn))
33 abate 421 let error loc msg = raise_loc loc (Error msg)
34 abate 9
35 abate 501 (* Schema datastructures *)
36 abate 5
37 abate 501 module StringSet = Set.Make (String)
38    
39 abate 508 (* just to remember imported schemas *)
40     let schemas = State.ref "Typer.schemas" StringSet.empty
41    
42 abate 501 let schema_types = State.ref "Typer.schema_types" (Hashtbl.create 51)
43     let schema_elements = State.ref "Typer.schema_elements" (Hashtbl.create 51)
44 abate 508 let schema_attributes = State.ref "Typer.schema_attributes" (Hashtbl.create 51)
45 abate 501
46 abate 278 (* Eliminate Recursion, propagate Sequence Capture Variables *)
47 abate 5
48 abate 278 let rec seq_vars accu = function
49     | Epsilon | Elem _ -> accu
50     | Seq (r1,r2) | Alt (r1,r2) -> seq_vars (seq_vars accu r1) r2
51     | Star r | WeakStar r -> seq_vars accu r
52     | SeqCapture (v,r) -> seq_vars (IdSet.add v accu) r
53 abate 71
54 abate 278 type derecurs_slot = {
55     ploc : Location.loc;
56     pid : int;
57     mutable ploop : bool;
58     mutable pdescr : derecurs option
59     } and derecurs =
60     | PAlias of derecurs_slot
61     | PType of Types.descr
62     | POr of derecurs * derecurs
63     | PAnd of derecurs * derecurs
64     | PDiff of derecurs * derecurs
65     | PTimes of derecurs * derecurs
66     | PXml of derecurs * derecurs
67     | PArrow of derecurs * derecurs
68     | POptional of derecurs
69     | PRecord of bool * derecurs label_map
70     | PCapture of id
71     | PConstant of id * Types.const
72     | PRegexp of derecurs_regexp * derecurs
73     and derecurs_regexp =
74     | PEpsilon
75     | PElem of derecurs
76     | PSeq of derecurs_regexp * derecurs_regexp
77     | PAlt of derecurs_regexp * derecurs_regexp
78     | PStar of derecurs_regexp
79     | PWeakStar of derecurs_regexp
80 abate 71
81 abate 278 let rec hash_derecurs = function
82 abate 426 | PAlias s ->
83     s.pid
84     | PType t ->
85     1 + 17 * (Types.hash_descr t)
86     | POr (p1,p2) ->
87     2 + 17 * (hash_derecurs p1) + 257 * (hash_derecurs p2)
88     | PAnd (p1,p2) ->
89     3 + 17 * (hash_derecurs p1) + 257 * (hash_derecurs p2)
90     | PDiff (p1,p2) ->
91     4 + 17 * (hash_derecurs p1) + 257 * (hash_derecurs p2)
92     | PTimes (p1,p2) ->
93     5 + 17 * (hash_derecurs p1) + 257 * (hash_derecurs p2)
94     | PXml (p1,p2) ->
95     6 + 17 * (hash_derecurs p1) + 257 * (hash_derecurs p2)
96     | PArrow (p1,p2) ->
97     7 + 17 * (hash_derecurs p1) + 257 * (hash_derecurs p2)
98     | POptional p ->
99     8 + 17 * (hash_derecurs p)
100     | PRecord (o,r) ->
101     (if o then 9 else 10) + 17 * (LabelMap.hash hash_derecurs r)
102     | PCapture x ->
103     11 + 17 * (Id.hash x)
104     | PConstant (x,c) ->
105     12 + 17 * (Id.hash x) + 257 * (Types.hash_const c)
106     | PRegexp (p,q) ->
107     13 + 17 * (hash_derecurs_regexp p) + 257 * (hash_derecurs q)
108 abate 278 and hash_derecurs_regexp = function
109 abate 426 | PEpsilon ->
110     1
111     | PElem p ->
112     2 + 17 * (hash_derecurs p)
113     | PSeq (p1,p2) ->
114     3 + 17 * (hash_derecurs_regexp p1) + 257 * (hash_derecurs_regexp p2)
115     | PAlt (p1,p2) ->
116     4 + 17 * (hash_derecurs_regexp p1) + 257 * (hash_derecurs_regexp p2)
117     | PStar p ->
118     5 + 17 * (hash_derecurs_regexp p)
119     | PWeakStar p ->
120     6 + 17 * (hash_derecurs_regexp p)
121 abate 107
122 abate 278 let rec equal_derecurs p1 p2 = (p1 == p2) || match p1,p2 with
123 abate 426 | PAlias s1, PAlias s2 ->
124     s1 == s2
125     | PType t1, PType t2 ->
126     Types.equal_descr t1 t2
127 abate 278 | POr (p1,q1), POr (p2,q2)
128     | PAnd (p1,q1), PAnd (p2,q2)
129     | PDiff (p1,q1), PDiff (p2,q2)
130     | PTimes (p1,q1), PTimes (p2,q2)
131     | PXml (p1,q1), PXml (p2,q2)
132 abate 426 | PArrow (p1,q1), PArrow (p2,q2) ->
133     (equal_derecurs p1 p2) && (equal_derecurs q1 q2)
134     | POptional p1, POptional p2 ->
135     equal_derecurs p1 p2
136     | PRecord (o1,r1), PRecord (o2,r2) ->
137     (o1 == o2) && (LabelMap.equal equal_derecurs r1 r2)
138     | PCapture x1, PCapture x2 ->
139     Id.equal x1 x2
140     | PConstant (x1,c1), PConstant (x2,c2) ->
141     (Id.equal x1 x2) && (Types.equal_const c1 c2)
142     | PRegexp (p1,q1), PRegexp (p2,q2) ->
143     (equal_derecurs_regexp p1 p2) && (equal_derecurs q1 q2)
144 abate 278 | _ -> false
145     and equal_derecurs_regexp r1 r2 = match r1,r2 with
146 abate 426 | PEpsilon, PEpsilon ->
147     true
148     | PElem p1, PElem p2 ->
149     equal_derecurs p1 p2
150 abate 278 | PSeq (p1,q1), PSeq (p2,q2)
151 abate 426 | PAlt (p1,q1), PAlt (p2,q2) ->
152     (equal_derecurs_regexp p1 p2) && (equal_derecurs_regexp q1 q2)
153 abate 278 | PStar p1, PStar p2
154 abate 426 | PWeakStar p1, PWeakStar p2 ->
155     equal_derecurs_regexp p1 p2
156 abate 278 | _ -> false
157 abate 5
158 abate 278 module DerecursTable = Hashtbl.Make(
159     struct
160     type t = derecurs
161     let hash = hash_derecurs
162     let equal = equal_derecurs
163     end
164     )
165 abate 5
166 abate 278 module RE = Hashtbl.Make(
167     struct
168     type t = derecurs_regexp * derecurs
169 abate 426 let hash (p,q) =
170     (hash_derecurs_regexp p) + 17 * (hash_derecurs q)
171     let equal (p1,q1) (p2,q2) =
172     (equal_derecurs_regexp p1 p2) && (equal_derecurs q1 q2)
173 abate 278 end
174     )
175 abate 71
176 abate 278
177     let counter = State.ref "Typer.counter - derecurs" 0
178     let mk_slot loc =
179     incr counter;
180     { ploop = false; ploc = loc; pid = !counter; pdescr = None }
181    
182     let rec derecurs env p = match p.descr with
183     | PatVar v ->
184     (try PAlias (TypeEnv.find v env)
185 abate 426 with Not_found ->
186     raise_loc_generic p.loc ("Undefined type/pattern " ^ v))
187 abate 501 | SchemaVar (kind, schema, item) ->
188     let try_elt () = fst (Hashtbl.find !schema_elements (schema, item)) in
189     let try_typ () = Hashtbl.find !schema_types (schema, item) in
190     let try_att () = Hashtbl.find !schema_attributes (schema, item) in
191     (match kind with
192     | `Element ->
193     (try
194     PType (try_elt ())
195     with Not_found ->
196     failwith (Printf.sprintf
197     "No element named '%s' found in schema '%s'" item schema))
198     | `Type ->
199     (try
200     PType (try_typ ())
201     with Not_found ->
202     failwith (Printf.sprintf
203     "No type named '%s' found in schema '%s'" item schema))
204     | `Attribute ->
205     (try
206     PType (try_att ())
207     with Not_found ->
208     failwith (Printf.sprintf
209     "No attribute named '%s' found in schema '%s'" item schema))
210     | `Any ->
211     PType
212     (try try_elt () with Not_found ->
213     (try try_typ () with Not_found ->
214     (try try_att () with Not_found ->
215     failwith (Printf.sprintf
216     "No item named '%s' found in schema '%s'" item schema)))))
217 abate 278 | Recurs (p,b) -> derecurs (derecurs_def env b) p
218     | Internal t -> PType t
219     | Or (p1,p2) -> POr (derecurs env p1, derecurs env p2)
220     | And (p1,p2) -> PAnd (derecurs env p1, derecurs env p2)
221     | Diff (p1,p2) -> PDiff (derecurs env p1, derecurs env p2)
222     | Prod (p1,p2) -> PTimes (derecurs env p1, derecurs env p2)
223     | XmlT (p1,p2) -> PXml (derecurs env p1, derecurs env p2)
224     | Arrow (p1,p2) -> PArrow (derecurs env p1, derecurs env p2)
225     | Optional p -> POptional (derecurs env p)
226     | Record (o,r) -> PRecord (o, LabelMap.map (derecurs env) r)
227     | Capture x -> PCapture x
228     | Constant (x,c) -> PConstant (x,c)
229     | Regexp (r,q) ->
230 abate 426 let constant_nil t v =
231     PAnd (t, PConstant (v, Types.Atom Sequence.nil_atom)) in
232 abate 278 let vars = seq_vars IdSet.empty r in
233     let q = IdSet.fold constant_nil (derecurs env q) vars in
234     let r = derecurs_regexp (fun p -> p) env r in
235     PRegexp (r, q)
236     and derecurs_regexp vars env = function
237 abate 426 | Epsilon ->
238     PEpsilon
239     | Elem p ->
240     PElem (vars (derecurs env p))
241     | Seq (p1,p2) ->
242     PSeq (derecurs_regexp vars env p1, derecurs_regexp vars env p2)
243     | Alt (p1,p2) ->
244     PAlt (derecurs_regexp vars env p1, derecurs_regexp vars env p2)
245     | Star p ->
246     PStar (derecurs_regexp vars env p)
247     | WeakStar p ->
248     PWeakStar (derecurs_regexp vars env p)
249     | SeqCapture (x,p) ->
250     derecurs_regexp (fun p -> PAnd (vars p, PCapture x)) env p
251 abate 71
252 abate 140
253 abate 278 and derecurs_def env b =
254     let b = List.map (fun (v,p) -> (v,p,mk_slot p.loc)) b in
255     let env = List.fold_left (fun env (v,p,s) -> TypeEnv.add v s env) env b in
256     List.iter (fun (v,p,s) -> s.pdescr <- Some (derecurs env p)) b;
257     env
258 abate 5
259 abate 278 (* Stratification and recursive hash-consing *)
260 abate 5
261 abate 277 type descr =
262     | IType of Types.descr
263     | IOr of descr * descr
264     | IAnd of descr * descr
265     | IDiff of descr * descr
266     | ITimes of slot * slot
267     | IXml of slot * slot
268     | IArrow of slot * slot
269 abate 278 | IOptional of descr
270 abate 277 | IRecord of bool * slot label_map
271     | ICapture of id
272     | IConstant of id * Types.const
273     and slot = {
274     mutable fv : fv option;
275     mutable hash : int option;
276     mutable rank1: int; mutable rank2: int;
277     mutable gen1 : int; mutable gen2: int;
278 abate 278 mutable d : descr option
279 abate 277 }
280    
281     let descr s =
282     match s.d with
283     | Some d -> d
284     | None -> assert false
285    
286     let gen = ref 0
287     let rank = ref 0
288    
289     let rec hash_descr = function
290     | IType x -> Types.hash_descr x
291     | IOr (d1,d2) -> 1 + 17 * (hash_descr d1) + 257 * (hash_descr d2)
292     | IAnd (d1,d2) -> 2 + 17 * (hash_descr d1) + 257 * (hash_descr d2)
293     | IDiff (d1,d2) -> 3 + 17 * (hash_descr d1) + 257 * (hash_descr d2)
294     | IOptional d -> 4 + 17 * (hash_descr d)
295     | ITimes (s1,s2) -> 5 + 17 * (hash_slot s1) + 257 * (hash_slot s2)
296     | IXml (s1,s2) -> 6 + 17 * (hash_slot s1) + 257 * (hash_slot s2)
297     | IArrow (s1,s2) -> 7 + 17 * (hash_slot s1) + 257 * (hash_slot s2)
298     | IRecord (o,r) -> (if o then 8 else 9) + 17 * (LabelMap.hash hash_slot r)
299     | ICapture x -> 10 + 17 * (Id.hash x)
300     | IConstant (x,y) -> 11 + 17 * (Id.hash x) + 257 * (Types.hash_const y)
301     and hash_slot s =
302     if s.gen1 = !gen then 13 * s.rank1
303     else (
304     incr rank;
305     s.rank1 <- !rank; s.gen1 <- !gen;
306     hash_descr (descr s)
307     )
308    
309     let rec equal_descr d1 d2 =
310     match (d1,d2) with
311     | IType x1, IType x2 -> Types.equal_descr x1 x2
312     | IOr (x1,y1), IOr (x2,y2)
313     | IAnd (x1,y1), IAnd (x2,y2)
314     | IDiff (x1,y1), IDiff (x2,y2) -> (equal_descr x1 x2) && (equal_descr y1 y2)
315     | IOptional x1, IOptional x2 -> equal_descr x1 x2
316     | ITimes (x1,y1), ITimes (x2,y2)
317     | IXml (x1,y1), IXml (x2,y2)
318     | IArrow (x1,y1), IArrow (x2,y2) -> (equal_slot x1 x2) && (equal_slot y1 y2)
319 abate 426 | IRecord (o1,r1), IRecord (o2,r2) ->
320     (o1 = o2) && (LabelMap.equal equal_slot r1 r2)
321 abate 277 | ICapture x1, ICapture x2 -> Id.equal x1 x2
322 abate 426 | IConstant (x1,y1), IConstant (x2,y2) ->
323     (Id.equal x1 x2) && (Types.equal_const y1 y2)
324 abate 277 | _ -> false
325     and equal_slot s1 s2 =
326     ((s1.gen1 = !gen) && (s2.gen2 = !gen) && (s1.rank1 = s2.rank2))
327     ||
328     ((s1.gen1 <> !gen) && (s2.gen2 <> !gen) && (
329     incr rank;
330     s1.rank1 <- !rank; s1.gen1 <- !gen;
331     s2.rank2 <- !rank; s2.gen2 <- !gen;
332     equal_descr (descr s1) (descr s2)
333     ))
334    
335     module Arg = struct
336     type t = slot
337    
338     let hash s =
339     match s.hash with
340     | Some h -> h
341     | None ->
342     incr gen; rank := 0;
343     let h = hash_slot s in
344     s.hash <- Some h;
345     h
346    
347 abate 278 let equal s1 s2 =
348     (s1 == s2) ||
349     (incr gen; rank := 0;
350     let e = equal_slot s1 s2 in
351 abate 355 (* if e then Printf.eprintf "Recursive hash-consig: Equal\n"; *)
352 abate 278 e)
353 abate 277 end
354     module SlotTable = Hashtbl.Make(Arg)
355    
356     let rec fv_slot s =
357     match s.fv with
358     | Some x -> x
359     | None ->
360     if s.gen1 = !gen then IdSet.empty
361     else (s.gen1 <- !gen; fv_descr (descr s))
362     and fv_descr = function
363 abate 278 | IType _ -> IdSet.empty
364 abate 277 | IOr (d1,d2)
365     | IAnd (d1,d2)
366     | IDiff (d1,d2) -> IdSet.cup (fv_descr d1) (fv_descr d2)
367     | IOptional d -> fv_descr d
368     | ITimes (s1,s2)
369     | IXml (s1,s2)
370     | IArrow (s1,s2) -> IdSet.cup (fv_slot s1) (fv_slot s2)
371 abate 426 | IRecord (o,r) ->
372     List.fold_left IdSet.cup IdSet.empty (LabelMap.map_to_list fv_slot r)
373 abate 277 | ICapture x | IConstant (x,_) -> IdSet.singleton x
374 abate 278
375 abate 277
376     let compute_fv s =
377     match s.fv with
378     | Some x -> ()
379     | None ->
380     incr gen;
381     let x = fv_slot s in
382     s.fv <- Some x
383    
384 abate 278
385     let todo_fv = ref []
386 abate 277
387     let mk () =
388     let s =
389     { d = None;
390     fv = None;
391     hash = None;
392     rank1 = 0; rank2 = 0;
393     gen1 = 0; gen2 = 0 } in
394 abate 278 todo_fv := s :: !todo_fv;
395 abate 277 s
396 abate 278
397     let flush_fv () =
398     List.iter compute_fv !todo_fv;
399     todo_fv := []
400 abate 277
401 abate 278 let compile_slot_hash = DerecursTable.create 67
402     let compile_hash = DerecursTable.create 67
403    
404 abate 277 let defs = ref []
405 abate 278
406     let rec compile p =
407     try DerecursTable.find compile_hash p
408 abate 277 with Not_found ->
409 abate 278 let c = real_compile p in
410     DerecursTable.replace compile_hash p c;
411     c
412     and real_compile = function
413     | PAlias v ->
414     if v.ploop then
415     raise_loc_generic v.ploc ("Unguarded recursion on type/pattern");
416     v.ploop <- true;
417     let r = match v.pdescr with Some x -> compile x | _ -> assert false in
418     v.ploop <- false;
419     r
420     | PType t -> IType t
421     | POr (t1,t2) -> IOr (compile t1, compile t2)
422     | PAnd (t1,t2) -> IAnd (compile t1, compile t2)
423     | PDiff (t1,t2) -> IDiff (compile t1, compile t2)
424     | PTimes (t1,t2) -> ITimes (compile_slot t1, compile_slot t2)
425     | PXml (t1,t2) -> IXml (compile_slot t1, compile_slot t2)
426     | PArrow (t1,t2) -> IArrow (compile_slot t1, compile_slot t2)
427     | POptional t -> IOptional (compile t)
428     | PRecord (o,r) -> IRecord (o, LabelMap.map compile_slot r)
429     | PConstant (x,v) -> IConstant (x,v)
430     | PCapture x -> ICapture x
431     | PRegexp (r,q) -> compile_regexp r q
432     and compile_regexp r q =
433     let memo = RE.create 17 in
434     let rec aux accu r q =
435     if RE.mem memo (r,q) then accu
436     else (
437     RE.add memo (r,q) ();
438     match r with
439 abate 426 | PEpsilon ->
440     (match q with
441     | PRegexp (r,q) -> aux accu r q
442     | _ -> (compile q) :: accu)
443 abate 278 | PElem p -> ITimes (compile_slot p, compile_slot q) :: accu
444     | PSeq (r1,r2) -> aux accu r1 (PRegexp (r2,q))
445     | PAlt (r1,r2) -> aux (aux accu r1 q) r2 q
446     | PStar r1 -> aux (aux accu r1 (PRegexp (r,q))) PEpsilon q
447     | PWeakStar r1 -> aux (aux accu PEpsilon q) r1 (PRegexp (r,q))
448     )
449     in
450     let accu = aux [] r q in
451     match accu with
452     | [] -> assert false
453     | p::l -> List.fold_left (fun acc p -> IOr (p,acc)) p l
454     and compile_slot p =
455     try DerecursTable.find compile_slot_hash p
456     with Not_found ->
457 abate 277 let s = mk () in
458 abate 278 defs := (s,p) :: !defs;
459     DerecursTable.add compile_slot_hash p s;
460 abate 277 s
461 abate 278
462 abate 277
463     let rec flush_defs () =
464     match !defs with
465     | [] -> ()
466 abate 278 | (s,p)::t -> defs := t; s.d <- Some (compile p); flush_defs ()
467 abate 277
468     let typ_nodes = SlotTable.create 67
469     let pat_nodes = SlotTable.create 67
470    
471     let rec typ = function
472     | IType t -> t
473     | IOr (s1,s2) -> Types.cup (typ s1) (typ s2)
474     | IAnd (s1,s2) -> Types.cap (typ s1) (typ s2)
475     | IDiff (s1,s2) -> Types.diff (typ s1) (typ s2)
476     | ITimes (s1,s2) -> Types.times (typ_node s1) (typ_node s2)
477     | IXml (s1,s2) -> Types.xml (typ_node s1) (typ_node s2)
478     | IArrow (s1,s2) -> Types.arrow (typ_node s1) (typ_node s2)
479     | IOptional s -> Types.Record.or_absent (typ s)
480     | IRecord (o,r) -> Types.record' (o, LabelMap.map typ_node r)
481     | ICapture x | IConstant (x,_) -> assert false
482    
483     and typ_node s : Types.node =
484     try SlotTable.find typ_nodes s
485     with Not_found ->
486     let x = Types.make () in
487     SlotTable.add typ_nodes s x;
488     Types.define x (typ (descr s));
489     x
490    
491     let rec pat d : Patterns.descr =
492     if IdSet.is_empty (fv_descr d)
493     then Patterns.constr (typ d)
494     else pat_aux d
495    
496    
497     and pat_aux = function
498     | IOr (s1,s2) -> Patterns.cup (pat s1) (pat s2)
499     | IAnd (s1,s2) -> Patterns.cap (pat s1) (pat s2)
500     | IDiff (s1,s2) when IdSet.is_empty (fv_descr s2) ->
501     let s2 = Types.neg (typ s2) in
502     Patterns.cap (pat s1) (Patterns.constr s2)
503     | IDiff _ ->
504     raise (Patterns.Error "Difference not allowed in patterns")
505     | ITimes (s1,s2) -> Patterns.times (pat_node s1) (pat_node s2)
506     | IXml (s1,s2) -> Patterns.xml (pat_node s1) (pat_node s2)
507     | IOptional _ ->
508     raise (Patterns.Error "Optional field not allowed in record patterns")
509     | IRecord (o,r) ->
510     let pats = ref [] in
511     let aux l s =
512     if IdSet.is_empty (fv_slot s) then typ_node s
513     else
514     ( pats := Patterns.record l (pat_node s) :: !pats;
515     Types.any_node )
516     in
517     let constr = Types.record' (o,LabelMap.mapi aux r) in
518     List.fold_left Patterns.cap (Patterns.constr constr) !pats
519     (* TODO: can avoid constr when o=true, and all fields have fv *)
520     | ICapture x -> Patterns.capture x
521     | IConstant (x,c) -> Patterns.constant x c
522     | IArrow _ ->
523     raise (Patterns.Error "Arrow not allowed in patterns")
524     | IType _ -> assert false
525    
526     and pat_node s : Patterns.node =
527     try SlotTable.find pat_nodes s
528     with Not_found ->
529     let x = Patterns.make (fv_slot s) in
530     SlotTable.add pat_nodes s x;
531     Patterns.define x (pat (descr s));
532     x
533    
534     let glb = State.ref "Typer.glb_env" TypeEnv.empty
535 abate 431
536 abate 277 let register_global_types b =
537 abate 278 List.iter
538     (fun (v,p) ->
539     if TypeEnv.mem v !glb
540     then raise_loc_generic p.loc ("Multiple definition for type " ^ v)
541     ) b;
542 abate 431 let old_glb = !glb in
543     try
544     glb := derecurs_def !glb b;
545     let b = List.map (fun (v,p) -> (v,p,compile (derecurs !glb p))) b in
546     flush_defs ();
547     flush_fv ();
548     let b =
549     List.map
550     (fun (v,p,s) ->
551     if not (IdSet.is_empty (fv_descr s)) then
552     raise_loc_generic p.loc
553     "Capture variables are not allowed in types";
554     let t = typ s in
555     if (p.loc <> noloc) && (Types.is_empty t) then
556     warning p.loc
557     ("This definition yields an empty type for " ^ v);
558     (v,t)) b in
559     List.iter (fun (v,t) -> Types.Print.register_global v t) b
560     with e ->
561     glb := old_glb;
562     raise e
563 abate 278
564     let dump_global_types ppf =
565     TypeEnv.iter (fun v _ -> Format.fprintf ppf " %s" v) !glb
566 abate 505
567     let do_typ loc r =
568     let s = compile_slot r in
569 abate 277 flush_defs ();
570     flush_fv ();
571     if IdSet.is_empty (fv_slot s) then typ_node s
572 abate 505 else raise_loc_generic loc "Capture variables are not allowed in types"
573    
574     let typ p =
575     do_typ p.loc (derecurs !glb p)
576 abate 277
577     let pat p =
578 abate 278 let s = compile_slot (derecurs !glb p) in
579 abate 277 flush_defs ();
580     flush_fv ();
581     try pat_node s
582     with Patterns.Error e -> raise_loc_generic p.loc e
583     | Location (loc,exn) when loc = noloc -> raise (Location (p.loc, exn))
584 abate 5
585    
586     (* II. Build skeleton *)
587    
588 abate 225 module Fv = IdSet
589 abate 6
590 abate 427 type branch = Branch of Typed.branch * branch list
591 abate 314
592 abate 427 let cur_branch : branch list ref = ref []
593    
594 abate 316 let exp loc fv e =
595 abate 6 fv,
596     { Typed.exp_loc = loc;
597 abate 5 Typed.exp_typ = Types.empty;
598 abate 316 Typed.exp_descr = e;
599 abate 5 }
600 abate 316
601    
602     let rec expr loc = function
603     | LocatedExpr (loc,e) -> expr loc e
604     | Forget (e,t) ->
605     let (fv,e) = expr loc e and t = typ t in
606     exp loc fv (Typed.Forget (e,t))
607     | Var s ->
608     exp loc (Fv.singleton s) (Typed.Var s)
609     | Apply (e1,e2) ->
610     let (fv1,e1) = expr loc e1 and (fv2,e2) = expr loc e2 in
611     exp loc (Fv.cup fv1 fv2) (Typed.Apply (e1,e2))
612     | Abstraction a ->
613     let iface = List.map (fun (t1,t2) -> (typ t1, typ t2))
614     a.fun_iface in
615     let t = List.fold_left
616     (fun accu (t1,t2) -> Types.cap accu (Types.arrow t1 t2))
617     Types.any iface in
618     let iface = List.map
619     (fun (t1,t2) -> (Types.descr t1, Types.descr t2))
620     iface in
621     let (fv0,body) = branches a.fun_body in
622     let fv = match a.fun_name with
623     | None -> fv0
624     | Some f -> Fv.remove f fv0 in
625     let e = Typed.Abstraction
626     { Typed.fun_name = a.fun_name;
627     Typed.fun_iface = iface;
628     Typed.fun_body = body;
629     Typed.fun_typ = t;
630     Typed.fun_fv = fv
631     } in
632     exp loc fv e
633     | Cst c ->
634     exp loc Fv.empty (Typed.Cst c)
635     | Pair (e1,e2) ->
636     let (fv1,e1) = expr loc e1 and (fv2,e2) = expr loc e2 in
637     exp loc (Fv.cup fv1 fv2) (Typed.Pair (e1,e2))
638     | Xml (e1,e2) ->
639     let (fv1,e1) = expr loc e1 and (fv2,e2) = expr loc e2 in
640     exp loc (Fv.cup fv1 fv2) (Typed.Xml (e1,e2))
641     | Dot (e,l) ->
642     let (fv,e) = expr loc e in
643     exp loc fv (Typed.Dot (e,l))
644     | RemoveField (e,l) ->
645     let (fv,e) = expr loc e in
646     exp loc fv (Typed.RemoveField (e,l))
647     | RecordLitt r ->
648     let fv = ref Fv.empty in
649     let r = LabelMap.map
650     (fun e ->
651     let (fv2,e) = expr loc e
652     in fv := Fv.cup !fv fv2; e)
653     r in
654     exp loc !fv (Typed.RecordLitt r)
655     | Op (op,le) ->
656     let (fvs,ltes) = List.split (List.map (expr loc) le) in
657     let fv = List.fold_left Fv.cup Fv.empty fvs in
658 abate 421 (try
659     (match (ltes,Typed.find_op op) with
660     | [e], `Unary op -> exp loc fv (Typed.UnaryOp (op, e))
661     | [e1;e2], `Binary op -> exp loc fv (Typed.BinaryOp (op, e1,e2))
662     | _ -> assert false)
663     with Not_found -> assert false)
664    
665 abate 316 | Match (e,b) ->
666     let (fv1,e) = expr loc e
667     and (fv2,b) = branches b in
668     exp loc (Fv.cup fv1 fv2) (Typed.Match (e, b))
669 abate 421 | Map (e,b) ->
670 abate 316 let (fv1,e) = expr loc e
671     and (fv2,b) = branches b in
672 abate 421 exp loc (Fv.cup fv1 fv2) (Typed.Map (e, b))
673     | Transform (e,b) ->
674     let (fv1,e) = expr loc e
675     and (fv2,b) = branches b in
676     exp loc (Fv.cup fv1 fv2) (Typed.Transform (e, b))
677 abate 331 | Xtrans (e,b) ->
678 abate 316 let (fv1,e) = expr loc e
679     and (fv2,b) = branches b in
680 abate 331 exp loc (Fv.cup fv1 fv2) (Typed.Xtrans (e, b))
681 abate 501 | Validate (e,schema,elt) ->
682     let (fv,e) = expr loc e in
683     exp loc fv (Typed.Validate (e, schema, elt))
684 abate 316 | Try (e,b) ->
685     let (fv1,e) = expr loc e
686     and (fv2,b) = branches b in
687     exp loc (Fv.cup fv1 fv2) (Typed.Try (e, b))
688    
689 abate 5
690 abate 316 and branches b =
691 abate 6 let fv = ref Fv.empty in
692 abate 19 let accept = ref Types.empty in
693 abate 314 let branch (p,e) =
694 abate 427 let cur_br = !cur_branch in
695     cur_branch := [];
696 abate 316 let (fv2,e) = expr noloc e in
697     let br_loc = merge_loc p.loc e.Typed.exp_loc in
698 abate 314 let p = pat p in
699     let fv2 = Fv.diff fv2 (Patterns.fv p) in
700     fv := Fv.cup !fv fv2;
701     accept := Types.cup !accept (Types.descr (Patterns.accept p));
702     let br =
703     {
704     Typed.br_loc = br_loc;
705     Typed.br_used = br_loc = noloc;
706     Typed.br_pat = p;
707     Typed.br_body = e } in
708 abate 427 cur_branch := Branch (br, !cur_branch) :: cur_br;
709 abate 314 br in
710     let b = List.map branch b in
711 abate 19 (!fv,
712     {
713     Typed.br_typ = Types.empty;
714     Typed.br_branches = b;
715 abate 45 Typed.br_accept = !accept;
716     Typed.br_compiled = None;
717 abate 19 }
718     )
719 abate 5
720 abate 122 let expr = expr noloc
721    
722 abate 277 let let_decl p e =
723     let (_,e) = expr e in
724     { Typed.let_pat = pat p;
725 abate 66 Typed.let_body = e;
726     Typed.let_compiled = None }
727    
728     (* III. Type-checks *)
729    
730     type env = Types.descr Env.t
731 abate 6
732     open Typed
733    
734 abate 421 let require loc t s =
735     if not (Types.subtype t s) then raise_loc loc (Constraint (t, s))
736 abate 17
737 abate 421 let check loc t s =
738     require loc t s; t
739 abate 17
740 abate 421 let should_have loc constr s =
741     raise_loc loc (ShouldHave (constr,s))
742    
743     let flatten loc arg constr precise =
744     let constr' = Sequence.star
745     (Sequence.approx (Types.cap Sequence.any constr)) in
746     let sconstr' = Sequence.star constr' in
747     let exact = Types.subtype constr' constr in
748     if exact then
749     let t = arg sconstr' precise in
750     if precise then Sequence.flatten t else constr
751     else
752     let t = arg sconstr' true in
753     Sequence.flatten t
754    
755 abate 19 let rec type_check env e constr precise =
756     let d = type_check' e.exp_loc env e.exp_descr constr precise in
757 abate 421 let d = if precise then d else constr in
758 abate 6 e.exp_typ <- Types.cup e.exp_typ d;
759     d
760    
761 abate 19 and type_check' loc env e constr precise = match e with
762 abate 54 | Forget (e,t) ->
763     let t = Types.descr t in
764     ignore (type_check env e t false);
765 abate 421 check loc t constr
766    
767 abate 19 | Abstraction a ->
768     let t =
769     try Types.Arrow.check_strenghten a.fun_typ constr
770     with Not_found ->
771 abate 421 should_have loc constr
772     "but the interface of the abstraction is not compatible"
773 abate 19 in
774     let env = match a.fun_name with
775     | None -> env
776     | Some f -> Env.add f a.fun_typ env in
777     List.iter
778     (fun (t1,t2) ->
779 abate 374 let acc = a.fun_body.br_accept in
780     if not (Types.subtype t1 acc) then
781     raise_loc loc (NonExhaustive (Types.diff t1 acc));
782 abate 65 ignore (type_check_branches loc env t1 a.fun_body t2 false)
783 abate 19 ) a.fun_iface;
784     t
785 abate 64
786 abate 19 | Match (e,b) ->
787     let t = type_check env e b.br_accept true in
788 abate 65 type_check_branches loc env t b constr precise
789 abate 30
790 abate 64 | Try (e,b) ->
791     let te = type_check env e constr precise in
792 abate 65 let tb = type_check_branches loc env Types.any b constr precise in
793 abate 64 Types.cup te tb
794    
795 abate 110 | Pair (e1,e2) ->
796     type_check_pair loc env e1 e2 constr precise
797 abate 421
798 abate 110 | Xml (e1,e2) ->
799     type_check_pair ~kind:`XML loc env e1 e2 constr precise
800 abate 159
801 abate 29 | RecordLitt r ->
802 abate 421 type_record loc env r constr precise
803 abate 31
804 abate 421 | Map (e,b) ->
805     type_map loc env false e b constr precise
806    
807     | Transform (e,b) ->
808     flatten loc (type_map loc env true e b) constr precise
809    
810 abate 86 | Apply (e1,e2) ->
811     let t1 = type_check env e1 Types.Arrow.any true in
812     let t1 = Types.Arrow.get t1 in
813     let dom = Types.Arrow.domain t1 in
814 abate 110 let res =
815     if Types.Arrow.need_arg t1 then
816     let t2 = type_check env e2 dom true in
817     Types.Arrow.apply t1 t2
818     else
819     (ignore (type_check env e2 dom false); Types.Arrow.apply_noarg t1)
820     in
821 abate 421 check loc res constr
822 abate 19
823 abate 421 | UnaryOp (o,e) ->
824 abate 426 let t = o.un_op_typer loc
825     (type_check env e) constr precise in
826 abate 421 check loc t constr
827    
828     | BinaryOp (o,e1,e2) ->
829 abate 426 let t = o.bin_op_typer loc
830     (type_check env e1)
831     (type_check env e2) constr precise in
832 abate 421 check loc t constr
833    
834     | Var s ->
835     let t =
836     try Env.find s env
837     with Not_found -> raise_loc loc (UnboundId s) in
838     check loc t constr
839    
840     | Cst c ->
841     check loc (Types.constant c) constr
842    
843     | Dot (e,l) ->
844     let t = type_check env e Types.Record.any true in
845     let t =
846     try (Types.Record.project t l)
847     with Not_found -> raise_loc loc (WrongLabel(t,l))
848     in
849     check loc t constr
850    
851     | RemoveField (e,l) ->
852     let t = type_check env e Types.Record.any true in
853     let t = Types.Record.remove_field t l in
854     check loc t constr
855    
856     | Xtrans (e,b) ->
857     let t = type_check env e Sequence.any true in
858     let t =
859     Sequence.map_tree
860     (fun t ->
861     let resid = Types.diff t b.br_accept in
862     let res = type_check_branches loc env t b Sequence.any true in
863     (res,resid)
864     ) t in
865     check loc t constr
866    
867 abate 501 | Validate (e, schema_name, elt_name) ->
868     ignore (type_check env e Types.any false);
869     let t = fst (Hashtbl.find !schema_elements (schema_name, elt_name)) in
870     check loc t constr
871 abate 421
872 abate 110 and type_check_pair ?(kind=`Normal) loc env e1 e2 constr precise =
873 abate 361 let rects = Types.Product.normal ~kind constr in
874 abate 110 if Types.Product.is_empty rects then
875     (match kind with
876 abate 421 | `Normal -> should_have loc constr "but it is a pair"
877     | `XML -> should_have loc constr "but it is an XML element");
878 abate 334 let need_s = Types.Product.need_second rects in
879 abate 355 let t1 = type_check env e1 (Types.Product.pi1 rects) (precise || need_s) in
880     let c2 = Types.Product.constraint_on_2 rects t1 in
881     if Types.is_empty c2 then
882     raise_loc loc (ShouldHave2 (constr,"but the first component has type",t1));
883     let t2 = type_check env e2 c2 precise in
884 abate 334
885 abate 110 if precise then
886 abate 355 match kind with
887     | `Normal -> Types.times (Types.cons t1) (Types.cons t2)
888     | `XML -> Types.xml (Types.cons t1) (Types.cons t2)
889 abate 110 else
890     constr
891    
892 abate 421 and type_record loc env r constr precise =
893     (* try to get rid of precise = true for values of fields *)
894     (* also: the use equivalent of need_second to optimize... *)
895     if not (Types.Record.has_record constr) then
896     should_have loc constr "but it is a record";
897     let (rconstr,res) =
898     List.fold_left
899     (fun (rconstr,res) (l,e) ->
900     (* could compute (split l e) once... *)
901     let pi = Types.Record.project_opt rconstr l in
902     if Types.is_empty pi then
903     (let l = U.to_string (LabelPool.value l) in
904     should_have loc constr
905     (Printf.sprintf "Field %s is not allowed here." l));
906     let t = type_check env e pi true in
907     let rconstr = Types.Record.condition rconstr l t in
908     let res = (l,Types.cons t) :: res in
909     (rconstr,res)
910     ) (constr, []) (LabelMap.get r)
911     in
912     if not (Types.Record.has_empty_record rconstr) then
913     should_have loc constr "More fields should be present";
914     let t =
915     Types.record' (false, LabelMap.from_list (fun _ _ -> assert false) res)
916     in
917     check loc t constr
918 abate 110
919 abate 19
920 abate 65 and type_check_branches loc env targ brs constr precise =
921 abate 374 if Types.is_empty targ then Types.empty
922 abate 9 else (
923     brs.br_typ <- Types.cup brs.br_typ targ;
924 abate 65 branches_aux loc env targ
925 abate 19 (if precise then Types.empty else constr)
926     constr precise brs.br_branches
927 abate 9 )
928 abate 6
929 abate 65 and branches_aux loc env targ tres constr precise = function
930 abate 374 | [] -> tres
931 abate 6 | b :: rem ->
932     let p = b.br_pat in
933     let acc = Types.descr (Patterns.accept p) in
934    
935     let targ' = Types.cap targ acc in
936     if Types.is_empty targ'
937 abate 65 then branches_aux loc env targ tres constr precise rem
938 abate 6 else
939     ( b.br_used <- true;
940     let res = Patterns.filter targ' p in
941     let env' = List.fold_left
942     (fun env (x,t) -> Env.add x (Types.descr t) env)
943     env res in
944 abate 19 let t = type_check env' b.br_body constr precise in
945     let tres = if precise then Types.cup t tres else tres in
946 abate 9 let targ'' = Types.diff targ acc in
947     if (Types.non_empty targ'') then
948 abate 65 branches_aux loc env targ'' tres constr precise rem
949 abate 9 else
950     tres
951 abate 6 )
952 abate 16
953 abate 421 and type_map loc env def e b constr precise =
954     let acc = if def then Sequence.any else Sequence.star b.br_accept in
955     let t = type_check env e acc true in
956    
957     let constr' = Sequence.approx (Types.cap Sequence.any constr) in
958     let exact = Types.subtype (Sequence.star constr') constr in
959     (* Note:
960     - could be more precise by integrating the decomposition
961     of constr inside Sequence.map.
962     *)
963     let res =
964     Sequence.map
965     (fun t ->
966     let res =
967     type_check_branches loc env t b constr' (precise || (not exact)) in
968     if def && not (Types.subtype t b.br_accept)
969     then Types.cup res Sequence.nil_type
970     else res)
971     t in
972     if exact then res else check loc res constr
973    
974 abate 66 and type_let_decl env l =
975     let acc = Types.descr (Patterns.accept l.let_pat) in
976     let t = type_check env l.let_body acc true in
977     let res = Patterns.filter t l.let_pat in
978     List.map (fun (x,t) -> (x, Types.descr t)) res
979    
980     and type_rec_funs env l =
981     let types =
982     List.fold_left
983 abate 431 (fun accu -> function
984     | { exp_descr=Abstraction { fun_typ = t; fun_name = Some f } } ->
985     (f,t) :: accu
986     | _ -> assert false
987     ) [] l
988 abate 66 in
989     let env' = List.fold_left (fun env (x,t) -> Env.add x t env) env types in
990 abate 431 List.iter (fun e -> ignore (type_check env' e Types.any false)) l;
991 abate 66 types
992    
993 abate 427
994     let rec unused_branches b =
995 abate 314 List.iter
996 abate 427 (fun (Branch (br,s)) ->
997     if not br.br_used
998     then warning br.br_loc "This branch is not used"
999     else unused_branches s
1000     )
1001     b
1002 abate 314
1003 abate 427 let report_unused_branches () =
1004     unused_branches !cur_branch;
1005     cur_branch := []
1006    
1007 abate 501 (* Schema stuff from now on ... *)
1008    
1009 abate 508 let debug = true
1010 abate 501
1011     (** convertion from XML Schema types (including global elements and
1012     attributes) to CDuce Types.descr *)
1013     module Schema_converter =
1014     struct
1015    
1016 abate 508 open Printf
1017     open Schema_types
1018 abate 501
1019     (* auxiliary functions *)
1020    
1021     (* build a regexp Elem from a Types.descr *)
1022 abate 505 let mk_re_elt descr = PElem descr
1023 abate 501
1024     (* conversion functions *)
1025    
1026     let cd_type_of_simple_type = function
1027 abate 505 | SBuilt_in name -> PType (Schema_builtin.cd_type_of_builtin name)
1028 abate 501 | SUser_defined (_, _, _, _) -> assert false (* TODO *)
1029    
1030 abate 505 let complex_memo = Hashtbl.create 213
1031    
1032 abate 501 let rec regexp_of_term = function
1033 abate 516 | All [] | Choice [] | Sequence [] -> PEpsilon
1034 abate 501 | Choice (hd :: tl) ->
1035     List.fold_left
1036 abate 505 (fun acc particle -> PAlt (acc, regexp_of_particle particle))
1037 abate 501 (regexp_of_particle hd) tl
1038 abate 516 | All (hd :: tl) | Sequence (hd :: tl) ->
1039 abate 501 List.fold_left
1040 abate 505 (fun acc particle -> PSeq (acc, regexp_of_particle particle))
1041 abate 501 (regexp_of_particle hd) tl
1042     | Elt decl -> mk_re_elt (cd_type_of_elt_decl !decl)
1043    
1044     and regexp_of_content_type = function
1045 abate 505 | CT_empty -> PEpsilon
1046 abate 501 | CT_simple st -> mk_re_elt (cd_type_of_simple_type st)
1047     | CT_model (particle, mixed) ->
1048     assert (not mixed); (* TODO mixed support *)
1049     regexp_of_particle particle
1050    
1051     and regexp_of_particle =
1052     (* given a regexp re and a (non negative) integer n create a regexp
1053     matching exactly n times re *)
1054     let rec repeat_regexp re = function
1055 abate 505 | 0 -> PEpsilon
1056     | n when n > 0 -> PSeq (re, repeat_regexp re (n - 1))
1057 abate 501 | _ -> assert false
1058     in
1059     fun (min, max, term) ->
1060     let term_regexp = regexp_of_term term in
1061     let min_regexp = repeat_regexp term_regexp min in
1062     match max with
1063     | Some max ->
1064     assert (max >= min);
1065     let rec aux acc = function
1066     | 0 -> acc
1067     | n ->
1068     aux
1069 abate 505 (PAlt (PEpsilon, (PSeq (term_regexp, acc))))
1070 abate 501 (n - 1)
1071     in
1072 abate 505 PSeq (min_regexp, aux PEpsilon (max - min))
1073     | None -> PSeq (min_regexp, PStar term_regexp)
1074 abate 501
1075     (** @return a pair composed by a type for the attributes (a record) and a
1076     type for the content model (a sequence) *)
1077     and cd_type_of_complex_type' = function
1078     | CBuilt_in name -> assert false
1079 abate 505 | CUser_defined (id, name, _, _, attr_uses, content) ->
1080     try PAlias (Hashtbl.find complex_memo id)
1081     with Not_found ->
1082     let slot = mk_slot noloc in
1083     Hashtbl.add complex_memo id slot;
1084     let content_re = regexp_of_content_type content in
1085     let content_ast_node = PRegexp (content_re, PType Sequence.nil_type) in
1086     slot.pdescr <- Some
1087     (PTimes (cd_type_of_attr_uses attr_uses, content_ast_node));
1088     PAlias slot
1089    
1090 abate 501
1091 abate 508 (* TODO if constraint is Fixed we can give a more precise CDuce type *)
1092    
1093 abate 501 (** @return a closed record *)
1094     and cd_type_of_attr_uses attr_uses =
1095 abate 505 let fields =
1096     List.map
1097     (fun (required, (name, st, _), _) ->
1098 abate 508 let r = cd_type_of_simple_type st in
1099 abate 505 let r = if required then r else POptional r in
1100     (LabelPool.mk (U.mk name), r)
1101     ) attr_uses in
1102     PRecord (false, LabelMap.from_list_disj fields)
1103 abate 501
1104 abate 508 and cd_type_of_att_decl (name, st, _) =
1105     let r = cd_type_of_simple_type st in
1106     PRecord (false, LabelMap.from_list_disj [(LabelPool.mk (U.mk name), r)])
1107    
1108 abate 501 and cd_type_of_elt_decl (name, typ, _) =
1109 abate 505 let atom_type = PType (Types.atom (Atoms.atom (Atoms.mk (U.mk name)))) in
1110     let content = match !typ with
1111 abate 508 | S st ->
1112     PTimes (PType Types.empty_closed_record, cd_type_of_simple_type st)
1113 abate 505 | C ct -> cd_type_of_complex_type' ct
1114     in
1115     PXml (atom_type, content)
1116 abate 501
1117 abate 505 let typ r = Types.descr (do_typ noloc r)
1118    
1119 abate 501 let cd_type_of_complex_type = function
1120     | CBuilt_in name -> Schema_builtin.cd_type_of_builtin name
1121 abate 505 | ct -> typ (PXml (PType Types.any, cd_type_of_complex_type' ct))
1122 abate 501
1123     let cd_type_of_type_def = function
1124 abate 505 | S st -> typ (cd_type_of_simple_type st)
1125 abate 501 | C ct -> cd_type_of_complex_type ct
1126    
1127 abate 508 let cd_type_of_elt_decl x = typ (cd_type_of_elt_decl x)
1128     let cd_type_of_att_decl x = typ (cd_type_of_att_decl x)
1129 abate 505
1130 abate 501 end
1131    
1132     let get_schema_validator (schema_name, elt_name) =
1133     snd (Hashtbl.find !schema_elements (schema_name, elt_name))
1134    
1135     let register_schema schema_name schema =
1136     if StringSet.mem schema_name !schemas then
1137     failwith ("Redefinition of schema " ^ schema_name)
1138     else begin
1139     schemas := StringSet.add schema_name !schemas;
1140     List.iter (* Schema types -> CDuce types *)
1141     (fun type_def ->
1142     let cd_type = Schema_converter.cd_type_of_type_def type_def in
1143     Hashtbl.add !schema_types
1144     (schema_name, Schema_types.name_of_type_def type_def)
1145     cd_type)
1146     schema.Schema_types.type_defs;
1147 abate 508 List.iter (* Schema attributes -> CDuce types *)
1148     (fun (att_name, _, _) as att_decl ->
1149     let cd_type = Schema_converter.cd_type_of_att_decl att_decl in
1150     Hashtbl.add !schema_attributes (schema_name, att_name) cd_type)
1151     schema.Schema_types.att_decls;
1152 abate 501 List.iter (* Schema elements -> CDuce types * validators *)
1153     (fun elt_decl ->
1154     let cd_type = Schema_converter.cd_type_of_elt_decl elt_decl in
1155     if debug then
1156     (Types.Print.print Format.std_formatter cd_type;
1157     Format.fprintf Format.std_formatter "\n";
1158     Format.pp_print_flush Format.std_formatter ());
1159     let validator = Schema_validator.validator_of_elt_decl elt_decl in
1160     Hashtbl.add !schema_elements
1161     (schema_name, Schema_types.name_of_elt_decl elt_decl)
1162     (cd_type, validator))
1163     schema.Schema_types.elt_decls
1164     end
1165    
1166     (* DEBUGGING ONLY *)
1167    
1168 abate 508 let get_schema_type x = fst (Hashtbl.find !schema_elements x)

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