annotate trunk/ddata.d @ 3:8e3ddf7a3178

moving
author Saaa
date Wed, 07 Oct 2009 14:02:25 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
Saaa
parents:
diff changeset
1 module ddata.ddata;
Saaa
parents:
diff changeset
2
Saaa
parents:
diff changeset
3 //debug
Saaa
parents:
diff changeset
4 //import std.stdio;
Saaa
parents:
diff changeset
5 import std.string;
Saaa
parents:
diff changeset
6
Saaa
parents:
diff changeset
7 import std2.conv : to;
Saaa
parents:
diff changeset
8 import std2.traits : isNumeric;
Saaa
parents:
diff changeset
9
Saaa
parents:
diff changeset
10 class DDataException : Exception
Saaa
parents:
diff changeset
11 {
Saaa
parents:
diff changeset
12 this(char[] msg)
Saaa
parents:
diff changeset
13 {
Saaa
parents:
diff changeset
14 super(msg);
Saaa
parents:
diff changeset
15 }
Saaa
parents:
diff changeset
16 this( uint loc, char c, char[] msg)
Saaa
parents:
diff changeset
17 {
Saaa
parents:
diff changeset
18 super( format( `parsing failed at string[`, loc-1, `] = '`,c,`'` ,msg));
Saaa
parents:
diff changeset
19 }
Saaa
parents:
diff changeset
20 }
Saaa
parents:
diff changeset
21
Saaa
parents:
diff changeset
22
Saaa
parents:
diff changeset
23 private enum TOKEN{ BOF, SQUARE_L, SQUARE_R, COMMA, ECOMMA, VALUE, EOF}
Saaa
parents:
diff changeset
24
Saaa
parents:
diff changeset
25 private template Depth(T: T[]) { const Depth = 1 + Depth!(T); }
Saaa
parents:
diff changeset
26 private template Depth(T) { const Depth = 0; }
Saaa
parents:
diff changeset
27
Saaa
parents:
diff changeset
28 private template BaseType(T: T[]) { alias BaseType!(T) BaseType; }
Saaa
parents:
diff changeset
29 private template BaseType(T) { alias T BaseType; }
Saaa
parents:
diff changeset
30
Saaa
parents:
diff changeset
31 private template indexAssign(T: T[])
Saaa
parents:
diff changeset
32 {
Saaa
parents:
diff changeset
33 void indexAssign(ref T array, BaseType!(T) value, int[] indices)
Saaa
parents:
diff changeset
34 {
Saaa
parents:
diff changeset
35 static if( is( typeof(array[0]) == typeof(value)))
Saaa
parents:
diff changeset
36 {
Saaa
parents:
diff changeset
37 array[indices[0]] = value;
Saaa
parents:
diff changeset
38 }
Saaa
parents:
diff changeset
39 else
Saaa
parents:
diff changeset
40 {
Saaa
parents:
diff changeset
41 indexAssign!(T)( array[indices[0]], value, indices[1..$]);
Saaa
parents:
diff changeset
42 }
Saaa
parents:
diff changeset
43 }
Saaa
parents:
diff changeset
44 }
Saaa
parents:
diff changeset
45
Saaa
parents:
diff changeset
46 private string ctToString(int i)
Saaa
parents:
diff changeset
47 {
Saaa
parents:
diff changeset
48 if (!i) return "0";
Saaa
parents:
diff changeset
49 string res;
Saaa
parents:
diff changeset
50 while (i) {
Saaa
parents:
diff changeset
51 res = "0123456789"[i%10] ~ res;
Saaa
parents:
diff changeset
52 i /= 10;
Saaa
parents:
diff changeset
53 }
Saaa
parents:
diff changeset
54 return res;
Saaa
parents:
diff changeset
55 }
Saaa
parents:
diff changeset
56
Saaa
parents:
diff changeset
57 private string indexString(int len)
Saaa
parents:
diff changeset
58 {
Saaa
parents:
diff changeset
59 string res;
Saaa
parents:
diff changeset
60 for (int i = 0; i < len; ++i)
Saaa
parents:
diff changeset
61 res ~= "[index["~ctToString(i)~"]] ";
Saaa
parents:
diff changeset
62 return res;
Saaa
parents:
diff changeset
63 }
Saaa
parents:
diff changeset
64
Saaa
parents:
diff changeset
65 private string casesString(int depth, TOKEN type)
Saaa
parents:
diff changeset
66 {
Saaa
parents:
diff changeset
67 string res;
Saaa
parents:
diff changeset
68 res ~= `switch( depth ){`;
Saaa
parents:
diff changeset
69
Saaa
parents:
diff changeset
70 for (int i = 0; i < depth; ++i)
Saaa
parents:
diff changeset
71 {
Saaa
parents:
diff changeset
72 switch(type)
Saaa
parents:
diff changeset
73 {
Saaa
parents:
diff changeset
74 case TOKEN.COMMA:
Saaa
parents:
diff changeset
75 res ~=`case `~ctToString(i)~`:`~
Saaa
parents:
diff changeset
76 `if(temp`~ indexString(i) ~`.length<=index[`~ctToString(i)~`] )temp`~ indexString(i) ~`.length=temp`~ indexString(i) ~`.length*2;`~
Saaa
parents:
diff changeset
77 `break;`;
Saaa
parents:
diff changeset
78 break;
Saaa
parents:
diff changeset
79
Saaa
parents:
diff changeset
80 case TOKEN.SQUARE_L:
Saaa
parents:
diff changeset
81 res ~=`case `~ctToString(i)~`:`~
Saaa
parents:
diff changeset
82 `temp`~ indexString(i) ~`.length=4;`~
Saaa
parents:
diff changeset
83 `break;`;
Saaa
parents:
diff changeset
84 break;
Saaa
parents:
diff changeset
85
Saaa
parents:
diff changeset
86 case TOKEN.SQUARE_R:
Saaa
parents:
diff changeset
87 res ~=`case `~ctToString(i)~`:`~
Saaa
parents:
diff changeset
88 `temp`~ indexString(i) ~`.length=index[`~ctToString(i)~`];`~
Saaa
parents:
diff changeset
89 `break;`;
Saaa
parents:
diff changeset
90 break;
Saaa
parents:
diff changeset
91
Saaa
parents:
diff changeset
92 default:
Saaa
parents:
diff changeset
93 assert(false);
Saaa
parents:
diff changeset
94 break;
Saaa
parents:
diff changeset
95 }
Saaa
parents:
diff changeset
96 }
Saaa
parents:
diff changeset
97
Saaa
parents:
diff changeset
98 res ~= `default:assert(false);break;}`;
Saaa
parents:
diff changeset
99 return res;
Saaa
parents:
diff changeset
100 }
Saaa
parents:
diff changeset
101
Saaa
parents:
diff changeset
102
Saaa
parents:
diff changeset
103 bool toBool(char[] s)
Saaa
parents:
diff changeset
104 {
Saaa
parents:
diff changeset
105 if(s == `true`)
Saaa
parents:
diff changeset
106 {
Saaa
parents:
diff changeset
107 return true;
Saaa
parents:
diff changeset
108 }
Saaa
parents:
diff changeset
109 else if(s == `false`)
Saaa
parents:
diff changeset
110 {
Saaa
parents:
diff changeset
111 return false;
Saaa
parents:
diff changeset
112 }
Saaa
parents:
diff changeset
113 else
Saaa
parents:
diff changeset
114 {
Saaa
parents:
diff changeset
115 throw new Exception(`Cannot convert "`~s~`" to bool`);
Saaa
parents:
diff changeset
116 }
Saaa
parents:
diff changeset
117 return false;
Saaa
parents:
diff changeset
118 }
Saaa
parents:
diff changeset
119
Saaa
parents:
diff changeset
120 public T toArray(T:D[],D)(char[] string)
Saaa
parents:
diff changeset
121 {
Saaa
parents:
diff changeset
122 int[ Depth!(T) ] index = 0;
Saaa
parents:
diff changeset
123
Saaa
parents:
diff changeset
124 T temp;
Saaa
parents:
diff changeset
125 char c;
Saaa
parents:
diff changeset
126
Saaa
parents:
diff changeset
127 int depth = -1;
Saaa
parents:
diff changeset
128
Saaa
parents:
diff changeset
129 int sLoc1 = -1, sLoc2 = -1;
Saaa
parents:
diff changeset
130 int loc = -1;
Saaa
parents:
diff changeset
131
Saaa
parents:
diff changeset
132 TOKEN last = TOKEN.BOF;
Saaa
parents:
diff changeset
133
Saaa
parents:
diff changeset
134 while(true)
Saaa
parents:
diff changeset
135 {
Saaa
parents:
diff changeset
136 loc++;
Saaa
parents:
diff changeset
137 //debug
Saaa
parents:
diff changeset
138 //writefln(loc);
Saaa
parents:
diff changeset
139 if( loc >= string.length )
Saaa
parents:
diff changeset
140 {
Saaa
parents:
diff changeset
141 if( last != TOKEN.SQUARE_R) throw new DDataException( `unexpected end`);
Saaa
parents:
diff changeset
142 if( depth != -1 ) throw new DDataException( `array depth not zero after parsing `);
Saaa
parents:
diff changeset
143 //throw new DDataException(`EOF before end of parsing`);
Saaa
parents:
diff changeset
144 return temp;
Saaa
parents:
diff changeset
145 }
Saaa
parents:
diff changeset
146
Saaa
parents:
diff changeset
147 c = string[loc];
Saaa
parents:
diff changeset
148 //debug
Saaa
parents:
diff changeset
149 //writefln(c);
Saaa
parents:
diff changeset
150 switch(c)
Saaa
parents:
diff changeset
151 {
Saaa
parents:
diff changeset
152 case ' ', '\t', '\v', '\r', '\n', '\f':
Saaa
parents:
diff changeset
153 if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L)
Saaa
parents:
diff changeset
154 {
Saaa
parents:
diff changeset
155 if(sLoc2 < 0)
Saaa
parents:
diff changeset
156 {
Saaa
parents:
diff changeset
157 sLoc1 = loc + 1;
Saaa
parents:
diff changeset
158 }else{
Saaa
parents:
diff changeset
159 sLoc2 = loc;
Saaa
parents:
diff changeset
160 last = TOKEN.VALUE;
Saaa
parents:
diff changeset
161 }
Saaa
parents:
diff changeset
162 }
Saaa
parents:
diff changeset
163 break;
Saaa
parents:
diff changeset
164
Saaa
parents:
diff changeset
165 case ',':
Saaa
parents:
diff changeset
166 index[depth] ++;
Saaa
parents:
diff changeset
167
Saaa
parents:
diff changeset
168 // resize array if necessary
Saaa
parents:
diff changeset
169 mixin ( casesString(Depth!(T), TOKEN.COMMA ) );
Saaa
parents:
diff changeset
170
Saaa
parents:
diff changeset
171 if( last == TOKEN.VALUE && depth == Depth!(T)-1 )
Saaa
parents:
diff changeset
172 {
Saaa
parents:
diff changeset
173 index[depth] --;
Saaa
parents:
diff changeset
174 static if( is(BaseType!(T) == bool) )
Saaa
parents:
diff changeset
175 {
Saaa
parents:
diff changeset
176 indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2] ), index);
Saaa
parents:
diff changeset
177 }
Saaa
parents:
diff changeset
178 else static if( isNumeric!( BaseType!(T) ) )
Saaa
parents:
diff changeset
179 {
Saaa
parents:
diff changeset
180 indexAssign!(T[])( temp, to!( BaseType!(T) )( string[ sLoc1..sLoc2] ), index);
Saaa
parents:
diff changeset
181 }
Saaa
parents:
diff changeset
182 else
Saaa
parents:
diff changeset
183 {
Saaa
parents:
diff changeset
184 assert(false);
Saaa
parents:
diff changeset
185 }
Saaa
parents:
diff changeset
186 index[depth] ++;
Saaa
parents:
diff changeset
187 sLoc1 = -1;
Saaa
parents:
diff changeset
188 sLoc2 = -1;
Saaa
parents:
diff changeset
189 last = TOKEN.ECOMMA;
Saaa
parents:
diff changeset
190 }else if( last == TOKEN.SQUARE_R ){
Saaa
parents:
diff changeset
191 last = TOKEN.COMMA;
Saaa
parents:
diff changeset
192 }else{
Saaa
parents:
diff changeset
193 throw new DDataException( loc, c, `: Value, ']' or ',' expected.`);
Saaa
parents:
diff changeset
194 }
Saaa
parents:
diff changeset
195 break;
Saaa
parents:
diff changeset
196
Saaa
parents:
diff changeset
197 case '[':
Saaa
parents:
diff changeset
198 if( last != TOKEN.COMMA && last != TOKEN.BOF && last != TOKEN.SQUARE_L ) throw new DDataException( loc, c, `: Beginning, '[' or ',' expected.`);
Saaa
parents:
diff changeset
199
Saaa
parents:
diff changeset
200 depth++;
Saaa
parents:
diff changeset
201 if(depth > index.length) throw new DDataException( loc, c, `: Array too deep = `~toString(depth));
Saaa
parents:
diff changeset
202 mixin ( casesString(Depth!(T), TOKEN.SQUARE_L ) );
Saaa
parents:
diff changeset
203 index[depth] = 0;
Saaa
parents:
diff changeset
204 last = TOKEN.SQUARE_L;
Saaa
parents:
diff changeset
205 sLoc1 = -1;
Saaa
parents:
diff changeset
206 sLoc2 = -1;
Saaa
parents:
diff changeset
207 break;
Saaa
parents:
diff changeset
208
Saaa
parents:
diff changeset
209 case ']':
Saaa
parents:
diff changeset
210 if( last == TOKEN.VALUE && depth == Depth!(T)-1 && sLoc2 != -1)
Saaa
parents:
diff changeset
211 {
Saaa
parents:
diff changeset
212 static if( is(BaseType!(T) == bool) )
Saaa
parents:
diff changeset
213 {
Saaa
parents:
diff changeset
214 indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2]), index);
Saaa
parents:
diff changeset
215 }
Saaa
parents:
diff changeset
216 else static if( isNumeric!( BaseType!(T) ) )
Saaa
parents:
diff changeset
217 {
Saaa
parents:
diff changeset
218 indexAssign!(T[])( temp, to!( BaseType!(T) )(string[ sLoc1..sLoc2]), index);
Saaa
parents:
diff changeset
219 }
Saaa
parents:
diff changeset
220 else
Saaa
parents:
diff changeset
221 {
Saaa
parents:
diff changeset
222 assert(false);
Saaa
parents:
diff changeset
223 }
Saaa
parents:
diff changeset
224 sLoc1 = -1;
Saaa
parents:
diff changeset
225 sLoc2 = -1;
Saaa
parents:
diff changeset
226 index[depth] ++;
Saaa
parents:
diff changeset
227 }
Saaa
parents:
diff changeset
228 else if( last == TOKEN.SQUARE_L )
Saaa
parents:
diff changeset
229 {
Saaa
parents:
diff changeset
230 sLoc1 = -1;
Saaa
parents:
diff changeset
231 sLoc2 = -1;
Saaa
parents:
diff changeset
232 }
Saaa
parents:
diff changeset
233 else if( last == TOKEN.SQUARE_R)
Saaa
parents:
diff changeset
234 {
Saaa
parents:
diff changeset
235 index[depth] ++;
Saaa
parents:
diff changeset
236 }
Saaa
parents:
diff changeset
237 else
Saaa
parents:
diff changeset
238 {
Saaa
parents:
diff changeset
239 throw new DDataException( loc, c, `: Value, '[' or ']' expected.`);
Saaa
parents:
diff changeset
240 }
Saaa
parents:
diff changeset
241
Saaa
parents:
diff changeset
242 // set array length to index[depth]
Saaa
parents:
diff changeset
243 mixin ( casesString(Depth!(T), TOKEN.SQUARE_R) );
Saaa
parents:
diff changeset
244
Saaa
parents:
diff changeset
245 index[depth] = 0;
Saaa
parents:
diff changeset
246 depth--;
Saaa
parents:
diff changeset
247 last = TOKEN.SQUARE_R;
Saaa
parents:
diff changeset
248 break;
Saaa
parents:
diff changeset
249
Saaa
parents:
diff changeset
250 default:
Saaa
parents:
diff changeset
251 if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L || last == TOKEN.VALUE)
Saaa
parents:
diff changeset
252 {
Saaa
parents:
diff changeset
253 if( sLoc1 < 0 )
Saaa
parents:
diff changeset
254 {
Saaa
parents:
diff changeset
255 sLoc1 = loc;
Saaa
parents:
diff changeset
256 sLoc2 = loc +1;
Saaa
parents:
diff changeset
257 } else {
Saaa
parents:
diff changeset
258 sLoc2 = loc +1;
Saaa
parents:
diff changeset
259 }
Saaa
parents:
diff changeset
260 last = TOKEN.VALUE;
Saaa
parents:
diff changeset
261 break;
Saaa
parents:
diff changeset
262 }
Saaa
parents:
diff changeset
263 throw new DDataException( loc, c, `: Out of place char found `);
Saaa
parents:
diff changeset
264 break;
Saaa
parents:
diff changeset
265 }
Saaa
parents:
diff changeset
266 }
Saaa
parents:
diff changeset
267 }
Saaa
parents:
diff changeset
268
Saaa
parents:
diff changeset
269 unittest
Saaa
parents:
diff changeset
270 {
Saaa
parents:
diff changeset
271 writefln("DData UnitTest...");
Saaa
parents:
diff changeset
272
Saaa
parents:
diff changeset
273 int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ];
Saaa
parents:
diff changeset
274
Saaa
parents:
diff changeset
275 char[] s = to!(char[])(ia);
Saaa
parents:
diff changeset
276 int[][][] ia2;
Saaa
parents:
diff changeset
277
Saaa
parents:
diff changeset
278 ia2 = toArray!(typeof(ia2))(s);
Saaa
parents:
diff changeset
279 assert( ia == ia2);
Saaa
parents:
diff changeset
280
Saaa
parents:
diff changeset
281 writefln("Done!");
Saaa
parents:
diff changeset
282 }
Saaa
parents:
diff changeset
283