Changeset 38
- Timestamp:
- 08/16/06 13:03:32 (2 years ago)
- Files:
-
- trunk/examples/testdll/testdll.d (modified) (1 diff)
- trunk/html_doc/class_wrapping.html (modified) (1 diff)
- trunk/infrastructure/pyd/ftype.d (modified) (1 diff)
- trunk/infrastructure/pyd/generators/ftype.py (modified) (4 diffs)
- trunk/infrastructure/pyd/generators/ftype.txt (added)
- trunk/infrastructure/pyd/generators/iterate.py (added)
- trunk/infrastructure/pyd/generators/iterate.txt (added)
- trunk/infrastructure/pyd/iteration.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/examples/testdll/testdll.d
r37 r38 53 53 } 54 54 Foo opAdd(Foo f) { return new Foo(m_i + f.m_i); } 55 int opApply(int delegate(inout int ) dg) {55 int opApply(int delegate(inout int, inout int) dg) { 56 56 int result = 0; 57 int j; 57 58 for (int i=0; i<10; ++i) { 58 result = dg(i); 59 j = i+1; 60 result = dg(i, j); 59 61 if (result) break; 60 62 } trunk/html_doc/class_wrapping.html
r36 r38 74 74 <p>At the moment, only the following operator overloads are supported:</p> 75 75 76 <p><code>opAdd, opSub, opMul, opDiv, opMod, opAnd, opOr, opXor, opShl, opShr, opCat, opAddAssign, opSubAssign, opMulAssign, opDivAssign, opModAssign, opAndAssign, opOrAssign, opXorAssign, opShlAssign, opShrAssign, opCatAssign, opIn_r </code></p>76 <p><code>opAdd, opSub, opMul, opDiv, opMod, opAnd, opOr, opXor, opShl, opShr, opCat, opAddAssign, opSubAssign, opMulAssign, opDivAssign, opModAssign, opAndAssign, opOrAssign, opXorAssign, opShlAssign, opShrAssign, opCatAssign, opIn_r, opApply</code></p> 77 77 78 <p>Most notably missing from this list are <code>opIndex, opIndexAssign, opSlice, opSliceAssign, opCall</code>, and <code>opApply</code>. Support for these operators is forthcoming. Also missing from the list are <code>opUShr</code> and <code>opUShrAssign</code>. Python does not have an unsigned right-shift operator, so these operator overloads are not supported. (You may still wrap them with a normal method using <code>wrapped_class.def</code>, of course.)</p> 78 <p>Most notably missing from this list are <code>opIndex, opIndexAssign, opSlice, opSliceAssign</code>, and <code>opCall</code>. Support for these operators is forthcoming. Also missing from the list are <code>opUShr</code> and <code>opUShrAssign</code>. Python does not have an unsigned right-shift operator, so these operator overloads are not supported. (You may still wrap them with a normal method using <code>wrapped_class.def</code>, of course.)</p> 79 80 <p>Notably <em>included</em> in the list is <code>opApply</code>. Pyd wraps D's iteration protocol with the help of Mikola Lysenko's StackThreads package.</p> 79 81 80 82 <h3><a class="anchor" name="examples">Examples</a></h3> trunk/infrastructure/pyd/ftype.d
r28 r38 144 144 const uint NumberOfArgs = ArglenConvT!(NumberOfArgsSwitchT!(Tf).type); 145 145 } 146 147 /* NumberOfArgsInout */ 148 template 149 ArgleninoutT(Tr) 150 { 151 Arglen0 152 ArgleninoutT(Tr function() fn) { assert(false); } 153 } 154 155 template 156 ArgleninoutT(Tr, Ta1) 157 { 158 Arglen1 159 ArgleninoutT(Tr function(inout Ta1) fn) { assert(false); } 160 } 161 162 template 163 ArgleninoutT(Tr, Ta1, Ta2) 164 { 165 Arglen2 166 ArgleninoutT(Tr function(inout Ta1, inout Ta2) fn) { assert(false); } 167 } 168 169 template 170 ArgleninoutT(Tr, Ta1, Ta2, Ta3) 171 { 172 Arglen3 173 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3) fn) { assert(false); } 174 } 175 176 template 177 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4) 178 { 179 Arglen4 180 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4) fn) { assert(false); } 181 } 182 183 template 184 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4, Ta5) 185 { 186 Arglen5 187 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4, inout Ta5) fn) { assert(false); } 188 } 189 190 template 191 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4, Ta5, Ta6) 192 { 193 Arglen6 194 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4, inout Ta5, inout Ta6) fn) { assert(false); } 195 } 196 197 template 198 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4, Ta5, Ta6, Ta7) 199 { 200 Arglen7 201 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4, inout Ta5, inout Ta6, inout Ta7) fn) { assert(false); } 202 } 203 204 template 205 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4, Ta5, Ta6, Ta7, Ta8) 206 { 207 Arglen8 208 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4, inout Ta5, inout Ta6, inout Ta7, inout Ta8) fn) { assert(false); } 209 } 210 211 template 212 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4, Ta5, Ta6, Ta7, Ta8, Ta9) 213 { 214 Arglen9 215 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4, inout Ta5, inout Ta6, inout Ta7, inout Ta8, inout Ta9) fn) { assert(false); } 216 } 217 218 template 219 ArgleninoutT(Tr, Ta1, Ta2, Ta3, Ta4, Ta5, Ta6, Ta7, Ta8, Ta9, Ta10) 220 { 221 Arglen10 222 ArgleninoutT(Tr function(inout Ta1, inout Ta2, inout Ta3, inout Ta4, inout Ta5, inout Ta6, inout Ta7, inout Ta8, inout Ta9, inout Ta10) fn) { assert(false); } 223 } 224 225 template 226 NumberOfArgsInoutT(Tf) 227 { 228 private Tf fptr; 229 alias typeof(ArgleninoutT(fptr)) type; 230 } 231 232 template 233 NumberOfArgsSwitchInoutT(Tf) 234 { 235 static if( is( typeof(*Tf) == function ) ) 236 alias NumberOfArgsInoutT!(Tf).type type; 237 else static if( is( Tf U == delegate ) ) 238 alias NumberOfArgsSwitchInoutT!(U*).type type; 239 } 240 241 public 242 template 243 NumberOfArgsInout(Tf) 244 { 245 const uint NumberOfArgsInout = ArglenConvT!(NumberOfArgsSwitchInoutT!(Tf).type); 246 } 247 248 /* ReturnType */ 146 249 147 250 template trunk/infrastructure/pyd/generators/ftype.py
r26 r38 20 20 21 21 # This is the file the module will be output to. 22 OUT_FILE = "ftype. d"22 OUT_FILE = "ftype.txt" 23 23 24 24 # This is the full name of the module. 25 MODULE_PATH = " ftype"25 MODULE_PATH = "pyd.ftype" 26 26 27 27 # … … 40 40 return "Ta%d" % i 41 41 42 def typenameinout(i): 43 if i == 0: 44 return "Tr" 45 else: 46 return "inout Ta%d" % i 47 42 48 def typeargs(n, omit_first=False): 43 49 if omit_first: … … 48 54 return ", ".join(typename(x) for x in xs) 49 55 56 def typeargsinout(n, omit_first=False): 57 if omit_first: 58 xs = range(1,n+1) 59 else: 60 xs = range(n+1) 61 62 return ", ".join(typenameinout(x) for x in xs) 63 50 64 def typefptr(n): 51 65 return "%s function(%s)" % (typename(0), typeargs(n, True)) 66 67 def typefninout(n): 68 return "%s function(%s)" % (typenameinout(0), typeargsinout(n, True)) 52 69 53 70 def typedelegate(n): … … 168 185 169 186 # 187 # NumberOfArgsInout 188 # 189 for i in range(MAX_ARGS+1): 190 print "" 191 print "template" 192 print "ArgleninoutT(%s)" % typeargs(i) 193 print "{" 194 print " Arglen%d" % i 195 print " ArgleninoutT(%s fn) { assert(false); }" % typefninout(i) 196 print "}" 197 198 print """ 199 template 200 NumberOfArgsInoutT(Tf) 201 { 202 private Tf fptr; 203 alias typeof(ArgleninoutT(fptr)) type; 204 }""" 205 206 print """ 207 template 208 NumberOfArgsSwitchInoutT(Tf) 209 { 210 static if( is( typeof(*Tf) == function ) ) 211 alias NumberOfArgsInoutT!(Tf).type type; 212 else static if( is( Tf U == delegate ) ) 213 alias NumberOfArgsSwitchInoutT!(U*).type type; 214 }""" 215 216 print """ 217 public 218 template 219 NumberOfArgsInout(Tf) 220 { 221 const uint NumberOfArgsInout = ArglenConvT!(NumberOfArgsSwitchInoutT!(Tf).type); 222 }""" 223 224 # 170 225 # ReturnType(Tf) 171 226 # trunk/infrastructure/pyd/iteration.d
r37 r38 23 23 /** 24 24 * This module provides the support for wrapping opApply with Python's 25 * iteration interface using Mikola Lysenko's StackThreads module.25 * iteration interface using Mikola Lysenko's StackThreads package. 26 26 */ 27 27 module pyd.iteration; … … 30 30 private import pyd.class_wrap; 31 31 private import pyd.exception; 32 private import pyd.ftype; 32 33 private import pyd.make_object; 33 34 private import st.stackcontext; … … 43 44 } 44 45 46 // Makes a PyTuple and "steals" all of the passed references 47 PyObject* _make_pytuple(PyObject*[] pyobjs ...) { 48 PyObject* temp = PyTuple_New(pyobjs.length); 49 if (temp is null) { 50 foreach (PyObject* o; pyobjs) { 51 Py_DECREF(o); 52 } 53 return null; 54 } 55 foreach (uint i, PyObject* o; pyobjs) { 56 PyTuple_SetItem(temp, i, o); 57 } 58 return temp; 59 } 60 45 61 // Creates an iterator object from an object. 46 62 PyObject* DPySC_FromWrapped(T) (T obj) { 63 // Get the number of args the opApply's delegate argument takes 64 const uint ARGS = NumberOfArgsInout!(ArgType!(typeof(&T.opApply), 1)); 47 65 auto sc = new StackContext(delegate void() { 48 66 T t = obj; 49 foreach (i; t) { 50 StackContext.throwYield(new DPyYield(_py(i))); 67 PyObject* temp; 68 // I seriously doubt I need to support up to ten (10!) arguments to the 69 // opApply delegate, but everything else in Pyd does, so here we go. 70 static if (ARGS == 1) { 71 foreach (i; t) { 72 StackContext.throwYield(new DPyYield(_py(i))); 73 } 74 } else static if (ARGS == 2) { 75 foreach (a0, a1; t) { 76 temp = _make_pytuple(_py(a0), _py(a1)); 77 if (temp is null) StackContext.throwYield(new DPyYield(null)); 78 StackContext.throwYield(new DPyYield(temp)); 79 } 80 } else static if (ARGS == 3) { 81 foreach (a0, a1, a2; t) { 82 temp = _make_pytuple(_py(a0), _py(a1), _py(a2)); 83 if (temp is null) StackContext.throwYield(new DPyYield(null)); 84 StackContext.throwYield(new DPyYield(temp)); 85 } 86 } else static if (ARGS == 4) { 87 foreach (a0, a1, a2, a3; t) { 88 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3)); 89 if (temp is null) StackContext.throwYield(new DPyYield(null)); 90 StackContext.throwYield(new DPyYield(temp)); 91 } 92 } else static if (ARGS == 5) { 93 foreach (a0, a1, a2, a3, a4; t) { 94 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4)); 95 if (temp is null) StackContext.throwYield(new DPyYield(null)); 96 StackContext.throwYield(new DPyYield(temp)); 97 } 98 } else static if (ARGS == 6) { 99 foreach (a0, a1, a2, a3, a4, a5; t) { 100 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5)); 101 if (temp is null) StackContext.throwYield(new DPyYield(null)); 102 StackContext.throwYield(new DPyYield(temp)); 103 } 104 } else static if (ARGS == 7) { 105 foreach (a0, a1, a2, a3, a4, a5, a6; t) { 106 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6)); 107 if (temp is null) StackContext.throwYield(new DPyYield(null)); 108 StackContext.throwYield(new DPyYield(temp)); 109 } 110 } else static if (ARGS == 8) { 111 foreach (a0, a1, a2, a3, a4, a5, a6, a7; t) { 112 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6), _py(a7)); 113 if (temp is null) StackContext.throwYield(new DPyYield(null)); 114 StackContext.throwYield(new DPyYield(temp)); 115 } 116 } else static if (ARGS == 9) { 117 foreach (a0, a1, a2, a3, a4, a5, a6, a7, a8; t) { 118 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6), _py(a7), _py(a8)); 119 if (temp is null) StackContext.throwYield(new DPyYield(null)); 120 StackContext.throwYield(new DPyYield(temp)); 121 } 122 } else static if (ARGS == 10) { 123 foreach (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9; t) { 124 temp = _make_pytuple(_py(a0), _py(a1), _py(a2), _py(a3), _py(a4), _py(a5), _py(a6), _py(a7), _py(a8), _py(a9)); 125 if (temp is null) StackContext.throwYield(new DPyYield(null)); 126 StackContext.throwYield(new DPyYield(temp)); 127 } 51 128 } 52 129 });
