1 /* Digital Mars DMDScript source code. 2 * Copyright (c) 2000-2002 by Chromium Communications 3 * D version Copyright (c) 2004-2010 by Digital Mars 4 * Distributed under the Boost Software License, Version 1.0. 5 * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 * written by Walter Bright 7 * http://www.digitalmars.com 8 * 9 * D2 port by Dmitry Olshansky 10 * 11 * DMDScript is implemented in the D Programming Language, 12 * http://www.digitalmars.com/d/ 13 * 14 * For a C++ implementation of DMDScript, including COM support, see 15 * http://www.digitalmars.com/dscript/cppscript.html 16 */ 17 18 19 module dmdscript.iterator; 20 21 import dmdscript.script; 22 import dmdscript.dobject; 23 import dmdscript.value; 24 import dmdscript.property; 25 26 Dobject getPrototype(Dobject o) 27 { 28 version(all) 29 { 30 return o.internal_prototype; // use internal [[Prototype]] 31 } 32 else 33 { 34 // use "prototype" 35 Value *v; 36 37 v = o.Get(TEXT_prototype); 38 if(!v || v.isPrimitive()) 39 return null; 40 o = v.toObject(); 41 return o; 42 } 43 } 44 45 struct Iterator 46 { 47 Value[] keys; 48 size_t keyindex; 49 Dobject o; 50 Dobject ostart; 51 52 debug 53 { 54 enum uint ITERATOR_VALUE = 0x1992836; 55 uint foo = ITERATOR_VALUE; 56 } 57 58 invariant() 59 { 60 debug assert(foo == ITERATOR_VALUE); 61 } 62 63 void ctor(Dobject o) 64 { 65 debug foo = ITERATOR_VALUE; 66 //writef("Iterator: o = %p, p = %p\n", o, p); 67 ostart = o; 68 this.o = o; 69 keys = o.proptable.table.keys.sort; 70 keyindex = 0; 71 } 72 73 Value *next() 74 { 75 Property* p; 76 77 //writef("Iterator::done() p = %p\n", p); 78 79 for(;; keyindex++) 80 { 81 while(keyindex == keys.length) 82 { 83 delete keys; 84 o = getPrototype(o); 85 if(!o) 86 return null; 87 keys = o.proptable.table.keys.sort; 88 keyindex = 0; 89 } 90 Value* key = &keys[keyindex]; 91 p = *key in o.proptable.table; 92 if(!p) // if no longer in property table 93 continue; 94 if(p.attributes & DontEnum) 95 continue; 96 else 97 { 98 // ECMA 12.6.3 99 // Do not enumerate those properties in prototypes 100 // that are overridden 101 if(o != ostart) 102 { 103 for(Dobject ot = ostart; ot != o; ot = getPrototype(ot)) 104 { 105 // If property p is in t, don't enumerate 106 if(*key in ot.proptable.table) 107 goto Lcontinue; 108 } 109 } 110 keyindex++; 111 return key; //&p.value; 112 113 Lcontinue: 114 ; 115 } 116 } 117 assert(0); 118 } 119 }