Changeset 151

Show
Ignore:
Timestamp:
11/30/07 02:14:47 (9 months ago)
Author:
Don Clugston
Message:

Now parsing and rank analysis supports combined slice & indices -- eg [1,2..4,5]. Categorisation step not yet implemented.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/blade/BladeDemo.d

    r150 r151  
    1414// Use heap-allocated arrays, or static arrays (DMD 1.023 or later) 
    1515// cdouble[] always remains aligned, even when sliced. 
     16 
    1617 
    1718    
     
    4041    mixin(vectorize("q+= q*2.01")); 
    4142   
    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..$]")); 
    4447    writefln("a=", a); 
    4548} 
  • trunk/blade/BladeRank.d

    r150 r151  
    8484    if (expr.length==1) { 
    8585        if (expr=="$") return 0; 
    86         assert(expr[0]>='A' && expr[0]<='Z', expr); 
     86        assert(expr[0]>='A' && expr[0]<='Z', "BLADE ICE: " ~ expr); 
    8787        return rank[expr[0]-'A']-'0'; 
    8888    } 
     
    199199            int totrank = lrank; 
    200200            do { 
    201                 // allow rank of 1 to be a slice operation 
    202                 // (so A[1,[2,$-1], $] is possible). 
    203 //                if (z>1) assert(0, right[0..z+1]); 
    204201                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                } 
    208224                                 
    209225                if (z==right.length-1) return totrank; 
     
    275291    assert(exprRank("A[B,(([B,C])[B]),B]", "600")==3); 
    276292    assert(exprRank("A+=(B[C..$])", "110")==1); 
     293    assert(exprRank("A+=(B[C,D..$])", "2300")==2); 
    277294} 
    278295 
  • trunk/blade/BladeSimplify.d

    r150 r151  
    249249} 
    250250 
    251 /+ 
    252251// 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. 
    254254bool isStrided(char [] s) 
    255255{ 
     
    257257   if (s[$-2..$]=="[]") return false; 
    258258   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; 
    264270            numbrack++; 
    265271        } 
    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        } 
    270280   } 
     281   return false; 
    271282} 
    272283 
    273284unittest { 
    274285    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 
    279292 
    280293RevisedExpression simplifyVectorExpression(char [] expr, char [] rank) 
     
    337350        } else f ~= c; 
    338351    } 
    339  
    340352    return RevisedExpression(f, comp, old_ranks~r, mapping); 
    341353} 
    342354 
    343 unittest {    
     355unittest { 
     356    assert(exprSimplify("A+=(B*(C[D,D..$]))","1020","","")=="(A+=(B* {C[D,D..$]} ))"); 
    344357    assert(exprSimplify("A+=(((D[E])*B)[E])", "103300","","")=="(A+=(B* {D[E][E]} ))"); 
    345358    assert(exprSimplify("A+=(B*((C[B])[B..E]))", "103300","","")=="(A+=(B* {C[B][B..E]} ))"); 
  • trunk/blade/SyntaxTree.d

    r150 r151  
    111111//  ==== LEXER ==== 
    112112 
    113 /** Return true if text is a D keyword 
     113/** Return true if text is a non-value, non-type D keyword 
    114114 */ 
    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" ]; 
     115bool 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" ]; 
    130131     
    131132    foreach(char [] s; keywords) { 
     
    176177            } 
    177178             // The next character is NOT part of the symbol. 
    178             if (isKeyword(symbol)) { 
     179            if (isNonTypeKeyword(symbol)) { 
    179180                code ~= symbol; // non-type keywords are NOT symbols 
    180181                symbol=""; 
     
    231232operation was performed. This gives the associativity and precedence rules 
    232233which the compiler used. 
     234 
     235Extension: This code allows opSlice and opIndex to be mixed, even though it is 
     236not yet allowed in normal D code. 
    233237*/ 
    234238class AST(char [] expr) 
     
    276280    preOp!("++") opAddAssign(T:int=int)(int x){ return null; } 
    277281    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; }     
    279284    AST!("(" ~ text ~ "[" ~ AllText!(T) ~ "])") opIndex(T...)(T x){ return null; } 
    280285    AST!("((" ~ text ~ "[" ~ AllText!(T) ~ "])=" ~ U.text ~ ")") opIndexAssign(U, T...)(U,T){ return null; } 
     
    286291    preOp!("-") opNeg(dummy=void)(){ return null; } 
    287292    preOp!("*") opStar(dummy=void)(){ return null; }  // D2.0 only 
     293 
    288294    postOp!("[]") opSlice(dummy=void)(){ return null; } 
    289295    static if (text.length>3 && text[$-3..$]!="++)" && text[$-3..$]!="--)") { 
     
    301307    static if (T.length==0) const char [] AllText = ""; 
    302308    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..$]); 
    303311    else const char [] AllText = T[0].text ~ "," ~ AllText!(T[1..$]); 
    304312} 
     
    329337                code ~= "(cast(AST!(`" ~ expr[i] ~"`))(null))"; 
    330338                lastWasSymbol = true; 
    331             } else { 
     339            } else {                 
    332340                if (!lastWasSymbol && expr[i]=='[') { 
    333341                    code ~= "(cast(AST!(``))(null))"; 
     
    336344                    && expr[i]!= '\n' && expr[i]!=')') lastWasSymbol = false; 
    337345                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]; 
    339351            } 
    340352        } 
     
    407419     
    408420    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]"); 
    409422    assert(mixin(mixin_getPrecedence("A[B][C,D]"))=="(A[B])[C,D]"); 
    410423    assert(mixin(mixin_getPrecedence("A[B,([C,D])]"))=="A[B,([C,D])]");