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

Contents of /runtime/run_dispatch.ml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 247 - (show annotations)
Tue Jul 10 17:19:00 2007 UTC (5 years, 10 months ago) by abate
File size: 7619 byte(s)
[r2003-03-16 12:52:57 by cvscast] Empty log message

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

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