view dmdscript_tango/iterator.d @ 3:8363a4bf6a8f

rename package: dmdscript to dmdscript_tango
author saaadel
date Sun, 24 Jan 2010 18:33:05 +0200
parents 55c2951c07be
children
line wrap: on
line source


/* Digital Mars DMDScript source code.
 * Copyright (c) 2000-2002 by Chromium Communications
 * D version Copyright (c) 2004-2005 by Digital Mars
 * All Rights Reserved
 * written by Walter Bright
 * www.digitalmars.com
 * Use at your own risk. There is no warranty, express or implied.
 * License for redistribution is by the GNU General Public License in gpl.txt.
 *
 * A binary, non-exclusive license for commercial use can be
 * purchased from www.digitalmars.com/dscript/buy.html.
 *
 * DMDScript is implemented in the D Programming Language,
 * www.digitalmars.com/d/
 *
 * For a C++ implementation of DMDScript, including COM support,
 * see www.digitalmars.com/dscript/cppscript.html.
 */


module dmdscript_tango.iterator;

import dmdscript_tango.script;
import dmdscript_tango.dobject;
import dmdscript_tango.value;
import dmdscript_tango.property;

Dobject getPrototype(Dobject o)
{
    version (all)
    {
	return o.internal_prototype;	// use internal [[Prototype]]
    }
    else
    {
	// use "prototype"
	Value *v;

	v = o.Get(TEXT_prototype);
	if (!v || v.isPrimitive())
	    return null;
	o = v.toObject();
	return o;
    }
}

struct Iterator
{
    Value[] keys;
    size_t keyindex;
    Dobject o;
    Dobject ostart;

    debug
    {
	const uint ITERATOR_VALUE = 0x1992836;
	uint foo = ITERATOR_VALUE;
    }

    invariant
    {
	debug assert(foo == ITERATOR_VALUE);
    }

    void ctor(Dobject o)
    {
	debug foo = ITERATOR_VALUE;
	//writef("Iterator: o = %p, p = %p\n", o, p);
	ostart = o;
	this.o = o;
	keys = o.proptable.table.keys.sort;
	keyindex = 0;
    }

    Value *next()
    {	Property* p;

	//writef("Iterator::done() p = %p\n", p);

	for (; ; keyindex++)
	{
	    while (keyindex == keys.length)
	    {
		delete keys;
		o = getPrototype(o);
		if (!o)
		    return null;
		keys = o.proptable.table.keys.sort;
		keyindex = 0;
	    }
	    Value* key = &keys[keyindex];
	    p = *key in o.proptable.table;
	    if (!p)			// if no longer in property table
		continue;
	    if (p.attributes & DontEnum)
		continue;
	    else
	    {
		// ECMA 12.6.3
		// Do not enumerate those properties in prototypes
		// that are overridden
		if (o != ostart)
		{
		    for (Dobject ot = ostart; ot != o; ot = getPrototype(ot))
		    {
			// If property p is in t, don't enumerate
			if (*key in ot.proptable.table)
			    goto Lcontinue;
		    }
		}
		keyindex++;
		return key; //&p.value;

	    Lcontinue:
		;
	    }
	}
	assert(0);
    }
}