Changeset 151
- Timestamp:
- 11/30/07 02:14:47 (9 months ago)
- Files:
-
- trunk/blade/BladeDemo.d (modified) (2 diffs)
- trunk/blade/BladeRank.d (modified) (3 diffs)
- trunk/blade/BladeSimplify.d (modified) (3 diffs)
- trunk/blade/SyntaxTree.d (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/BladeDemo.d
r150 r151 14 14 // Use heap-allocated arrays, or static arrays (DMD 1.023 or later) 15 15 // cdouble[] always remains aligned, even when sliced. 16 16 17 17 18 … … 40 41 mixin(vectorize("q+= q*2.01")); 41 42 42 // This parses OK, but isn't get supported at the codegen step. 43 // mixin(vectorize("a+=another[1,[1,$]]")); 43 // This parses OK, but isn't yet supported at the codegen step. 44 // mixin(vectorize("a+=6*another[1,[1,$]]")); 45 // This parses, but crashes at categorize. 46 // mixin(vectorize("a+=6*another[1,1..$]")); 44 47 writefln("a=", a); 45 48 } trunk/blade/BladeRank.d
r150 r151 84 84 if (expr.length==1) { 85 85 if (expr=="$") return 0; 86 assert(expr[0]>='A' && expr[0]<='Z', expr);86 assert(expr[0]>='A' && expr[0]<='Z', "BLADE ICE: " ~ expr); 87 87 return rank[expr[0]-'A']-'0'; 88 88 } … … 199 199 int totrank = lrank; 200 200 do { 201 // allow rank of 1 to be a slice operation202 // (so A[1,[2,$-1], $] is possible).203 // if (z>1) assert(0, right[0..z+1]);204 201 int rrank = subexprRank(right[0..z+1], rank); 205 if (rrank<0) return rrank; 206 if (rrank>1) return RankError.NonScalarIndex; 207 if (rrank==0) --totrank; 202 if (z==right.length-1 || right[z+1]==',') { 203 // allow rank of 1 to be a slice operation 204 // (so A[1,[2,$-1], $] is possible). 205 if (rrank<0) return rrank; 206 if (rrank>1) return RankError.NonScalarIndex; 207 if (rrank==0) --totrank; 208 if (z==right.length-1) return totrank; 209 } else if (!(z+3 < right.length && right[z+1..z+3]=="..")) { 210 return RankError.DotDotExpected; 211 } else {// slice 212 char [] start = right[0..z+1]; 213 char [] end = right[z+3..$]; 214 int startrank = subexprRank(start, rank); 215 if (startrank<0) return startrank; 216 z = exprLength(end); 217 int endrank = subexprRank(end[0..z+1], rank); 218 if (endrank<0) return endrank; 219 if (startrank!=0 || endrank!=0) return RankError.NonScalarSlice; 220 right = end; 221 // assert(0, start ~ "@" ~ end); 222 // assert(0, right); 223 } 208 224 209 225 if (z==right.length-1) return totrank; … … 275 291 assert(exprRank("A[B,(([B,C])[B]),B]", "600")==3); 276 292 assert(exprRank("A+=(B[C..$])", "110")==1); 293 assert(exprRank("A+=(B[C,D..$])", "2300")==2); 277 294 } 278 295 trunk/blade/BladeSimplify.d
r150 r151 249 249 } 250 250 251 /+252 251 // return true if the given symbol has a non-zero stride. 253 // s must end with an index or slicing expression. 252 // This happens whenever there is a slice (including a complete slice) 253 // on a non-final index. 254 254 bool isStrided(char [] s) 255 255 { … … 257 257 if (s[$-2..$]=="[]") return false; 258 258 int numbrack=0; 259 bool retval = true; 260 for (int i = s.length-2; i>1; --i) { 261 if (s[i]==']') numbrack--; 262 if (s[i]=='[') { 263 if (numbrack==0) return retval; 259 int paren = 0; 260 bool hasSliced=false; 261 bool startIndex=false; 262 for(int i=1; i<s.length; ++i) { 263 if (s[i]=='(') ++paren; 264 else if (s[i]==')') --paren; 265 if (paren==0 && s[i]==']') { 266 if (hasSliced && startIndex) return true; 267 numbrack--; if (s[i-1]=='[') { hasSliced=true; startIndex=false; } } 268 if (paren==0 && s[i]=='[') { 269 startIndex = true; 264 270 numbrack++; 265 271 } 266 if (numbrack==0 && s[i]=='.' && s[i-1]=='.') { 267 // it's a slice 268 retval = false; 269 } 272 if (paren==0 && numbrack==1 && s[i]==',') { 273 if (hasSliced && startIndex) return true; 274 startIndex = true; 275 } 276 if (paren==0 && numbrack==2 && s[i]==',') { startIndex=false; hasSliced=true; } 277 if (paren==0 && numbrack==1 && s[i]=='.' && s[i-1]=='.') { 278 startIndex = false; // [..] slices don't move the index to the next value. 279 } 270 280 } 281 return false; 271 282 } 272 283 273 284 unittest { 274 285 assert(!isStrided("A[3..5][]")); 275 assert(isStrided("A[2..7][3]")); 276 assert(!isStrided("A[7][B[2]..6]")); 277 } 278 +/ 286 assert(!isStrided("A[2..7][3]")); 287 assert(isStrided("A[[2,7],3]")); 288 assert(!isStrided("A[2,[2,7]]")); 289 assert(!isStrided("A[7][B[[1,3],2]..6]")); 290 } 291 279 292 280 293 RevisedExpression simplifyVectorExpression(char [] expr, char [] rank) … … 337 350 } else f ~= c; 338 351 } 339 340 352 return RevisedExpression(f, comp, old_ranks~r, mapping); 341 353 } 342 354 343 unittest { 355 unittest { 356 assert(exprSimplify("A+=(B*(C[D,D..$]))","1020","","")=="(A+=(B* {C[D,D..$]} ))"); 344 357 assert(exprSimplify("A+=(((D[E])*B)[E])", "103300","","")=="(A+=(B* {D[E][E]} ))"); 345 358 assert(exprSimplify("A+=(B*((C[B])[B..E]))", "103300","","")=="(A+=(B* {C[B][B..E]} ))"); trunk/blade/SyntaxTree.d
r150 r151 111 111 // ==== LEXER ==== 112 112 113 /** Return true if text is a D keyword113 /** Return true if text is a non-value, non-type D keyword 114 114 */ 115 bool isKeyword(char [] text) { 116 char [][] keywords = [ "abstract", "alias", "align", "asm", "assert", 117 "auto", "body", "bool", "break", "byte", "case", "cast", "catch", 118 "cdouble", "cent", "cfloat", "char", "class", "const", "continue", 119 "creal", "dchar", "debug", "default", "delegate", "delete", "deprecated", 120 "do", "double", "else", "enum", "export", "extern", "false", "final", 121 "finally", "float", "for", "foreach", "foreach_reverse", "function", 122 "goto", "idouble", "if", "ifloat", "import", "in", "inout", "int", 123 "interface", "invariant", "ireal", "is", "lazy", "long", "macro", "mixin", 124 "module", "new", "null", "out", "override", "package", "pragma", "private", 125 "protected", "public", "real", "ref", "return", "scope", "short", "static", 126 "struct", "super", "switch", "synchronized", "template", "this", "throw", 127 "__traits", "true", "try", "typedef", "typeid", "typeof", "ubyte", "ucent", 128 "uint", "ulong", "union", "unittest", "ushort", "version", "void", 129 "volatile", "wchar", "while", "with" ]; 115 bool isNonTypeKeyword(char [] text) { 116 char [][] keywords = [ 117 // "byte", "bool", "cdouble", "cent", "cfloat", "cdouble", "creal", "char", 118 // "double", "dchar", "false", "float", "idouble", "ifloat", "int", "ireal", "long", 119 // "null", "real", "short", "true", "ubyte", "ucent", "uint", "ulong", "ushort", 120 // "wchar", "this", "super", "void" 121 "abstract", "alias", "align", "asm", "assert", "auto", "body", "break", 122 "case", "cast", "catch", "class", "const", "continue", "dchar", "debug", 123 "default", "delegate", "delete", "deprecated", "do", "else", "enum", 124 "export", "extern", "final", "finally", "for", "foreach", "foreach_reverse", 125 "function", "goto", "if", "import", "in", "inout", "interface", "invariant", 126 "is", "lazy", "macro", "mixin", "module", "new", "out", "override", 127 "package", "pragma", "private", "protected", "public", "ref", "return", 128 "scope", "static", "struct", "switch", "synchronized", "template", "throw", 129 "__traits", "try", "typedef", "typeid", "typeof", "union", "unittest", 130 "version", "volatile", "while", "with" ]; 130 131 131 132 foreach(char [] s; keywords) { … … 176 177 } 177 178 // The next character is NOT part of the symbol. 178 if (is Keyword(symbol)) {179 if (isNonTypeKeyword(symbol)) { 179 180 code ~= symbol; // non-type keywords are NOT symbols 180 181 symbol=""; … … 231 232 operation was performed. This gives the associativity and precedence rules 232 233 which the compiler used. 234 235 Extension: This code allows opSlice and opIndex to be mixed, even though it is 236 not yet allowed in normal D code. 233 237 */ 234 238 class AST(char [] expr) … … 276 280 preOp!("++") opAddAssign(T:int=int)(int x){ return null; } 277 281 preOp!("--") opSubAssign(T:int=int)(int x){ return null; } 278 AST!("(" ~ text ~ "[" ~ T.text ~ ".." ~ U.text ~ "])") opSlice(T, U)(T x, U y){ return null; } 282 // OpSlice is combined with opIndex. 283 // AST!("(" ~ text ~ "[" ~ T.text ~ ".." ~ U.text ~ "])") opSlice(T, U)(T x, U y){ return null; } 279 284 AST!("(" ~ text ~ "[" ~ AllText!(T) ~ "])") opIndex(T...)(T x){ return null; } 280 285 AST!("((" ~ text ~ "[" ~ AllText!(T) ~ "])=" ~ U.text ~ ")") opIndexAssign(U, T...)(U,T){ return null; } … … 286 291 preOp!("-") opNeg(dummy=void)(){ return null; } 287 292 preOp!("*") opStar(dummy=void)(){ return null; } // D2.0 only 293 288 294 postOp!("[]") opSlice(dummy=void)(){ return null; } 289 295 static if (text.length>3 && text[$-3..$]!="++)" && text[$-3..$]!="--)") { … … 301 307 static if (T.length==0) const char [] AllText = ""; 302 308 else static if (T.length==1) const char [] AllText = T[0].text; 309 else static if (T.length>2 && T[1].text=="..") // Convert back to a slice 310 const char [] AllText = T[0].text ~ ".." ~ AllText!(T[2..$]); 303 311 else const char [] AllText = T[0].text ~ "," ~ AllText!(T[1..$]); 304 312 } … … 329 337 code ~= "(cast(AST!(`" ~ expr[i] ~"`))(null))"; 330 338 lastWasSymbol = true; 331 } else { 339 } else { 332 340 if (!lastWasSymbol && expr[i]=='[') { 333 341 code ~= "(cast(AST!(``))(null))"; … … 336 344 && expr[i]!= '\n' && expr[i]!=')') lastWasSymbol = false; 337 345 if (expr[i]==']') lastWasSymbol=true; 338 code ~= expr[i]; 346 if (i<expr.length-1 && expr[i..i+2]=="..") { 347 code ~= ",(cast(AST!(`..`))(null)),"; 348 ++i; 349 } 350 else code ~= expr[i]; 339 351 } 340 352 } … … 407 419 408 420 assert(mixin(mixin_getPrecedence("A[B,[C,D]]"))=="A[B,([C,D])]"); 421 assert(mixin(mixin_getPrecedence("A[B,C..D]"))=="A[B,C..D]"); 409 422 assert(mixin(mixin_getPrecedence("A[B][C,D]"))=="(A[B])[C,D]"); 410 423 assert(mixin(mixin_getPrecedence("A[B,([C,D])]"))=="A[B,([C,D])]");
