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

Contents of /runtime/run_dispatch.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 248 - (show annotations)
Tue Jul 10 17:19:03 2007 UTC (5 years, 10 months ago) by abate
File size: 7665 byte(s)
[r2003-03-16 13:04:06 by cvscast] Empty log message

Original author: cvscast
Date: 2003-03-16 13:04:06+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 *)
7
8 open Value
9 open Ident
10 open Patterns.Compile
11
12
13 let buffer = ref (Array.create 127 Absent)
14 let cursor = ref 0
15
16 let blit a1 ofs1 a2 ofs2 len =
17 for i = 0 to len - 1 do
18 Array.unsafe_set a2 (ofs2 + i) (Array.unsafe_get a1 (ofs1 + i))
19 done
20 (* important to do this in the increasing order ... *)
21
22
23 let ensure_room n =
24 let l = Array.length !buffer in
25 if !cursor + n > l then
26 let buffer' = Array.create (l * 2 + n) Absent in
27 blit !buffer 0 buffer' 0 !cursor;
28 buffer := buffer'
29
30
31 let make_result_prod v1 r1 v2 r2 v (code,r) =
32 let n = Array.length r in
33 if n = 0 then code else (
34 ensure_room n;
35 let buf = !buffer in
36 let c = !cursor in
37 for a = 0 to n - 1 do
38 let x = match Array.unsafe_get r a with
39 | Catch -> v
40 | Const c -> const c
41 | Left i -> if (i < 0) then v1 else buf.(r1 + i)
42 | Right j -> if (j < 0) then v2 else buf.(r2 + j)
43 | Recompose (i,j) ->
44 Pair ((if (i < 0) then v1 else buf.(r1 + i)),
45 (if (j < 0) then v2 else buf.(r2 + j)))
46 in
47 buf.(c + a) <- x
48 done;
49 if r1 <> c then blit buf c buf r1 n;
50 cursor := r1 + n; (* clean space for GC ? *)
51 code )
52
53 let make_result_basic v (code,r) =
54 let n = Array.length r in
55 if n = 0 then code else (
56 ensure_room n;
57 let buf = !buffer in
58 for a = 0 to n - 1 do
59 let x = match Array.unsafe_get r a with
60 | Catch -> v
61 | Const c -> const c
62 | _ -> assert false
63 in
64 buf.(!cursor + a) <- x
65 done;
66 cursor := !cursor + n;
67 code )
68
69
70 let make_result_char ch (code,r) =
71 let n = Array.length r in
72 if n = 0 then code else (
73 ensure_room n;
74 let buf = !buffer in
75 for a = 0 to n - 1 do
76 let x = match Array.unsafe_get r a with
77 | Catch -> Char ch
78 | Const c -> const c
79 | _ -> assert false
80 in
81 buf.(!cursor + a) <- x
82 done;
83 cursor := !cursor + n;
84 code )
85
86 let tail_string i j s q =
87 if i + 1 = j then q else String (i + 1,j,s,q)
88
89 let make_result_string i j s q r1 r2 (code,r) =
90 let n = Array.length r in
91 if n = 0 then code else (
92 ensure_room n;
93 let buf = !buffer in
94 for a = 0 to n - 1 do
95 let x = match Array.unsafe_get r a with
96 | Catch -> String (i,j,s,q)
97 | Const c -> const c
98 | Left n -> if (n < 0) then Char (Chars.mk_char s.[i]) else buf.(r1 + n)
99 | Right m -> if (m < 0) then tail_string i j s q else buf.(r2 + m)
100 | Recompose (n,m) ->
101 Pair ((if (n < 0) then Char (Chars.mk_char s.[i]) else buf.(r1 + n)),
102 (if (m < 0) then tail_string i j s q else buf.(r2 + m)))
103 in
104 buf.(!cursor + a) <- x
105 done;
106 if r1 <> !cursor then blit buf !cursor buf r1 n;
107 cursor := r1 + n;
108 code )
109
110
111 let rec run_disp_basic v f = function
112 | [(_,r)] -> make_result_basic v r
113 | (t,r)::rem -> if f t then make_result_basic v r else run_disp_basic v f rem
114 | _ -> assert false
115
116 let rec run_dispatcher d v =
117 (*
118 Format.fprintf Format.std_formatter "Matching (%a) with:@\n" Value.print v;
119 Patterns.Compile.print_dispatcher Format.std_formatter d;
120 *)
121 match actions d with
122 | AIgnore r -> make_result_basic v r
123 | AKind k -> run_disp_kind k v
124
125 and run_disp_kind actions v =
126 match v with
127 | Pair (v1,v2) -> run_disp_prod v v1 v2 actions.prod
128 | Xml (v1,v2) -> run_disp_prod v v1 v2 actions.xml
129 | Record r -> run_disp_record false v (LabelMap.get r) actions.record
130 | String (i,j,s,q) -> run_disp_string i j s q actions
131 | Atom a -> make_result_basic v (Atoms.get_map a actions.atoms)
132 | Char c -> make_result_basic v (Chars.get_map c actions.chars)
133 | Integer i ->
134 run_disp_basic v (fun t -> Types.Int.has_int t i) actions.basic
135 | Abstraction (iface,_) ->
136 run_disp_basic v (fun t -> Types.Arrow.check_iface iface t)
137 actions.basic
138 | Absent ->
139 run_disp_basic v (fun t -> Types.Record.has_absent t) actions.basic
140 (* | v ->
141 run_disp_kind actions (normalize v)
142 *)
143
144
145 and run_disp_prod v v1 v2 = function
146 | Impossible -> assert false
147 | TailCall d1 -> run_dispatcher d1 v1
148 | Ignore d2 -> run_disp_prod2 v1 !cursor v v2 d2
149 | Dispatch (d1,b1) ->
150 let r1 = !cursor in
151 let code1 = run_dispatcher d1 v1 in
152 run_disp_prod2 v1 r1 v v2 b1.(code1)
153
154 and run_disp_prod2 v1 r1 v v2 = function
155 | Impossible -> assert false
156 | Ignore r -> make_result_prod v1 r1 v2 !cursor v r
157 | TailCall d2 -> run_dispatcher d2 v2
158 | Dispatch (d2,b2) ->
159 let r2 = !cursor in
160 let code2 = run_dispatcher d2 v2 in
161 make_result_prod v1 r1 v2 r2 v b2.(code2)
162
163 and run_disp_record other v fields = function
164 | None -> assert false
165 | Some (RecLabel (l,d)) ->
166 let rec aux other = function
167 | (l1,_) :: rem when l1 < l -> aux true rem
168 | (l1,vl) :: rem when l1 = l ->
169 run_disp_record1 other vl rem d
170 | rem ->
171 run_disp_record1 other Absent rem d
172 in
173 aux other fields
174 | Some (RecNolabel (some,none)) ->
175 let r = if other then some else none in
176 match r with
177 | Some r -> make_result_basic v r
178 | None -> assert false
179
180 and run_disp_record1 other v1 rem = function
181 | Impossible -> assert false
182 | TailCall d1 -> run_dispatcher d1 v1
183 | Ignore d2 -> run_disp_record2 other v1 !cursor rem d2
184 | Dispatch (d1,b1) ->
185 let r1 = !cursor in
186 let code1 = run_dispatcher d1 v1 in
187 run_disp_record2 other v1 r1 rem b1.(code1)
188
189 and run_disp_record2 other v1 r1 rem = function
190 | Impossible -> assert false
191 | Ignore r -> make_result_prod v1 r1 Absent 0 Absent r
192 | TailCall d2 -> run_disp_record_loop other rem d2
193 | Dispatch (d2,b2) ->
194 let r2 = !cursor in
195 let code2 = run_disp_record_loop other rem d2 in
196 make_result_prod v1 r1 Absent r2 Absent b2.(code2)
197
198 and run_disp_record_loop other rem d =
199 match actions d with
200 | AIgnore r -> make_result_basic Absent r
201 | AKind k -> run_disp_record other Absent rem k.record
202
203
204 and run_disp_string i j s q actions =
205 if i = j then run_disp_kind actions q
206 else match actions.prod with
207 | Impossible -> assert false
208 | TailCall d1 -> run_disp_string_char d1 (Chars.mk_char s.[i])
209 | Ignore d2 -> run_disp_string2 !cursor i j s q d2
210 | Dispatch (d1,b1) ->
211 let r1 = !cursor in
212 let code1 = run_disp_string_char d1 (Chars.mk_char s.[i]) in
213 run_disp_string2 r1 i j s q b1.(code1)
214 and run_disp_string_char d ch =
215 match actions d with
216 | AIgnore r -> make_result_char ch r
217 | AKind k -> make_result_char ch (Chars.get_map ch k.chars)
218 and run_disp_string2 r1 i j s q = function
219 | Impossible -> assert false
220 | Ignore r ->
221 make_result_string i j s q r1 0 r
222 | TailCall d2 -> run_disp_string_loop i j s q d2
223 | Dispatch (d2,b2) ->
224 let r2 = !cursor in
225 let code2 = run_disp_string_loop i j s q d2 in
226 make_result_string i j s q r1 r2 b2.(code2)
227 and run_disp_string_loop i j s q d =
228 match actions d with
229 | AIgnore r -> make_result_basic Absent r
230 | AKind k -> run_disp_string (succ i) j s q k
231
232 let run_dispatcher d v =
233 let code = run_dispatcher d v in
234 (* for unknown reasons, it seems to be faster to copy the interesting prefix... *)
235 (* cursor := 0;
236 (code,!buffer) *)
237 let r = Array.create !cursor Absent in
238 blit !buffer 0 r 0 !cursor;
239 cursor := 0;
240 (code,r)
241
242
243
244 (*
245 let rec check_overwrite_aux r i =
246 if i < 0 then true
247 else match r.(i) with
248 | Right j | Recompose (_,j) ->
249 if (j < 0) || (j >=i ) then check_overwrite_aux r (i - 1) else false
250 | _ -> check_overwrite_aux r (i - 1)
251
252
253 let check_overwrite r2 r =
254 (Array.length r2 = Array.length r) && (check_overwrite_aux r (Array.length r - 1))
255
256
257 *)

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