Changeset 139
- Timestamp:
- 11/16/07 12:37:50 (10 months ago)
- Files:
-
- trunk/blade/Blade.d (modified) (3 diffs)
- trunk/blade/BladeRank.d (modified) (2 diffs)
- trunk/blade/BladeSimplify.d (modified) (6 diffs)
- trunk/blade/BladeUtil.d (modified) (1 diff)
- trunk/blade/SyntaxTreeDemo.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/Blade.d
r138 r139 46 46 47 47 public import blade.SyntaxTree : AbstractSyntaxTree, syntaxtreeof, AST, Symbol; 48 private import blade.BladeUtil : wrapInQuotes, startsWith;48 private import blade.BladeUtil : enquote; 49 49 private import blade.BladeRank; 50 50 private import blade.BladeSimplify : simplifySyntaxTree, RevisedExpression; … … 176 176 { 177 177 char [] result = assertAllVectorLengthsEqual(tree, revised); 178 result ~= "X87VECGEN!(" ~ wrapInQuotes(revised.expression);178 result ~= `X87VECGEN!("` ~ enquote(revised.expression) ~ `"`; 179 179 char [] vals; 180 180 … … 223 223 char [] result = assertAllVectorLengthsEqual(tree, revised); 224 224 result ~= assertAllVectorsAlign128(tree, revised); 225 226 char [] scalartype = SSE2? ",double" : ",float"; 227 char [] vectortype = SSE2? ",double*" : ",float*"; 228 229 result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ "," ~ wrapInQuotes(revised.expression); 225 226 result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ `,"` ~ enquote(revised.expression) ~ `"`; 230 227 // For SSE2, everything must be implicitly convertible to double. 231 228 char [] vals; 232 229 for (int i=0; i<revised.mapping.length;++i) { 233 230 char rnk = revised.rank[i]; 234 if (rnk=='0') result ~= scalartype;235 else result ~= vectortype;231 if (rnk=='0') result ~= SSE2? ",double" : ",float"; 232 else result ~= SSE2? ",double*" : ",float*"; 236 233 vals ~= "," ~ getValueForSymbol(revised.mapping[i], tree, revised); 237 234 // for vectors, we only need the pointer, not the length trunk/blade/BladeRank.d
r138 r139 189 189 if (op=="[") { 190 190 assert(lrank>0, "Cannot index a scalar"); 191 if (right.length==0) return lrank; // was [], which doesn't change the length 191 192 int z = exprLength(right); 192 193 if (z+1 == right.length) { … … 237 238 assert(exprRank("A=(B*C)", "202")==2); 238 239 assert(exprRank("B*=(C*A)", "010")==1); 240 assert(exprRank("(A[])+B", "22")==2); 239 241 assert(exprRank("D+=((A+C)*B)", "2022")==2); 240 242 assert(exprRank("D+=((A&C)*B)", "0101")==1); trunk/blade/BladeSimplify.d
r138 r139 49 49 } 50 50 51 private: 52 51 53 /* Adjust the expression to remove all references to duplicated symbol table 52 54 * entries. (Duplicates can occur as a result of resolving aliases or constants). … … 85 87 } 86 88 87 89 /// As for exprSimplify, but allows the whole thing to be wrapped in parentheses. 88 90 char [] subexprSimplify(char [] expr, char [] rank, char [] mulexpr, char [] indexexpr) 89 91 { … … 104 106 // strip off the parentheses before simplifying 105 107 return exprSimplify(expr[1..$-1], rank, mulexpr, indexexpr); 108 } 109 110 // Simplify a scalar*tensor expression. 111 char [] simplifyScalarMul(char [] scalar, char [] tensor, char [] mulexpr, char [] rank, char [] indexexpr) 112 { 113 char [] m = scalar; 114 if (mulexpr.length>0) m = "(" ~ mulexpr ~ "*" ~ scalar ~ ")"; 115 if (tensor.length > 1 && hasScalarMultiply(tensor[1..$-1], rank)) { 116 // opportunity for scalar folding 117 return subexprSimplify(tensor, rank, m, indexexpr); 118 } else { 119 if (m.length>1) m = " {" ~ m ~ "} "; 120 return "(" ~ m ~ "*" ~ subexprSimplify(tensor, rank, "", indexexpr) ~ ")"; 121 } 106 122 } 107 123 … … 142 158 char [] right = expr[y+1..$]; 143 159 if (expr[x+1]=='[') right = expr[y+1..$-1]; // drop off the ']'. 144 int lrank = subexprRank(left, rank);145 160 if (op=="[") { 146 161 // accumulate indexing and slicing operations 147 162 return subexprSimplify(left, rank, mulexpr, "[" ~ right ~ "]" ~ indexexpr); 148 163 } 164 int lrank = subexprRank(left, rank); 149 165 int rrank = subexprRank(right, rank); 150 166 // Fold scalars together 151 167 if (op=="*") { 152 if (lrank==0) { 153 char [] m = left; 154 if (mulexpr.length>0) m = "(" ~ left ~ "*" ~ mulexpr ~ ")"; 155 if (right.length > 1 && hasScalarMultiply(right[1..$-1], rank)) { 156 // opportunity for scalar folding 157 return subexprSimplify(right[1..$-1], rank, m, indexexpr); 158 } else { 159 if (m.length>1) m = " {" ~ m ~ "} "; 160 return "(" ~ m ~ "*" ~ subexprSimplify(right, rank, "", indexexpr) ~ ")"; 161 } 162 163 } else if (rrank==0) { 164 char [] m = right; 165 if (mulexpr.length>0) m = "(" ~ mulexpr ~ "*" ~ right ~ ")"; 166 if (left.length> 1 && hasScalarMultiply(left[1..$-1], rank)) { 167 return subexprSimplify(left, rank, m, indexexpr); 168 } else { 169 if (m.length>1) m = " {" ~ m ~ "} "; 170 return "(" ~ m ~ "*" ~ subexprSimplify(left, rank, "", indexexpr) ~ ")"; 171 } 172 } // else it's matrix * matrix 168 if (lrank==0) 169 return simplifyScalarMul(left, right, mulexpr, rank, indexexpr); 170 else if (rrank==0) 171 return simplifyScalarMul(right, left, mulexpr, rank, indexexpr); 172 // else it's matrix * matrix 173 173 } 174 174 if (op=="*=") { … … 178 178 if (m.length>1) m= " {" ~ m ~ "} "; 179 179 return "(" ~ subexprSimplify(left, rank, "", indexexpr)~ "*=" ~ m ~ ")"; 180 } 180 } // else it's matrix *= matrix 181 181 } 182 182 return "(" ~ subexprSimplify(left, rank, mulexpr, indexexpr) ~ op ~ subexprSimplify(right, rank, mulexpr, indexexpr) ~ ")"; … … 270 270 assert(exprSimplify("A*=(B*C)", "100","","")== "(A*= {(B*C)} )"); 271 271 assert(exprSimplify("A=((B*C)-D)", "1101","","")=="(A=((C*B)-D))"); 272 assert(exprSimplify("A=(((B*E)+(C*E))*D)", "11100","","")=="(A=(( {(D*E)} *B)+( {(D*E)} *C)))"); 273 assert(exprSimplify("A=(D*((B*E)+(C*E)))", "11100","","")=="(A=(( {(D*E)} *B)+( {(D*E)} *C)))"); 272 274 273 275 RevisedExpression e = simplifyVectorExpression("A+=(((D[B])*C)[B])", "2004"); trunk/blade/BladeUtil.d
r138 r139 30 30 } 31 31 32 /**33 * return true if the first characters of x are y.34 */35 bool startsWith(char [] x, char [] y)36 {37 return (x.length>=y.length && x[0..y.length]==y);38 }39 40 32 /** Escape any quotes and backslashes inside the given string 41 33 */ 42 34 char [] enquote(char [] instr) 43 35 { 44 char [] str=""; 45 foreach(char c; instr) { 46 if (c=='"' || c=='\\') str ~= `\`; 47 str ~= c; 36 // It's worth using copy-on-write even for CTFE. 37 for(int i=0; i<instr.length; ++i) { 38 if (instr[i]=='"' || instr[i]=='\\') { 39 char [] str=instr[0..i]; 40 foreach(char c; instr[i..$]) { 41 if (c=='"' || c=='\\') str ~= `\`; 42 str ~= c; 43 } 44 return str; 45 } 48 46 } 49 return str; 50 } 51 52 /** Add quotes to the start and end of the string, 53 * escaping any quotes and backslashes inside it. 54 */ 55 char [] wrapInQuotes(char [] instr) 56 { 57 char [] str=`"`; 58 foreach(char c; instr) { 59 if (c=='"' || c=='\\') str ~= `\`; 60 str ~= c; 61 } 62 return str ~ `"`; 47 return instr; 63 48 } 64 49 65 50 unittest { 66 51 assert(enquote(`"a\"`)==`\"a\\\"`); 67 assert(wrapInQuotes(`"a\"`)==`"\"a\\\""`);68 52 } trunk/blade/SyntaxTreeDemo.d
r138 r139 4 4 unary operators: & ! 5 5 && and || operators 6 $ not really supported: a[$-1] should be replaced by a[a.length-1]7 6 NCEG floating point operators 8 7 new, delete, anonymous classes
