Changeset 98
- Timestamp:
- 01/02/06 05:01:50 (3 years ago)
- Files:
-
- trunk/ddl/DynamicLibrary.d (modified) (1 diff)
- trunk/ddl/Mangle.d (modified) (1 diff)
- trunk/meta/conv.d (modified) (6 diffs)
- trunk/meta/strhacks.d (modified) (4 diffs)
- trunk/meta/string.d (modified) (1 diff)
- trunk/test/linktest1.d (modified) (2 diffs)
- trunk/test/testclassinterface.d (added)
- trunk/test/testmodule.d (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ddl/DynamicLibrary.d
r94 r98 68 68 public bit isCModule(){ 69 69 return true; 70 } 71 72 public void* getExportAddress(char[] name){ 73 return this.getExport(name).address; 74 } 70 } 71 72 // Dynamic loading of non-class objects, including static functions 75 73 76 74 template getDExport(T, char [] name) { 77 75 static if(T.mangleof[0] == 'P'){ 78 typeof(T) getDExport() { return cast(typeof(T))getExportAddress( "_D" ~ mangleText!(name) ~ sliceheadoff!(T.mangleof, 1)); } 79 } else{ 80 typeof(T) getDExport() { return cast(typeof(T))getExportAddress("_D" ~ mangleText!(name) ~ T.mangleof); } 81 } 82 } 83 /* 84 TODO: investigate the proper mangle code for these 85 86 template getClassInfo(char[] classname){ 87 ClassInfo getClassinfo(){ 88 return cast(ClassInfo)getExportAddress("__Class_" ~ mangleText!(name)); 76 typeof(T) getDExport() { 77 return cast(typeof(T))getExport( "_D" ~ mangleSymbolName!(name) ~ sliceheadoff!(T.mangleof, 1)).address; 78 } 79 } else { 80 typeof(T) getDExport() { 81 return cast(typeof(T))getExport("_D" ~ mangleSymbolName!(name) ~ T.mangleof).address; } 89 82 } 90 83 } 91 84 92 template getCtor(Tfn, char[] classname){93 typeof(Tfn) getCtor(){94 //TODO: hack up the mangleof of Tfn, to replace the return type as the correct type.95 return cast( typeof(Tfn))getExportAddress( "_D" ~ mangleText!(classname) ~ "_ctor" ~ Tfn.mangleof ~ mangleText!(classname));85 /// Load the ClassInfo corresponding to classname. 86 template getClassInfo(char[] classname){ 87 ClassInfo getClassInfo(){ 88 return cast(ClassInfo)getExport("__Class_" ~ mangleSymbolName!(classname)).address; 96 89 } 97 90 } 91 /** TInterface function(P1) getCtor!(TInterface, classname, P1); 92 * 93 * Returns a function which constructs a class, using the given parameters. 94 * For example: 95 * ------------ 96 * auto newFoo = getCtor("FooModule.Foo", char [], real); 97 * auto newFooI = getCtor("FooModule.Foo", int); 98 * x = newFooI(58); 99 * y = newFoo("Avogadro's Number", 6.022e23); 100 * ----------------- 101 * is equivalent to: 102 * ----------------- 103 * x = new FooModule.Foo(58); 104 * y = new FooModule.Foo("Avogadro's Number", 6.022e23); 105 * ----------------- 106 */ 107 // TODO: might be better to return a delegate? 108 template getCtor(TInterface, char [] classname) { 109 TInterface function() getCtor() { 110 static ClassInfo typeClass; 111 typeClass = getClassInfo!(classname)(); 112 static Object function (Object) rawCtor; 113 rawCtor = cast(Object function (Object)) getExport( 114 "_D" ~ mangleSymbolName!(classname) ~ mangleSymbolName!("_ctor") 115 ~ "F" 116 ~ "ZC" ~ mangleSymbolName!(classname)).address; 117 static TInterface internalCtor() { 118 auto a = _d_newclass(typeClass); 119 rawCtor(a); 120 return cast(TInterface)a; 121 } 122 123 return &internalCtor; 124 } 125 } 98 126 99 template createObject(char[] classname){ 100 Object createObject(){ 101 auto typeClass = getClassInfo!(classname)(); 102 auto objClass = _d_newclass(typeTestClass); 103 auto ctorClass = getCtor!(Object function(Object),classname)(); 104 return ctorClass(objClass); 105 } 106 }*/ 127 template getCtor(TInterface, char [] classname, P1) { 128 TInterface function(P1) getCtor() { 129 static ClassInfo typeClass; 130 typeClass = getClassInfo!(classname)(); 131 static Object function (P1, Object) rawCtor; 132 rawCtor = cast(Object function (P1, Object)) getExport( 133 "_D" ~ mangleSymbolName!(classname) ~ mangleSymbolName!("_ctor") 134 ~ "F" ~ P1.mangleof 135 ~ "ZC" ~ mangleSymbolName!(classname)).address; 136 static TInterface internalCtor(P1 p1) { 137 auto a = _d_newclass(typeClass); 138 rawCtor(p1, a); 139 return cast(TInterface)a; 140 } 141 142 return &internalCtor; 143 } 144 } 145 template getCtor(TInterface, char [] classname, P1, P2) { 146 TInterface function(P1, P2) getCtor() { 147 static ClassInfo typeClass; 148 typeClass = getClassInfo!(classname)(); 149 static Object function (P1, P2, Object) rawCtor; 150 rawCtor = cast(Object function (P1, P2, Object)) getExport( 151 "_D" ~ mangleSymbolName!(classname) ~ mangleSymbolName!("_ctor") 152 ~ "F" ~ P1.mangleof ~ P2.mangleof 153 ~ "ZC" ~ mangleSymbolName!(classname)).address; 154 static TInterface internalCtor(P1 p1, P2 p2) { 155 auto a = _d_newclass(typeClass); 156 rawCtor(p1, a); 157 return cast(TInterface)a; 158 } 159 160 return &internalCtor; 161 } 162 } 107 163 } trunk/ddl/Mangle.d
r94 r98 38 38 import meta.strhacks; 39 39 40 template mangleText(char[] text, char [] latestword="") 40 /** char [] mangleSymbolName!(char [] name); 41 * Convert a name of the form "module.func" to the form 42 * "6module4func". 43 */ 44 template mangleSymbolName(char[] text, char [] latestword="") 41 45 { 42 46 static if (text.length<1) { 43 static if ( strlen!(latestword)==0)44 const char[] mangle Text= "";45 else const char[] mangle Text = itoa!(strlen!(latestword)) ~ latestword;47 static if (latestword.length==0) 48 const char[] mangleSymbolName = ""; 49 else const char[] mangleSymbolName = itoa!(latestword.length) ~ latestword; 46 50 } else static if (text[0]=='.') { 47 const char[] mangle Text=48 itoa!( strlen!(latestword)) ~ latestword ~ .mangleText!(slice!(text, 1, strlen!(text)), "");51 const char[] mangleSymbolName = 52 itoa!(latestword.length) ~ latestword ~ .mangleSymbolName!(text[1..(text.length)], ""); 49 53 } else 50 const char[] mangle Text = .mangleText!( slice!(text, 1, strlen!(text)), concat!(latestword,slice!(text, 0, 1)));54 const char[] mangleSymbolName = .mangleSymbolName!( text[1..(text.length)], concat!(latestword,text[0..(1)])); 51 55 } trunk/meta/conv.d
r89 r98 4 4 * so most of these functions have unique names. 5 5 * Compile with -version=testmeta to run unit tests. 6 * Author: Don Clugston. License: Public domain. 6 7 */ 7 8 … … 19 20 template itoa(long n) 20 21 { 21 static if (n<0) const char [] itoa = "-" ~ .itoa!(-n); 22 else static if (n<10L) const char [] itoa = decimaldigit!(n); 23 else const char [] itoa = .itoa!(n/10L) ~ decimaldigit!(n%10L); 22 static if (n<0) { 23 const char [] itoa = "-" ~ .itoa!(-n); 24 } else static if (n<10L) { 25 const char [] itoa = decimaldigit!(n); 26 } else { 27 const char [] itoa = .itoa!(n/10L) ~ decimaldigit!(n%10L); 28 } 24 29 } 25 30 26 31 template toHexString(ulong n) 27 32 { 28 static if (n<16L) const char [] toHexString = hexdigit!(n); 29 else const char [] toHexString = .toHexString!(n >> 4) ~ hexdigit!(n&0xF); 33 static if (n<16L) { 34 const char [] toHexString = hexdigit!(n); 35 } else { 36 const char [] toHexString = .toHexString!(n >> 4) ~ hexdigit!(n&0xF); 37 } 30 38 } 31 39 … … 37 45 static if (s.length==indx) const long atoi=sofar; 38 46 else static if (indx==0 && s[indx]=='-') const long atoi = -.atoi!(s, 0, 1); 39 else static if (!isdigit!( getcharat!(s, indx)) ) const long atoi = sofar;40 else const long atoi = .atoi!(s, sofar * 10 + (getcharat!(s, indx)-'0'), indx+1);47 else static if (!isdigit!( cast(char) s[indx] ) ) const long atoi = sofar; 48 else const long atoi = .atoi!(s, sofar * 10 + s[indx]-'0', indx+1); 41 49 } 42 50 43 51 /******************************************************* 44 * the number of digitswhich would be 'consumed' by atoi!().52 * the number of characters in s[] which would be 'consumed' by atoi!(). 45 53 */ 46 54 template countleadingdigits(char [] s, int indx=0) 47 55 { 48 static if (s.length==indx) const int countleadingdigits=indx; 49 else static if (indx==0 && s[indx]=='-') const int countleadingdigits = .countleadingdigits!(s, indx+1); 50 else static if (!isdigit!(getcharat!(s, indx))) const int countleadingdigits=indx; 51 else const int countleadingdigits = .countleadingdigits!(s, indx+1); 56 static if (s.length==indx) { 57 const int countleadingdigits=indx; 58 } else static if (indx==0 && s[indx]=='-') { 59 const int countleadingdigits = .countleadingdigits!(s, indx+1); 60 } else static if (!isdigit!( cast(char)s[indx] )) { 61 const int countleadingdigits=indx; 62 } else { 63 const int countleadingdigits = .countleadingdigits!(s, indx+1); 64 } 65 } 66 67 /******************************* 68 * int sigfigs!(char [] s) 69 * 70 * Returns the number of significant figures in the decimal number s. 71 */ 72 template sigfigs(char [] s, int p=0) 73 { 74 static if ( s.length ==p ) { 75 const int sigfigs=0; 76 } else static if ( s[p]=='.'|| (p==0 && s[p]=='-') ) { 77 const int sigfigs = .sigfigs!(s, p+1); 78 }else static if ( isdigit!(cast(char)s[p]) ) { 79 const int sigfigs = 1 + .sigfigs!(s, p+1); 80 } else static if ( s[p]=='e' || s[p]=='E' ) { 81 // abort once we reach the exponent 82 const int sigfigs=0; 83 } else { 84 static assert(0); // invalid character in string 85 } 52 86 } 53 87 … … 67 101 template fcvt(real x) 68 102 { 69 static if (x<0) const real fcvt = "-" ~ .fcvt!(-x); 70 else static if (x==cast(long)x) const char [] fcvt = itoa!(cast(long)x); 71 else const char [] fcvt = itoa!(cast(long)x) ~ "." ~ chomp!(afterdec!(x - cast(long)x), '0'); 103 static if (x<0) { 104 const real fcvt = "-" ~ .fcvt!(-x); 105 } else static if (x==cast(long)x) { 106 const char [] fcvt = itoa!(cast(long)x); 107 } else { 108 const char [] fcvt = itoa!(cast(long)x) ~ "." ~ chomp!(afterdec!(x - cast(long)x), '0'); 109 } 72 110 } 73 111 … … 91 129 92 130 version(testmeta) { 93 import meta.strhacks;131 private import meta.strhacks; 94 132 95 133 static assert( streq!(itoa!(5638), "5638")); … … 100 138 static assert( countleadingdigits!("325827wip")==6); 101 139 static assert( countleadingdigits!("abc")==0); 140 static assert( sigfigs!("1.2500")==5); 141 static assert( sigfigs!("-380.0")==4); 142 static assert( sigfigs!("0")==1); 143 static assert( sigfigs!("-1.20e49")==3); 102 144 } trunk/meta/strhacks.d
r89 r98 1 /** Workarounds required for DMD 0.14 11 /** Workarounds required for DMD 0.142 2 2 * 3 3 * Most of these are only required when they are used as a template value parameter. … … 8 8 { 9 9 const int strlen = str.length; 10 }11 12 /// = str[from..to]13 template slice(char [] str, int from, int to)14 {15 const char [] slice = str[from..to];16 }17 18 // = str[n]19 template getcharat(char [] str, int n)20 {21 const char getcharat = str[n];22 }23 24 /// = str[from..$]25 template sliceheadoff(char [] str, int from)26 {27 const char [] sliceheadoff = str[from..str.length];28 }29 30 template slicetailoff(char [] str, int charstochopoff)31 {32 const char [] slicetailoff = str[0..str.length-charstochopoff];33 10 } 34 11 … … 44 21 else static if (str1[0]!=str2[0]) const bool streq=false; 45 22 else static if (str1.length==1) const bool streq=true; 46 else const bool streq = .streq!(s lice!(str1, 1, strlen!(str1)), slice!(str2, 1, strlen!(str2)));23 else const bool streq = .streq!(str1[1..(str1.length)], str2[1..(str2.length)]); 47 24 } 48 25 … … 72 49 static assert(!streq!("abc", "axc") ); 73 50 static assert(!streq!("abc", "abcd") ); 74 static assert(streq!(sliceheadoff!("abcdefg", 3), "defg")); 51 // static assert(streq!("abcdef", "abc" ~ "def")); // this crashes DMD 0.142 52 static assert(streq!("abcdef", concat!("abc", "def"))); 75 53 } 54 55 //----------------------------------------------------------------- 56 // Workarounds required for DMD 0.141, fixed for DMD 0.142 57 58 /// = str[from..to] 59 template slice(char [] str, int from, int to) 60 { 61 const char [] slice = str[from..to]; 62 } 63 64 /// = str[from..$] 65 template sliceheadoff(char [] str, int from) 66 { 67 const char [] sliceheadoff = str[from..str.length]; 68 } 69 70 template slicetailoff(char [] str, int charstochopoff) 71 { 72 const char [] slicetailoff = str[0..str.length-charstochopoff]; 73 } 74 75 // Actually this is still buggy in DMD 0.142, you need to cast(char). 76 // = str[n] 77 template getcharat(char [] str, int n) 78 { 79 const char getcharat = str[n]; 80 } 81 82 //----------------------------------------------------------------- trunk/meta/string.d
r88 r98 8 8 { 9 9 static if (str.length==0) const char[] chomp=str; 10 else static if (str[str len!(str)-1]==delimiter)11 const char [] chomp = .chomp!( s licetailoff!(str, 1), delimiter);10 else static if (str[str.length - 1]==delimiter) 11 const char [] chomp = .chomp!( str[0..(str.length-1)], delimiter); 12 12 else const char [] chomp = str; 13 13 } trunk/test/linktest1.d
r94 r98 13 13 - tests those exported handles 14 14 */ 15 16 private import test.testclassinterface; 17 18 template getCtorName(char [] fullclassname) 19 { 20 const char [] getCtorName = "_D" ~ mangleSymbolName!(fullclassname) 21 ~ mangleSymbolName!("_ctor") ~ "FZC" ~ mangleSymbolName!(fullclassname); 22 } 23 24 template getCtorName(char [] fullclassname, P1) 25 { 26 const char [] getCtorName = "_D" ~ mangleSymbolName!(fullclassname) 27 ~ mangleSymbolName!("_ctor") ~ "F" ~P1.mangleof ~ "ZC" ~ mangleSymbolName!(fullclassname); 28 } 29 15 30 void main(){ 16 31 Stdout.println("Starting."); … … 29 44 Stdout.println("add: 42+69 = %d",addFun(42,69)); 30 45 helloWorld(); 46 47 // Create a class using two different constructors. We need to specify 48 // the interface we'll be using (in this case, ITestClass). 49 50 // Constructor with no parameters 51 auto newTestClass = testLibrary.getCtor!(ITestClass, "test.testmodule.TestClass")(); 52 auto a = newTestClass(); 53 54 // Constructor with one parameter 55 auto newTestClass1 = testLibrary.getCtor!(ITestClass, "test.testmodule.TestClass", int)(); 56 auto b = newTestClass1(31415); 57 58 // Call a member function of the interface 59 a.callable(); 60 b.callable(); 31 61 32 62 Stdout.println("Done."); trunk/test/testmodule.d
r66 r98 26 26 27 27 private import std.stdio; 28 import test.testclassinterface; 28 29 29 class TestClass{ 30 31 class TestClass : ITestClass { 30 32 uint a; 31 33 32 34 public this(){ 33 35 a = 1; 34 printf("TestClass created \n");36 printf("TestClass created with no parameters\n"); 35 37 test(); 38 } 39 public this(int w) 40 { 41 a=w; 42 printf("TestClass created with parameter %d\n", w); 43 test(); 44 45 } 46 public void callable() { 47 writefln("In externally callable function, A=", a); 36 48 } 37 49 … … 41 53 42 54 static this(){ 43 writefln("TestClass init alized");55 writefln("TestClass initialized"); 44 56 } 45 57 }
