# HG changeset patch # User Saaa # Date 1254916945 -7200 # Node ID 8e3ddf7a317896810400b2d003ecc2b7e3c5546d # Parent ee1232043257ca90ce5e7611f86936c0165088e6 moving diff -r ee1232043257 -r 8e3ddf7a3178 ddata.d --- a/ddata.d Wed Oct 07 13:56:33 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,283 +0,0 @@ -module ddata.ddata; - -//debug -//import std.stdio; -import std.string; - -import std2.conv : to; -import std2.traits : isNumeric; - -class DDataException : Exception -{ - this(char[] msg) - { - super(msg); - } - this( uint loc, char c, char[] msg) - { - super( format( `parsing failed at string[`, loc-1, `] = '`,c,`'` ,msg)); - } -} - - -private enum TOKEN{ BOF, SQUARE_L, SQUARE_R, COMMA, ECOMMA, VALUE, EOF} - -private template Depth(T: T[]) { const Depth = 1 + Depth!(T); } -private template Depth(T) { const Depth = 0; } - -private template BaseType(T: T[]) { alias BaseType!(T) BaseType; } -private template BaseType(T) { alias T BaseType; } - -private template indexAssign(T: T[]) -{ - void indexAssign(ref T array, BaseType!(T) value, int[] indices) - { - static if( is( typeof(array[0]) == typeof(value))) - { - array[indices[0]] = value; - } - else - { - indexAssign!(T)( array[indices[0]], value, indices[1..$]); - } - } -} - -private string ctToString(int i) -{ - if (!i) return "0"; - string res; - while (i) { - res = "0123456789"[i%10] ~ res; - i /= 10; - } - return res; -} - -private string indexString(int len) -{ - string res; - for (int i = 0; i < len; ++i) - res ~= "[index["~ctToString(i)~"]] "; - return res; -} - -private string casesString(int depth, TOKEN type) -{ - string res; - res ~= `switch( depth ){`; - - for (int i = 0; i < depth; ++i) - { - switch(type) - { - case TOKEN.COMMA: - res ~=`case `~ctToString(i)~`:`~ - `if(temp`~ indexString(i) ~`.length<=index[`~ctToString(i)~`] )temp`~ indexString(i) ~`.length=temp`~ indexString(i) ~`.length*2;`~ - `break;`; - break; - - case TOKEN.SQUARE_L: - res ~=`case `~ctToString(i)~`:`~ - `temp`~ indexString(i) ~`.length=4;`~ - `break;`; - break; - - case TOKEN.SQUARE_R: - res ~=`case `~ctToString(i)~`:`~ - `temp`~ indexString(i) ~`.length=index[`~ctToString(i)~`];`~ - `break;`; - break; - - default: - assert(false); - break; - } - } - - res ~= `default:assert(false);break;}`; - return res; -} - - -bool toBool(char[] s) -{ - if(s == `true`) - { - return true; - } - else if(s == `false`) - { - return false; - } - else - { - throw new Exception(`Cannot convert "`~s~`" to bool`); - } - return false; -} - -public T toArray(T:D[],D)(char[] string) -{ - int[ Depth!(T) ] index = 0; - - T temp; - char c; - - int depth = -1; - - int sLoc1 = -1, sLoc2 = -1; - int loc = -1; - - TOKEN last = TOKEN.BOF; - - while(true) - { - loc++; - //debug - //writefln(loc); - if( loc >= string.length ) - { - if( last != TOKEN.SQUARE_R) throw new DDataException( `unexpected end`); - if( depth != -1 ) throw new DDataException( `array depth not zero after parsing `); - //throw new DDataException(`EOF before end of parsing`); - return temp; - } - - c = string[loc]; - //debug - //writefln(c); - switch(c) - { - case ' ', '\t', '\v', '\r', '\n', '\f': - if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L) - { - if(sLoc2 < 0) - { - sLoc1 = loc + 1; - }else{ - sLoc2 = loc; - last = TOKEN.VALUE; - } - } - break; - - case ',': - index[depth] ++; - - // resize array if necessary - mixin ( casesString(Depth!(T), TOKEN.COMMA ) ); - - if( last == TOKEN.VALUE && depth == Depth!(T)-1 ) - { - index[depth] --; - static if( is(BaseType!(T) == bool) ) - { - indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2] ), index); - } - else static if( isNumeric!( BaseType!(T) ) ) - { - indexAssign!(T[])( temp, to!( BaseType!(T) )( string[ sLoc1..sLoc2] ), index); - } - else - { - assert(false); - } - index[depth] ++; - sLoc1 = -1; - sLoc2 = -1; - last = TOKEN.ECOMMA; - }else if( last == TOKEN.SQUARE_R ){ - last = TOKEN.COMMA; - }else{ - throw new DDataException( loc, c, `: Value, ']' or ',' expected.`); - } - break; - - case '[': - if( last != TOKEN.COMMA && last != TOKEN.BOF && last != TOKEN.SQUARE_L ) throw new DDataException( loc, c, `: Beginning, '[' or ',' expected.`); - - depth++; - if(depth > index.length) throw new DDataException( loc, c, `: Array too deep = `~toString(depth)); - mixin ( casesString(Depth!(T), TOKEN.SQUARE_L ) ); - index[depth] = 0; - last = TOKEN.SQUARE_L; - sLoc1 = -1; - sLoc2 = -1; - break; - - case ']': - if( last == TOKEN.VALUE && depth == Depth!(T)-1 && sLoc2 != -1) - { - static if( is(BaseType!(T) == bool) ) - { - indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2]), index); - } - else static if( isNumeric!( BaseType!(T) ) ) - { - indexAssign!(T[])( temp, to!( BaseType!(T) )(string[ sLoc1..sLoc2]), index); - } - else - { - assert(false); - } - sLoc1 = -1; - sLoc2 = -1; - index[depth] ++; - } - else if( last == TOKEN.SQUARE_L ) - { - sLoc1 = -1; - sLoc2 = -1; - } - else if( last == TOKEN.SQUARE_R) - { - index[depth] ++; - } - else - { - throw new DDataException( loc, c, `: Value, '[' or ']' expected.`); - } - - // set array length to index[depth] - mixin ( casesString(Depth!(T), TOKEN.SQUARE_R) ); - - index[depth] = 0; - depth--; - last = TOKEN.SQUARE_R; - break; - - default: - if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L || last == TOKEN.VALUE) - { - if( sLoc1 < 0 ) - { - sLoc1 = loc; - sLoc2 = loc +1; - } else { - sLoc2 = loc +1; - } - last = TOKEN.VALUE; - break; - } - throw new DDataException( loc, c, `: Out of place char found `); - break; - } - } -} - -unittest -{ - writefln("DData UnitTest..."); - - int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ]; - - char[] s = to!(char[])(ia); - int[][][] ia2; - - ia2 = toArray!(typeof(ia2))(s); - assert( ia == ia2); - - writefln("Done!"); -} - diff -r ee1232043257 -r 8e3ddf7a3178 trunk/ddata.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/ddata.d Wed Oct 07 14:02:25 2009 +0200 @@ -0,0 +1,283 @@ +module ddata.ddata; + +//debug +//import std.stdio; +import std.string; + +import std2.conv : to; +import std2.traits : isNumeric; + +class DDataException : Exception +{ + this(char[] msg) + { + super(msg); + } + this( uint loc, char c, char[] msg) + { + super( format( `parsing failed at string[`, loc-1, `] = '`,c,`'` ,msg)); + } +} + + +private enum TOKEN{ BOF, SQUARE_L, SQUARE_R, COMMA, ECOMMA, VALUE, EOF} + +private template Depth(T: T[]) { const Depth = 1 + Depth!(T); } +private template Depth(T) { const Depth = 0; } + +private template BaseType(T: T[]) { alias BaseType!(T) BaseType; } +private template BaseType(T) { alias T BaseType; } + +private template indexAssign(T: T[]) +{ + void indexAssign(ref T array, BaseType!(T) value, int[] indices) + { + static if( is( typeof(array[0]) == typeof(value))) + { + array[indices[0]] = value; + } + else + { + indexAssign!(T)( array[indices[0]], value, indices[1..$]); + } + } +} + +private string ctToString(int i) +{ + if (!i) return "0"; + string res; + while (i) { + res = "0123456789"[i%10] ~ res; + i /= 10; + } + return res; +} + +private string indexString(int len) +{ + string res; + for (int i = 0; i < len; ++i) + res ~= "[index["~ctToString(i)~"]] "; + return res; +} + +private string casesString(int depth, TOKEN type) +{ + string res; + res ~= `switch( depth ){`; + + for (int i = 0; i < depth; ++i) + { + switch(type) + { + case TOKEN.COMMA: + res ~=`case `~ctToString(i)~`:`~ + `if(temp`~ indexString(i) ~`.length<=index[`~ctToString(i)~`] )temp`~ indexString(i) ~`.length=temp`~ indexString(i) ~`.length*2;`~ + `break;`; + break; + + case TOKEN.SQUARE_L: + res ~=`case `~ctToString(i)~`:`~ + `temp`~ indexString(i) ~`.length=4;`~ + `break;`; + break; + + case TOKEN.SQUARE_R: + res ~=`case `~ctToString(i)~`:`~ + `temp`~ indexString(i) ~`.length=index[`~ctToString(i)~`];`~ + `break;`; + break; + + default: + assert(false); + break; + } + } + + res ~= `default:assert(false);break;}`; + return res; +} + + +bool toBool(char[] s) +{ + if(s == `true`) + { + return true; + } + else if(s == `false`) + { + return false; + } + else + { + throw new Exception(`Cannot convert "`~s~`" to bool`); + } + return false; +} + +public T toArray(T:D[],D)(char[] string) +{ + int[ Depth!(T) ] index = 0; + + T temp; + char c; + + int depth = -1; + + int sLoc1 = -1, sLoc2 = -1; + int loc = -1; + + TOKEN last = TOKEN.BOF; + + while(true) + { + loc++; + //debug + //writefln(loc); + if( loc >= string.length ) + { + if( last != TOKEN.SQUARE_R) throw new DDataException( `unexpected end`); + if( depth != -1 ) throw new DDataException( `array depth not zero after parsing `); + //throw new DDataException(`EOF before end of parsing`); + return temp; + } + + c = string[loc]; + //debug + //writefln(c); + switch(c) + { + case ' ', '\t', '\v', '\r', '\n', '\f': + if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L) + { + if(sLoc2 < 0) + { + sLoc1 = loc + 1; + }else{ + sLoc2 = loc; + last = TOKEN.VALUE; + } + } + break; + + case ',': + index[depth] ++; + + // resize array if necessary + mixin ( casesString(Depth!(T), TOKEN.COMMA ) ); + + if( last == TOKEN.VALUE && depth == Depth!(T)-1 ) + { + index[depth] --; + static if( is(BaseType!(T) == bool) ) + { + indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2] ), index); + } + else static if( isNumeric!( BaseType!(T) ) ) + { + indexAssign!(T[])( temp, to!( BaseType!(T) )( string[ sLoc1..sLoc2] ), index); + } + else + { + assert(false); + } + index[depth] ++; + sLoc1 = -1; + sLoc2 = -1; + last = TOKEN.ECOMMA; + }else if( last == TOKEN.SQUARE_R ){ + last = TOKEN.COMMA; + }else{ + throw new DDataException( loc, c, `: Value, ']' or ',' expected.`); + } + break; + + case '[': + if( last != TOKEN.COMMA && last != TOKEN.BOF && last != TOKEN.SQUARE_L ) throw new DDataException( loc, c, `: Beginning, '[' or ',' expected.`); + + depth++; + if(depth > index.length) throw new DDataException( loc, c, `: Array too deep = `~toString(depth)); + mixin ( casesString(Depth!(T), TOKEN.SQUARE_L ) ); + index[depth] = 0; + last = TOKEN.SQUARE_L; + sLoc1 = -1; + sLoc2 = -1; + break; + + case ']': + if( last == TOKEN.VALUE && depth == Depth!(T)-1 && sLoc2 != -1) + { + static if( is(BaseType!(T) == bool) ) + { + indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2]), index); + } + else static if( isNumeric!( BaseType!(T) ) ) + { + indexAssign!(T[])( temp, to!( BaseType!(T) )(string[ sLoc1..sLoc2]), index); + } + else + { + assert(false); + } + sLoc1 = -1; + sLoc2 = -1; + index[depth] ++; + } + else if( last == TOKEN.SQUARE_L ) + { + sLoc1 = -1; + sLoc2 = -1; + } + else if( last == TOKEN.SQUARE_R) + { + index[depth] ++; + } + else + { + throw new DDataException( loc, c, `: Value, '[' or ']' expected.`); + } + + // set array length to index[depth] + mixin ( casesString(Depth!(T), TOKEN.SQUARE_R) ); + + index[depth] = 0; + depth--; + last = TOKEN.SQUARE_R; + break; + + default: + if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L || last == TOKEN.VALUE) + { + if( sLoc1 < 0 ) + { + sLoc1 = loc; + sLoc2 = loc +1; + } else { + sLoc2 = loc +1; + } + last = TOKEN.VALUE; + break; + } + throw new DDataException( loc, c, `: Out of place char found `); + break; + } + } +} + +unittest +{ + writefln("DData UnitTest..."); + + int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ]; + + char[] s = to!(char[])(ia); + int[][][] ia2; + + ia2 = toArray!(typeof(ia2))(s); + assert( ia == ia2); + + writefln("Done!"); +} +