Mercurial > projects > ldc
comparison druntime/src/compiler/dmd/switch_.d @ 1458:e0b2d67cfe7c
Added druntime (this should be removed once it works).
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 02 Jun 2009 17:43:06 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1456:7b218ec1044f | 1458:e0b2d67cfe7c |
---|---|
1 /** | |
2 * Contains support code for switch blocks using string constants. | |
3 * | |
4 * Copyright: Copyright Digital Mars 2004 - 2009. | |
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>. | |
6 * Authors: Walter Bright, Sean Kelly | |
7 * | |
8 * Copyright Digital Mars 2004 - 2009. | |
9 * Distributed under the Boost Software License, Version 1.0. | |
10 * (See accompanying file LICENSE_1_0.txt or copy at | |
11 * http://www.boost.org/LICENSE_1_0.txt) | |
12 */ | |
13 module rt.switch_; | |
14 | |
15 private import core.stdc.string; | |
16 | |
17 /****************************************************** | |
18 * Support for switch statements switching on strings. | |
19 * Input: | |
20 * table[] sorted array of strings generated by compiler | |
21 * ca string to look up in table | |
22 * Output: | |
23 * result index of match in table[] | |
24 * -1 if not in table | |
25 */ | |
26 | |
27 extern (C): | |
28 | |
29 int _d_switch_string(char[][] table, char[] ca) | |
30 in | |
31 { | |
32 //printf("in _d_switch_string()\n"); | |
33 assert(table.length >= 0); | |
34 assert(ca.length >= 0); | |
35 | |
36 // Make sure table[] is sorted correctly | |
37 int j; | |
38 | |
39 for (j = 1; j < table.length; j++) | |
40 { | |
41 int len1 = table[j - 1].length; | |
42 int len2 = table[j].length; | |
43 | |
44 assert(len1 <= len2); | |
45 if (len1 == len2) | |
46 { | |
47 int ci; | |
48 | |
49 ci = memcmp(table[j - 1].ptr, table[j].ptr, len1); | |
50 assert(ci < 0); // ci==0 means a duplicate | |
51 } | |
52 } | |
53 } | |
54 out (result) | |
55 { | |
56 int i; | |
57 int cj; | |
58 | |
59 //printf("out _d_switch_string()\n"); | |
60 if (result == -1) | |
61 { | |
62 // Not found | |
63 for (i = 0; i < table.length; i++) | |
64 { | |
65 if (table[i].length == ca.length) | |
66 { cj = memcmp(table[i].ptr, ca.ptr, ca.length); | |
67 assert(cj != 0); | |
68 } | |
69 } | |
70 } | |
71 else | |
72 { | |
73 assert(0 <= result && result < table.length); | |
74 for (i = 0; 1; i++) | |
75 { | |
76 assert(i < table.length); | |
77 if (table[i].length == ca.length) | |
78 { | |
79 cj = memcmp(table[i].ptr, ca.ptr, ca.length); | |
80 if (cj == 0) | |
81 { | |
82 assert(i == result); | |
83 break; | |
84 } | |
85 } | |
86 } | |
87 } | |
88 } | |
89 body | |
90 { | |
91 //printf("body _d_switch_string(%.*s)\n", ca); | |
92 int low; | |
93 int high; | |
94 int mid; | |
95 int c; | |
96 char[] pca; | |
97 | |
98 low = 0; | |
99 high = table.length; | |
100 | |
101 version (none) | |
102 { | |
103 // Print table | |
104 printf("ca[] = '%s'\n", cast(char *)ca); | |
105 for (mid = 0; mid < high; mid++) | |
106 { | |
107 pca = table[mid]; | |
108 printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
109 } | |
110 } | |
111 if (high && | |
112 ca.length >= table[0].length && | |
113 ca.length <= table[high - 1].length) | |
114 { | |
115 // Looking for 0 length string, which would only be at the beginning | |
116 if (ca.length == 0) | |
117 return 0; | |
118 | |
119 char c1 = ca[0]; | |
120 | |
121 // Do binary search | |
122 while (low < high) | |
123 { | |
124 mid = (low + high) >> 1; | |
125 pca = table[mid]; | |
126 c = ca.length - pca.length; | |
127 if (c == 0) | |
128 { | |
129 c = cast(ubyte)c1 - cast(ubyte)pca[0]; | |
130 if (c == 0) | |
131 { | |
132 c = memcmp(ca.ptr, pca.ptr, ca.length); | |
133 if (c == 0) | |
134 { //printf("found %d\n", mid); | |
135 return mid; | |
136 } | |
137 } | |
138 } | |
139 if (c < 0) | |
140 { | |
141 high = mid; | |
142 } | |
143 else | |
144 { | |
145 low = mid + 1; | |
146 } | |
147 } | |
148 } | |
149 | |
150 //printf("not found\n"); | |
151 return -1; // not found | |
152 } | |
153 | |
154 unittest | |
155 { | |
156 switch (cast(char []) "c") | |
157 { | |
158 case "coo": | |
159 default: | |
160 break; | |
161 } | |
162 } | |
163 | |
164 /********************************** | |
165 * Same thing, but for wide chars. | |
166 */ | |
167 | |
168 int _d_switch_ustring(wchar[][] table, wchar[] ca) | |
169 in | |
170 { | |
171 //printf("in _d_switch_ustring()\n"); | |
172 assert(table.length >= 0); | |
173 assert(ca.length >= 0); | |
174 | |
175 // Make sure table[] is sorted correctly | |
176 int j; | |
177 | |
178 for (j = 1; j < table.length; j++) | |
179 { | |
180 int len1 = table[j - 1].length; | |
181 int len2 = table[j].length; | |
182 | |
183 assert(len1 <= len2); | |
184 if (len1 == len2) | |
185 { | |
186 int c; | |
187 | |
188 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof); | |
189 assert(c < 0); // c==0 means a duplicate | |
190 } | |
191 } | |
192 } | |
193 out (result) | |
194 { | |
195 int i; | |
196 int c; | |
197 | |
198 //printf("out _d_switch_string()\n"); | |
199 if (result == -1) | |
200 { | |
201 // Not found | |
202 for (i = 0; i < table.length; i++) | |
203 { | |
204 if (table[i].length == ca.length) | |
205 { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof); | |
206 assert(c != 0); | |
207 } | |
208 } | |
209 } | |
210 else | |
211 { | |
212 assert(0 <= result && result < table.length); | |
213 for (i = 0; 1; i++) | |
214 { | |
215 assert(i < table.length); | |
216 if (table[i].length == ca.length) | |
217 { | |
218 c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof); | |
219 if (c == 0) | |
220 { | |
221 assert(i == result); | |
222 break; | |
223 } | |
224 } | |
225 } | |
226 } | |
227 } | |
228 body | |
229 { | |
230 //printf("body _d_switch_ustring()\n"); | |
231 int low; | |
232 int high; | |
233 int mid; | |
234 int c; | |
235 wchar[] pca; | |
236 | |
237 low = 0; | |
238 high = table.length; | |
239 | |
240 /* | |
241 // Print table | |
242 wprintf("ca[] = '%.*s'\n", ca); | |
243 for (mid = 0; mid < high; mid++) | |
244 { | |
245 pca = table[mid]; | |
246 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
247 } | |
248 */ | |
249 | |
250 // Do binary search | |
251 while (low < high) | |
252 { | |
253 mid = (low + high) >> 1; | |
254 pca = table[mid]; | |
255 c = ca.length - pca.length; | |
256 if (c == 0) | |
257 { | |
258 c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof); | |
259 if (c == 0) | |
260 { //printf("found %d\n", mid); | |
261 return mid; | |
262 } | |
263 } | |
264 if (c < 0) | |
265 { | |
266 high = mid; | |
267 } | |
268 else | |
269 { | |
270 low = mid + 1; | |
271 } | |
272 } | |
273 //printf("not found\n"); | |
274 return -1; // not found | |
275 } | |
276 | |
277 | |
278 unittest | |
279 { | |
280 switch (cast(wchar []) "c") | |
281 { | |
282 case "coo": | |
283 default: | |
284 break; | |
285 } | |
286 } | |
287 | |
288 | |
289 /********************************** | |
290 * Same thing, but for wide chars. | |
291 */ | |
292 | |
293 int _d_switch_dstring(dchar[][] table, dchar[] ca) | |
294 in | |
295 { | |
296 //printf("in _d_switch_dstring()\n"); | |
297 assert(table.length >= 0); | |
298 assert(ca.length >= 0); | |
299 | |
300 // Make sure table[] is sorted correctly | |
301 int j; | |
302 | |
303 for (j = 1; j < table.length; j++) | |
304 { | |
305 int len1 = table[j - 1].length; | |
306 int len2 = table[j].length; | |
307 | |
308 assert(len1 <= len2); | |
309 if (len1 == len2) | |
310 { | |
311 int c; | |
312 | |
313 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof); | |
314 assert(c < 0); // c==0 means a duplicate | |
315 } | |
316 } | |
317 } | |
318 out (result) | |
319 { | |
320 int i; | |
321 int c; | |
322 | |
323 //printf("out _d_switch_string()\n"); | |
324 if (result == -1) | |
325 { | |
326 // Not found | |
327 for (i = 0; i < table.length; i++) | |
328 { | |
329 if (table[i].length == ca.length) | |
330 { c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof); | |
331 assert(c != 0); | |
332 } | |
333 } | |
334 } | |
335 else | |
336 { | |
337 assert(0 <= result && result < table.length); | |
338 for (i = 0; 1; i++) | |
339 { | |
340 assert(i < table.length); | |
341 if (table[i].length == ca.length) | |
342 { | |
343 c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof); | |
344 if (c == 0) | |
345 { | |
346 assert(i == result); | |
347 break; | |
348 } | |
349 } | |
350 } | |
351 } | |
352 } | |
353 body | |
354 { | |
355 //printf("body _d_switch_ustring()\n"); | |
356 int low; | |
357 int high; | |
358 int mid; | |
359 int c; | |
360 dchar[] pca; | |
361 | |
362 low = 0; | |
363 high = table.length; | |
364 | |
365 /* | |
366 // Print table | |
367 wprintf("ca[] = '%.*s'\n", ca); | |
368 for (mid = 0; mid < high; mid++) | |
369 { | |
370 pca = table[mid]; | |
371 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
372 } | |
373 */ | |
374 | |
375 // Do binary search | |
376 while (low < high) | |
377 { | |
378 mid = (low + high) >> 1; | |
379 pca = table[mid]; | |
380 c = ca.length - pca.length; | |
381 if (c == 0) | |
382 { | |
383 c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof); | |
384 if (c == 0) | |
385 { //printf("found %d\n", mid); | |
386 return mid; | |
387 } | |
388 } | |
389 if (c < 0) | |
390 { | |
391 high = mid; | |
392 } | |
393 else | |
394 { | |
395 low = mid + 1; | |
396 } | |
397 } | |
398 //printf("not found\n"); | |
399 return -1; // not found | |
400 } | |
401 | |
402 | |
403 unittest | |
404 { | |
405 switch (cast(dchar []) "c") | |
406 { | |
407 case "coo": | |
408 default: | |
409 break; | |
410 } | |
411 } |