/[svn]/runtime/run_dispatch.ml
ViewVC logotype

Contents of /runtime/run_dispatch.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 956 - (show annotations)
Tue Jul 10 18:13:56 2007 UTC (5 years, 10 months ago) by abate
File size: 10234 byte(s)
[r2004-01-20 16:12:13 by afrisch] Debut des types abstraits

Original author: afrisch
Date: 2004-01-20 16:12:15+00:00
1 (* Running dispatchers *)
2
3 (* Possible simple optimizations:
4 - in make_result_prod, see if buffer can be simply overwritten
5 (precompute this ...)
6 - optimize for Xml elements (don't build the Pair (attr,content))
7 *)
8
9 (*
10 let (<) : int -> int -> bool = (<);;
11 *)
12
13 open Value
14 open Ident
15 open Patterns.Compile
16 open Encodings
17
18
19 let buffer = ref (Array.create 127 Absent)
20 let cursor = ref 0
21
22 let blit a1 ofs1 a2 ofs2 len =
23 for i = 0 to len - 1 do
24 Array.unsafe_set a2 (ofs2 + i) (Array.unsafe_get a1 (ofs1 + i))
25 done
26 (* important to do this in the increasing order ... *)
27
28
29 let ensure_room n =
30 let l = Array.length !buffer in
31 if !cursor + n > l then
32 let buffer' = Array.create (l * 2 + n) Absent in
33 blit !buffer 0 buffer' 0 !cursor;
34 buffer := buffer'
35
36
37 let make_result_prod v1 r1 v2 r2 v (code,r) =
38 let n = Array.length r in
39 if n == 0 then code else (
40 ensure_room n;
41 let buf = !buffer in
42 let c = !cursor in
43 for a = 0 to n - 1 do
44 let x = match Array.unsafe_get r a with
45 | Catch -> v
46 | Const c -> const c
47 | Left i -> if (i < 0) then v1 else buf.(r1 + i)
48 | Right j -> if (j < 0) then v2 else buf.(r2 + j)
49 | Recompose (i,j) ->
50 Pair ((if (i < 0) then v1 else buf.(r1 + i)),
51 (if (j < 0) then v2 else buf.(r2 + j)))
52 in
53 buf.(c + a) <- x
54 done;
55 if r1 != c then blit buf c buf r1 n;
56 cursor := r1 + n; (* clean space for GC ? *)
57 code )
58
59 let make_result_basic v (code,r) =
60 let n = Array.length r in
61 if n == 0 then code else (
62 ensure_room n;
63 let buf = !buffer in
64 for a = 0 to n - 1 do
65 let x = match Array.unsafe_get r a with
66 | Catch -> v
67 | Const c -> const c
68 | _ -> assert false
69 in
70 buf.(!cursor) <- x;
71 incr cursor
72 done;
73 code )
74
75
76 let make_result_char ch (code,r) =
77 let n = Array.length r in
78 if n == 0 then code else (
79 ensure_room n;
80 let buf = !buffer in
81 for a = 0 to n - 1 do
82 let x = match Array.unsafe_get r a with
83 | Catch -> Char ch
84 | Const c -> const c
85 | _ -> assert false
86 in
87 buf.(!cursor + a) <- x
88 done;
89 cursor := !cursor + n;
90 code )
91
92 let tail_string_latin1 i j s q =
93 if i + 1 == j then q else String_latin1 (i + 1,j,s,q)
94
95 let make_result_string_latin1 i j s q r1 r2 (code,r) =
96 let n = Array.length r in
97 if n == 0 then code else (
98 ensure_room n;
99 let buf = !buffer in
100 for a = 0 to n - 1 do
101 let x = match Array.unsafe_get r a with
102 | Catch -> String_latin1 (i,j,s,q)
103 | Const c -> const c
104 | Left n -> if (n < 0) then Char (Chars.V.mk_char s.[i]) else buf.(r1 + n)
105 | Right m -> if (m < 0) then tail_string_latin1 i j s q else buf.(r2 + m)
106 | Recompose (n,m) ->
107 Pair ((if (n < 0) then Char (Chars.V.mk_char s.[i]) else buf.(r1 + n)),
108 (if (m < 0) then tail_string_latin1 i j s q else buf.(r2 + m)))
109 in
110 buf.(!cursor + a) <- x
111 done;
112 if r1 != !cursor then blit buf !cursor buf r1 n;
113 cursor := r1 + n;
114 code )
115
116 let tail_string_utf8 i j s q =
117 let i = Utf8.advance s i in
118 if Utf8.equal_index i j then q else String_utf8 (i,j,s,q)
119
120 let make_result_string_utf8 i j s q r1 r2 (code,r) =
121 let n = Array.length r in
122 if n == 0 then code else (
123 ensure_room n;
124 let buf = !buffer in
125 for a = 0 to n - 1 do
126 let x = match Array.unsafe_get r a with
127 | Catch -> String_utf8 (i,j,s,q)
128 | Const c -> const c
129 | Left n -> if (n < 0) then Char (Chars.V.mk_int (Utf8.get s i)) else buf.(r1 + n)
130 | Right m -> if (m < 0) then tail_string_utf8 i j s q else buf.(r2 + m)
131 | Recompose (n,m) ->
132 Pair ((if (n < 0) then Char (Chars.V.mk_int (Utf8.get s i)) else buf.(r1 + n)),
133 (if (m < 0) then tail_string_utf8 i j s q else buf.(r2 + m)))
134 in
135 buf.(!cursor + a) <- x
136 done;
137 if r1 != !cursor then blit buf !cursor buf r1 n;
138 cursor := r1 + n;
139 code )
140
141 let rec run_disp_basic v f = function
142 | [(_,r)] -> make_result_basic v r
143 | (t,r)::rem -> if f t then make_result_basic v r else run_disp_basic v f rem
144 | _ -> assert false
145
146 let rec run_dispatcher d v =
147 (*
148 Format.fprintf Format.std_formatter "Matching (%a) with:@\n" Value.print v;
149 Patterns.Compile.print_dispatcher Format.std_formatter d;
150 *)
151 match actions d with
152 | AIgnore r -> make_result_basic v r
153 | AKind k -> run_disp_kind k v
154
155 and run_disp_kind actions v =
156 match v with
157 | Pair (v1,v2) -> run_disp_prod v v1 v2 actions.prod
158 | Xml (v1,v2,v3) -> run_disp_prod v v1 (Pair (v2,v3)) actions.xml
159 | Record r -> run_disp_record false v (LabelMap.get r) actions.record
160 | String_latin1 (i,j,s,q) -> run_disp_string_latin1 i j s q actions
161 | String_utf8 (i,j,s,q) -> run_disp_string_utf8 i j s q actions
162 | Atom a -> make_result_basic v (Atoms.get_map a actions.atoms)
163 | Char c -> make_result_basic v (Chars.get_map c actions.chars)
164 | Integer i ->
165 run_disp_basic v (fun t -> Types.Int.has_int t i) actions.basic
166 | Abstraction (iface,_)
167 | Abstraction2 (_,iface,_) ->
168 run_disp_basic v (fun t -> Types.Arrow.check_iface iface t)
169 actions.basic
170 | Abstract (abs,_) ->
171 run_disp_basic v (fun t -> Types.Abstract.contains abs (Types.get_abstract t))
172 actions.basic
173 | Absent ->
174 run_disp_basic v (fun t -> Types.Record.has_absent t) actions.basic
175 | Concat (_,_) as v -> run_disp_kind actions (Value.normalize v)
176 | Delayed _ -> assert false
177
178
179 and run_disp_prod v v1 v2 = function
180 | Impossible -> assert false
181 | TailCall d1 -> run_dispatcher d1 v1
182 | Ignore d2 -> run_disp_prod2 v1 !cursor v v2 d2
183 | Dispatch (d1,b1) ->
184 let r1 = !cursor in
185 let code1 = run_dispatcher d1 v1 in
186 run_disp_prod2 v1 r1 v v2 b1.(code1)
187
188 and run_disp_prod2 v1 r1 v v2 = function
189 | Impossible -> assert false
190 | Ignore r -> make_result_prod v1 r1 v2 !cursor v r
191 | TailCall d2 -> run_dispatcher d2 v2
192 | Dispatch (d2,b2) ->
193 let r2 = !cursor in
194 let code2 = run_dispatcher d2 v2 in
195 make_result_prod v1 r1 v2 r2 v b2.(code2)
196
197 and run_disp_record other v fields = function
198 | None -> assert false
199 | Some (RecLabel (l,d)) ->
200 let rec aux other = function
201 | (l1,_) :: rem when l1 < l -> aux true rem
202 | (l1,vl) :: rem when l1 == l ->
203 run_disp_record1 other vl rem d
204 | rem ->
205 run_disp_record1 other Absent rem d
206 in
207 aux other fields
208 | Some (RecNolabel (some,none)) ->
209 let other = other || (fields != []) in
210 let r = if other then some else none in
211 match r with
212 | Some r -> make_result_basic v r
213 | None -> assert false
214
215 and run_disp_record1 other v1 rem = function
216 | Impossible -> assert false
217 | TailCall d1 -> run_dispatcher d1 v1
218 | Ignore d2 -> run_disp_record2 other v1 !cursor rem d2
219 | Dispatch (d1,b1) ->
220 let r1 = !cursor in
221 let code1 = run_dispatcher d1 v1 in
222 run_disp_record2 other v1 r1 rem b1.(code1)
223
224 and run_disp_record2 other v1 r1 rem = function
225 | Impossible -> assert false
226 | Ignore r -> make_result_prod v1 r1 Absent 0 Absent r
227 | TailCall d2 -> run_disp_record_loop other rem d2
228 | Dispatch (d2,b2) ->
229 let r2 = !cursor in
230 let code2 = run_disp_record_loop other rem d2 in
231 make_result_prod v1 r1 Absent r2 Absent b2.(code2)
232
233 and run_disp_record_loop other rem d =
234 match actions d with
235 | AIgnore r -> make_result_basic Absent r
236 | AKind k -> run_disp_record other Absent rem k.record
237
238
239 and run_disp_string_latin1 i j s q actions =
240 if i == j then run_disp_kind actions q
241 else match actions.prod with
242 | Impossible -> assert false
243 | TailCall d1 -> run_disp_string_latin1_char d1 (Chars.V.mk_char s.[i])
244 | Ignore d2 -> run_disp_string_latin1_2 !cursor i j s q d2
245 | Dispatch (d1,b1) ->
246 let r1 = !cursor in
247 let code1 = run_disp_string_latin1_char d1 (Chars.V.mk_char s.[i]) in
248 run_disp_string_latin1_2 r1 i j s q b1.(code1)
249 and run_disp_string_latin1_char d ch =
250 match actions d with
251 | AIgnore r -> make_result_char ch r
252 | AKind k -> make_result_char ch (Chars.get_map ch k.chars)
253 and run_disp_string_latin1_2 r1 i j s q = function
254 | Impossible -> assert false
255 | Ignore r ->
256 make_result_string_latin1 i j s q r1 0 r
257 | TailCall d2 -> run_disp_string_latin1_loop i j s q d2
258 | Dispatch (d2,b2) ->
259 let r2 = !cursor in
260 let code2 = run_disp_string_latin1_loop i j s q d2 in
261 make_result_string_latin1 i j s q r1 r2 b2.(code2)
262 and run_disp_string_latin1_loop i j s q d =
263 match actions d with
264 | AIgnore r -> make_result_basic Absent r
265 | AKind k -> run_disp_string_latin1 (succ i) j s q k
266
267 and run_disp_string_utf8 i j s q actions =
268 if Utf8.equal_index i j then run_disp_kind actions q
269 else match actions.prod with
270 | Impossible -> assert false
271 | TailCall d1 -> run_disp_string_utf8_char d1 (Chars.V.mk_int (Utf8.get s i))
272 | Ignore d2 -> run_disp_string_utf8_2 !cursor i j s q d2
273 | Dispatch (d1,b1) ->
274 let r1 = !cursor in
275 let code1 = run_disp_string_utf8_char d1 (Chars.V.mk_int (Utf8.get s i)) in
276 run_disp_string_utf8_2 r1 i j s q b1.(code1)
277 and run_disp_string_utf8_char d ch =
278 match actions d with
279 | AIgnore r -> make_result_char ch r
280 | AKind k -> make_result_char ch (Chars.get_map ch k.chars)
281 and run_disp_string_utf8_2 r1 i j s q = function
282 | Impossible -> assert false
283 | Ignore r ->
284 make_result_string_utf8 i j s q r1 0 r
285 | TailCall d2 -> run_disp_string_utf8_loop i j s q d2
286 | Dispatch (d2,b2) ->
287 let r2 = !cursor in
288 let code2 = run_disp_string_utf8_loop i j s q d2 in
289 make_result_string_utf8 i j s q r1 r2 b2.(code2)
290 and run_disp_string_utf8_loop i j s q d =
291 match actions d with
292 | AIgnore r -> make_result_basic Absent r
293 | AKind k -> run_disp_string_utf8 (Utf8.advance s i) j s q k
294
295 let run_dispatcher d v =
296 let code = run_dispatcher d v in
297 cursor := 0;
298 (code,!buffer)
299 (* let r = Array.create !cursor Absent in
300 blit !buffer 0 r 0 !cursor;
301 cursor := 0;
302 (code,r) *)
303
304
305
306 (*
307 let rec check_overwrite_aux r i =
308 if i < 0 then true
309 else match r.(i) with
310 | Right j | Recompose (_,j) ->
311 if (j < 0) || (j >=i ) then check_overwrite_aux r (i - 1) else false
312 | _ -> check_overwrite_aux r (i - 1)
313
314
315 let check_overwrite r2 r =
316 (Array.length r2 = Array.length r) && (check_overwrite_aux r (Array.length r - 1))
317
318
319 *)

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