Wrong lowering for a[b][c]++

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Mar 21 11:29:14 PDT 2012


A question was asked on the d-learn forum about why this throws a
RangeError:

	int[string][int] map;
	map["abc"][20]++;

This is understandable, since the compiler translates the second line to:

	map.opIndex("abc").opIndexUnary!"++"(20);

Since map["abc"] doesn't exist yet, opIndex throws RangeError before we
ever get to the ++.

I'd like to propose the following fix: if a given chained indexing
expression has any operator applied to its final result (either a unary
operator like ++ or --, or an assignment operator like +=), then instead
of translating previous indexes into opIndex, the compiler should map it
to a new operator overload, say opIndexCreate, which creates the
relevant entry with default value if it doesn't exist yet. That is to
say:

	map["abc"][20]++;

should be translated to:

	map.opIndexCreate("abc").opIndexUnary!"++"(20);

where opIndexCreate looks something like:

	Slot opIndexCreate(Key k) {
		Slot *s = findSlot(k);
		if (s is null) {
			s = createNewSlot(k);
		}
		return s;
	}

Similar changes should be made for expressions like a[b][c][d]=100, or
a[b][c][d]+=100.

In other words, if the tail of a chain of indexing operations maps to
opIndexAssign, opIndexUnary, or opIndexOpAssign, then all preceding
opIndex calls should be converted to opIndexCreate instead.

Comments?


T

-- 
One Word to write them all, One Access to find them, One Excel to count them all, And thus to Windows bind them. -- Mike Champion


More information about the Digitalmars-d mailing list