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

Contents of /runtime/run_dispatch.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 431 - (show annotations)
Tue Jul 10 17:34:25 2007 UTC (5 years, 10 months ago) by abate
File size: 10046 byte(s)
[r2003-05-25 16:53:21 by cvscast] toplevel

Original author: cvscast
Date: 2003-05-25 16:53:22+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 + a) <- x
71 done;
72 cursor := !cursor + n;
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.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.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.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.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 run_disp_basic v (fun t -> Types.Arrow.check_iface iface t)
168 actions.basic
169 | Absent ->
170 run_disp_basic v (fun t -> Types.Record.has_absent t) actions.basic
171 | Delayed _ -> assert false
172
173
174 and run_disp_prod v v1 v2 = function
175 | Impossible -> assert false
176 | TailCall d1 -> run_dispatcher d1 v1
177 | Ignore d2 -> run_disp_prod2 v1 !cursor v v2 d2
178 | Dispatch (d1,b1) ->
179 let r1 = !cursor in
180 let code1 = run_dispatcher d1 v1 in
181 run_disp_prod2 v1 r1 v v2 b1.(code1)
182
183 and run_disp_prod2 v1 r1 v v2 = function
184 | Impossible -> assert false
185 | Ignore r -> make_result_prod v1 r1 v2 !cursor v r
186 | TailCall d2 -> run_dispatcher d2 v2
187 | Dispatch (d2,b2) ->
188 let r2 = !cursor in
189 let code2 = run_dispatcher d2 v2 in
190 make_result_prod v1 r1 v2 r2 v b2.(code2)
191
192 and run_disp_record other v fields = function
193 | None -> assert false
194 | Some (RecLabel (l,d)) ->
195 let rec aux other = function
196 | (l1,_) :: rem when l1 < l -> aux true rem
197 | (l1,vl) :: rem when l1 == l ->
198 run_disp_record1 other vl rem d
199 | rem ->
200 run_disp_record1 other Absent rem d
201 in
202 aux other fields
203 | Some (RecNolabel (some,none)) ->
204 let r = if other then some else none in
205 match r with
206 | Some r -> make_result_basic v r
207 | None -> assert false
208
209 and run_disp_record1 other v1 rem = function
210 | Impossible -> assert false
211 | TailCall d1 -> run_dispatcher d1 v1
212 | Ignore d2 -> run_disp_record2 other v1 !cursor rem d2
213 | Dispatch (d1,b1) ->
214 let r1 = !cursor in
215 let code1 = run_dispatcher d1 v1 in
216 run_disp_record2 other v1 r1 rem b1.(code1)
217
218 and run_disp_record2 other v1 r1 rem = function
219 | Impossible -> assert false
220 | Ignore r -> make_result_prod v1 r1 Absent 0 Absent r
221 | TailCall d2 -> run_disp_record_loop other rem d2
222 | Dispatch (d2,b2) ->
223 let r2 = !cursor in
224 let code2 = run_disp_record_loop other rem d2 in
225 make_result_prod v1 r1 Absent r2 Absent b2.(code2)
226
227 and run_disp_record_loop other rem d =
228 match actions d with
229 | AIgnore r -> make_result_basic Absent r
230 | AKind k -> run_disp_record other Absent rem k.record
231
232
233 and run_disp_string_latin1 i j s q actions =
234 if i == j then run_disp_kind actions q
235 else match actions.prod with
236 | Impossible -> assert false
237 | TailCall d1 -> run_disp_string_latin1_char d1 (Chars.mk_char s.[i])
238 | Ignore d2 -> run_disp_string_latin1_2 !cursor i j s q d2
239 | Dispatch (d1,b1) ->
240 let r1 = !cursor in
241 let code1 = run_disp_string_latin1_char d1 (Chars.mk_char s.[i]) in
242 run_disp_string_latin1_2 r1 i j s q b1.(code1)
243 and run_disp_string_latin1_char d ch =
244 match actions d with
245 | AIgnore r -> make_result_char ch r
246 | AKind k -> make_result_char ch (Chars.get_map ch k.chars)
247 and run_disp_string_latin1_2 r1 i j s q = function
248 | Impossible -> assert false
249 | Ignore r ->
250 make_result_string_latin1 i j s q r1 0 r
251 | TailCall d2 -> run_disp_string_latin1_loop i j s q d2
252 | Dispatch (d2,b2) ->
253 let r2 = !cursor in
254 let code2 = run_disp_string_latin1_loop i j s q d2 in
255 make_result_string_latin1 i j s q r1 r2 b2.(code2)
256 and run_disp_string_latin1_loop i j s q d =
257 match actions d with
258 | AIgnore r -> make_result_basic Absent r
259 | AKind k -> run_disp_string_latin1 (succ i) j s q k
260
261 and run_disp_string_utf8 i j s q actions =
262 if Utf8.equal_index i j then run_disp_kind actions q
263 else match actions.prod with
264 | Impossible -> assert false
265 | TailCall d1 -> run_disp_string_utf8_char d1 (Chars.mk_int (Utf8.get s i))
266 | Ignore d2 -> run_disp_string_utf8_2 !cursor i j s q d2
267 | Dispatch (d1,b1) ->
268 let r1 = !cursor in
269 let code1 = run_disp_string_utf8_char d1 (Chars.mk_int (Utf8.get s i)) in
270 run_disp_string_utf8_2 r1 i j s q b1.(code1)
271 and run_disp_string_utf8_char d ch =
272 match actions d with
273 | AIgnore r -> make_result_char ch r
274 | AKind k -> make_result_char ch (Chars.get_map ch k.chars)
275 and run_disp_string_utf8_2 r1 i j s q = function
276 | Impossible -> assert false
277 | Ignore r ->
278 make_result_string_utf8 i j s q r1 0 r
279 | TailCall d2 -> run_disp_string_utf8_loop i j s q d2
280 | Dispatch (d2,b2) ->
281 let r2 = !cursor in
282 let code2 = run_disp_string_utf8_loop i j s q d2 in
283 make_result_string_utf8 i j s q r1 r2 b2.(code2)
284 and run_disp_string_utf8_loop i j s q d =
285 match actions d with
286 | AIgnore r -> make_result_basic Absent r
287 | AKind k -> run_disp_string_utf8 (Utf8.advance s i) j s q k
288
289 let run_dispatcher d v =
290 let code = run_dispatcher d v in
291 (* for unknown reasons, it seems to be faster to copy the interesting prefix... *)
292 (* cursor := 0;
293 (code,!buffer) *)
294 let r = Array.create !cursor Absent in
295 blit !buffer 0 r 0 !cursor;
296 cursor := 0;
297 (code,r)
298
299
300
301 (*
302 let rec check_overwrite_aux r i =
303 if i < 0 then true
304 else match r.(i) with
305 | Right j | Recompose (_,j) ->
306 if (j < 0) || (j >=i ) then check_overwrite_aux r (i - 1) else false
307 | _ -> check_overwrite_aux r (i - 1)
308
309
310 let check_overwrite r2 r =
311 (Array.length r2 = Array.length r) && (check_overwrite_aux r (Array.length r - 1))
312
313
314 *)

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