0
|
1
|
|
2 /* Digital Mars DMDScript source code.
|
|
3 * Copyright (c) 2000-2002 by Chromium Communications
|
|
4 * D version Copyright (c) 2004-2005 by Digital Mars
|
|
5 * All Rights Reserved
|
|
6 * written by Walter Bright
|
|
7 * www.digitalmars.com
|
|
8 * Use at your own risk. There is no warranty, express or implied.
|
|
9 * License for redistribution is by the GNU General Public License in gpl.txt.
|
|
10 *
|
|
11 * A binary, non-exclusive license for commercial use can be
|
|
12 * purchased from www.digitalmars.com/dscript/buy.html.
|
|
13 *
|
|
14 * DMDScript is implemented in the D Programming Language,
|
|
15 * www.digitalmars.com/d/
|
|
16 *
|
|
17 * For a C++ implementation of DMDScript, including COM support,
|
|
18 * see www.digitalmars.com/dscript/cppscript.html.
|
|
19 */
|
|
20
|
|
21
|
3
|
22 module dmdscript_tango.iterator;
|
0
|
23
|
3
|
24 import dmdscript_tango.script;
|
|
25 import dmdscript_tango.dobject;
|
|
26 import dmdscript_tango.value;
|
|
27 import dmdscript_tango.property;
|
0
|
28
|
|
29 Dobject getPrototype(Dobject o)
|
|
30 {
|
|
31 version (all)
|
|
32 {
|
|
33 return o.internal_prototype; // use internal [[Prototype]]
|
|
34 }
|
|
35 else
|
|
36 {
|
|
37 // use "prototype"
|
|
38 Value *v;
|
|
39
|
|
40 v = o.Get(TEXT_prototype);
|
|
41 if (!v || v.isPrimitive())
|
|
42 return null;
|
|
43 o = v.toObject();
|
|
44 return o;
|
|
45 }
|
|
46 }
|
|
47
|
|
48 struct Iterator
|
|
49 {
|
|
50 Value[] keys;
|
|
51 size_t keyindex;
|
|
52 Dobject o;
|
|
53 Dobject ostart;
|
|
54
|
|
55 debug
|
|
56 {
|
|
57 const uint ITERATOR_VALUE = 0x1992836;
|
|
58 uint foo = ITERATOR_VALUE;
|
|
59 }
|
|
60
|
|
61 invariant
|
|
62 {
|
|
63 debug assert(foo == ITERATOR_VALUE);
|
|
64 }
|
|
65
|
|
66 void ctor(Dobject o)
|
|
67 {
|
|
68 debug foo = ITERATOR_VALUE;
|
|
69 //writef("Iterator: o = %p, p = %p\n", o, p);
|
|
70 ostart = o;
|
|
71 this.o = o;
|
|
72 keys = o.proptable.table.keys.sort;
|
|
73 keyindex = 0;
|
|
74 }
|
|
75
|
|
76 Value *next()
|
|
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;
|
|
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 }
|