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 std.algorithm.sorting; 22 23 import dmdscript.script; 24 import dmdscript.dobject; 25 import dmdscript.value; 26 import dmdscript.property; 27 28 Dobject getPrototype(Dobject o) 29 { 30 version(all) 31 { 32 return o.internal_prototype; // use internal [[Prototype]] 33 } 34 else 35 { 36 // use "prototype" 37 Value *v; 38 39 v = o.Get(TEXT_prototype); 40 if(!v || v.isPrimitive()) 41 return null; 42 o = v.toObject(); 43 return o; 44 } 45 } 46 47 struct Iterator 48 { 49 Value[] keys; 50 size_t keyindex; 51 Dobject o; 52 Dobject ostart; 53 54 debug 55 { 56 enum uint ITERATOR_VALUE = 0x1992836; 57 uint foo = ITERATOR_VALUE; 58 } 59 60 invariant() 61 { 62 debug assert(foo == ITERATOR_VALUE); 63 } 64 65 void ctor(Dobject o) 66 { 67 debug foo = ITERATOR_VALUE; 68 //writef("Iterator: o = %p, p = %p\n", o, p); 69 ostart = o; 70 this.o = o; 71 keys = o.proptable.table.keys.sort().release; 72 keyindex = 0; 73 } 74 75 Value *next() 76 { 77 Property* p; 78 79 //writef("Iterator::done() p = %p\n", p); 80 81 for(;; keyindex++) 82 { 83 while(keyindex == keys.length) 84 { 85 delete keys; 86 o = getPrototype(o); 87 if(!o) 88 return null; 89 keys = o.proptable.table.keys.sort().release; 90 keyindex = 0; 91 } 92 Value* key = &keys[keyindex]; 93 p = *key in o.proptable.table; 94 if(!p) // if no longer in property table 95 continue; 96 if(p.attributes & DontEnum) 97 continue; 98 else 99 { 100 // ECMA 12.6.3 101 // Do not enumerate those properties in prototypes 102 // that are overridden 103 if(o != ostart) 104 { 105 for(Dobject ot = ostart; ot != o; ot = getPrototype(ot)) 106 { 107 // If property p is in t, don't enumerate 108 if(*key in ot.proptable.table) 109 goto Lcontinue; 110 } 111 } 112 keyindex++; 113 return key; //&p.value; 114 115 Lcontinue: 116 ; 117 } 118 } 119 assert(0); 120 } 121 }