Changeset 123
- Timestamp:
- 10/30/07 14:00:23 (10 months ago)
- Files:
-
- trunk/blade/Blade.d (modified) (7 diffs)
- trunk/blade/BladeDemo.d (modified) (1 diff)
- trunk/blade/BladeUtil.d (modified) (3 diffs)
- trunk/blade/CodegenX86.d (modified) (2 diffs)
- trunk/blade/SyntaxTree.d (modified) (5 diffs)
- trunk/blade/SyntaxTreeDemo.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/Blade.d
r122 r123 53 53 54 54 public import blade.SyntaxTree : AbstractSyntaxTree, syntaxtreeof, AST, Symbol; 55 private import blade.BladeUtil : wrapInQuotes ;55 private import blade.BladeUtil : wrapInQuotes, startsWith; 56 56 private import blade.BladeRank; 57 57 public import blade.CodegenX86 : generateCodeForAsmX87, generateCodeForSSE2, MAX_X87_VECTORS, MAX_SSE_VECTORS; … … 86 86 87 87 // ------------------------------------ 88 // return true if the first characters of x are y.89 bool startsWith(char [] x, char [] y)90 {91 return (x.length>=y.length && x[0..y.length]==y);92 }93 88 94 89 // ------------------------------------ … … 142 137 } 143 138 144 145 139 //------------------------------------------------------- 146 140 // Invoker functions 147 141 //------------------------------------------------------- 148 // These are CTFE functions which, when mixed in, will call 149 // the BLASfunction. They ensure that all types are converted into standard142 // These are CTFE functions which, when mixed in, will call the BLAS template 143 // function. They ensure that all types are converted into standard 150 144 // simple forms, ensure that the vector lengths are equal, and pass in all 151 145 // of the parameters. … … 154 148 char [] invokeX87(AbstractSyntaxTree tree) 155 149 { 156 char [] result = "X87VECGEN!(" ~ wrapInQuotes(tree.expression); 150 char [] result = assertAllVectorLengthsEqual(tree); 151 result ~= "X87VECGEN!(" ~ wrapInQuotes(tree.expression); 157 152 for (int i=0; i<tree.symbolTable.length;++i) { 158 153 char [] t = tree.symbolTable[i].type; … … 162 157 // We convert everything else to double, since that uses less 163 158 // FPU stack space. 164 if (t == "real" || t =="double" || t=="float") result ~= "," ~ t;165 else if (t =="long" || t=="ulong") result~=",real";159 if (t == "real" || t == "double" || t == "float") result ~= "," ~ t; 160 else if (t == "long" || t == "ulong") result ~= ",real"; 166 161 else result ~= "double"; // Convert all other scalars into doubles. 167 162 } … … 183 178 /// Generate code which will call the SSE2 function 184 179 char [] invokeSSE2(AbstractSyntaxTree tree) 180 { 181 char [] result = assertAllVectorLengthsEqual(tree); 182 183 result ~= "SSEVECGEN!(" ~ wrapInQuotes(tree.expression); 184 // For SSE2, everything must be implicitly convertible to double. 185 for (int i=0; i<tree.symbolTable.length;++i) { 186 if (tree.symbolTable[i].rank==0) result ~= ",double"; 187 else result ~= ",double[]"; 188 } 189 result ~= ")("; 190 int knt=0; 191 for (int i=0; i<tree.symbolTable.length;++i) { 192 if (knt>0) result ~=","; 193 result ~= tree.symbolTable[i].value; 194 ++knt; 195 } 196 return result ~ ");"; 197 } 198 199 200 char [] assertAllVectorLengthsEqual(AbstractSyntaxTree tree) 185 201 { 186 202 char [] result =""; … … 197 213 } 198 214 } 199 200 result ~= "SSEVECGEN!(" ~ wrapInQuotes(tree.expression); 201 // For SSE2, everything must be implicitly convertible to double. 202 for (int i=0; i<tree.symbolTable.length;++i) { 203 if (tree.symbolTable[i].rank==0) result ~= ",double"; 204 else result ~= ",double[]"; 205 } 206 result ~= ")("; 207 int knt=0; 208 for (int i=0; i<tree.symbolTable.length;++i) { 209 if (knt>0) result ~=","; 210 result ~= tree.symbolTable[i].value; 211 ++knt; 212 } 213 return result ~ ");"; 214 } 215 return result; 216 } 217 218 /* 219 // Return a vector which contains the length of the expression. 220 int findVectorForLength(AbstractSyntaxTree tree) 221 { 222 } 223 */ 215 224 216 225 // Categorise the expression, and dispatch to the appropriate code generator. trunk/blade/BladeDemo.d
r122 r123 22 22 d[0..$] = [17.0, 28.25, 1, 56.2];; 23 23 auto w2=z.ptr; 24 float[] q = [17.0f, 28.25, 1 ];25 float [ 3] r;26 idouble [] p = [2.3i, 254i, 0.1i ];24 float[] q = [17.0f, 28.25, 1, 0]; 25 float [4] r; 26 idouble [] p = [2.3i, 254i, 0.1i, 1.2i]; 27 27 for(int i=0; i<r.length;++i) { 28 28 // r[i]= q[i]+ a[i]*2213.3; 29 29 r[i]= q[i]*2213.3L; 30 30 } 31 31 32 32 mixin(vectorize(" a += d*2.01")); 33 mixin(vectorize(" a += r*2.01")); 33 34 34 35 writefln("a=", a); trunk/blade/BladeUtil.d
r120 r123 1 1 // Written in the D programming language 1.0 2 2 /** 3 * Utility functions3 * General CTFE string utility functions 4 4 * BLADE 0.3Alpha -- Basic Linear Algebra D Expressions 5 5 */ … … 9 9 public: 10 10 11 // General utilities.11 // Convert from integral type to string. 12 12 char [] itoa(T)(T x) 13 13 { … … 25 25 } 26 26 27 27 28 unittest { 28 29 assert(blade.BladeUtil.itoa(-5)=="-5"); 29 30 } 30 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 41 /** Add quotes to the start and end of the string, 42 * escaping any quotes and backslashes inside it. 43 */ 31 44 char [] wrapInQuotes(char [] instr) 32 45 { trunk/blade/CodegenX86.d
r121 r123 439 439 440 440 if (operations.length>2 && operations[$-1]=='=') { 441 storage ~= " fstp " ~ indexedVectorPrev(typelist, ranklist, operations[$-2] ) ~ "; // " ~ operations[ done..done+2]~ \n;441 storage ~= " fstp " ~ indexedVectorPrev(typelist, ranklist, operations[$-2] ) ~ "; // " ~ operations[$-2..$-1] ~ "=" ~ \n; 442 442 operations=operations[0..$-2]; 443 443 } … … 479 479 } else { 480 480 // For scalar float or double values, we can multiply directly, saving one slot on the FP stack. 481 next = " fmul " ~ operandSize(typelist[operations[done]-'A']) ~ "val" ~ itoa(operations[done]-'A') ~"; \n";481 next = " fmul " ~ operandSize(typelist[operations[done]-'A']) ~ "val" ~ itoa(operations[done]-'A') ~"; // * " ~ operations[done..done+1] ~ "\n"; 482 482 mainbody ~= next; firstbody ~= next; 483 483 } trunk/blade/SyntaxTree.d
r118 r123 30 30 * NOTES: 31 31 * Functions (including properties) are typed as function pointers in the symbol table. 32 * QUIRKS: 33 * If the expression refers to a non-existent variable, a sensible error message 34 * will be printed, but it will be followed by a torrent of useless error messages. 32 * ERROR HANDLING: 33 * If the expression refers to a non-existent variable, the type will be an empty string, 34 * and the value will be the name of the variable. 35 * Syntax errors in the expression generate normal D errors in the user code, except 36 * for mismatched parentheses. 37 * QUIRKS: 35 38 * The syntaxtreeof() function and the Symbol and AST classes must be visible to the user code. 36 39 */ … … 56 59 { 57 60 char [][] symbols = replaceSymbolsWithPlaceholders(expression); 58 char [] result = `AbstractSyntaxTree(` ~ mixin_getPrecedence(expression) ~ `,[`; 61 char [] result = `AbstractSyntaxTree(` ~ mixin_getPrecedence(expression) ~ `,[`; 59 62 for(int i=0; i<symbols.length; ++i) { 60 63 if (i>0) result ~=","; … … 63 66 ~ `,` ~ mixin_rankOf(symbols[i]) ~ `)`; 64 67 } 68 65 69 result ~="])"; 66 70 return "mixin(" ~ wrapInQuotes(result) ~ ")"; … … 317 321 { 318 322 // Compiler bug: typeof(x).stringof doesn't compile if x is a function. 319 return `mixin(is(typeof(` ~ sym ~ `)==function)?` ~ wrapInQuotes("typeof(&" ~ sym ~ ").stringof")~`:` ~ wrapInQuotes("typeof(" ~ sym ~ ").stringof") ~ `)`; 323 // If it doesn't compile at all, return an empty string. 324 return `mixin(!is(typeof(` ~ sym ~ `))?"\"\"" : is(typeof(` ~ sym ~ `)==function)?` ~ wrapInQuotes("typeof(&" ~ sym ~ ").stringof")~`:` ~ wrapInQuotes("typeof(" ~ sym ~ ").stringof") ~ `)`; 320 325 } 321 326 … … 327 332 // (1) 1.23.stringof fails to compile. Fortunately (1.23).stringof works. 328 333 // (2) x.stringof doesn't compile, if x is a function. Just return x instead. 334 // We also return x if x doesn't compile (eg, is an undefined variable). 329 335 if (sym[0]>='0' && sym[0]<='9') { // numeric literal 330 336 return "(" ~ sym ~ ").stringof"; 331 337 } 332 return `mixin(is(typeof(` ~ sym ~ `)==function) ?` ~ wrapInQuotes(wrapInQuotes(sym)) ~ `:` ~ wrapInQuotes(sym ~ ".stringof") ~ ")";338 return `mixin(is(typeof(` ~ sym ~ `)==function) || !is(typeof(` ~ sym ~ `))?` ~ wrapInQuotes(wrapInQuotes(sym)) ~ `:` ~ wrapInQuotes(sym ~ ".stringof") ~ ")"; 333 339 } 334 340 trunk/blade/SyntaxTreeDemo.d
r118 r123 51 51 char [] displayParseResult(AbstractSyntaxTree tree) 52 52 { 53 char [] sym=" Rank\t Const?\tType\tValue\n";53 char [] sym=" Rank\tLiteral\tType\tValue\n"; 54 54 for (int i=0; i<tree.symbolTable.length; ++i) { 55 55 Symbol q = tree.symbolTable[i]; 56 56 sym~=cast(char)('A'+i) ~ ": " ~ cast(char)('0' + q.rank) ~ \t; 57 57 char c = q.value[0]; 58 bool isConst = ((c>='0' && c<='9')||c=='-'|| c=='"' || c=='\''); 59 if (isConst) sym~="CONST"; 58 if (tree.symbolTable[i].type=="") sym ~= "ERROR"; 59 else if ((c>='0' && c<='9')||c=='-') sym ~= "Numeric"; 60 else if (c=='"' || c=='\'') sym ~= "String"; 60 61 sym ~=\t ~ q.type ~ \t ~ q.value ~ \n; 61 62 } 62 return `Expression is: ` ~ tree.expression ~ \n ~ prettyTree(tree.expression) ~ \n ~ sym; 63 return `Expression is: ` ~ tree.expression ~ \n ~ prettyTree(tree.expression) ~ \n ~ sym; 63 64 } 64 65 … … 77 78 const int butNotThis=6; 78 79 79 int func(int x, int itsInterestingThatYouCanSeeThis = butNotThis ) { return 2; } 80 80 int func(int x, int youCanSeeThis = butNotThis ) { return 2; } 81 81 82 82 struct Blah(int Y) { … … 100 100 mixin(vec("b = ags.af[fróg*2..56] in s")); 101 101 mixin(vec("func(d*35,d+ 4)")); 102 mixin(vec("QUAL^s "));102 mixin(vec("QUAL^st")); 103 103 mixin(vec("sin(3.45)")); 104 104 }
