comparison druntime/src/compiler/ldc/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 }