view dmd/AssocArrayLiteralExp.d @ 63:cab4c37afb89

A bunch of implementations
author korDen
date Mon, 23 Aug 2010 16:52:24 +0400
parents 460959608115
children 4290d870944a
line wrap: on
line source

module dmd.AssocArrayLiteralExp;

import dmd.Expression;
import dmd.backend.elem;
import dmd.InterState;
import dmd.MATCH;
import dmd.Type;
import dmd.TypeAArray;
import dmd.OutBuffer;
import dmd.Loc;
import dmd.Scope;
import dmd.InlineCostState;
import dmd.IRState;
import dmd.InlineDoState;
import dmd.HdrGenState;
import dmd.InlineScanState;
import dmd.ArrayTypes;
import dmd.TOK;
import dmd.PREC;
import dmd.expression.Util;

class AssocArrayLiteralExp : Expression
{
	Expressions keys;
	Expressions values;

	this(Loc loc, Expressions keys, Expressions values)
	{
		super(loc, TOK.TOKassocarrayliteral, this.sizeof);
		assert(keys.dim == values.dim);
		this.keys = keys;
		this.values = values;	
	}

	Expression syntaxCopy()
	{
		return new AssocArrayLiteralExp(loc,
				arraySyntaxCopy(keys), arraySyntaxCopy(values));
	}

	Expression semantic(Scope sc)
	{
		Expression e;
		Type tkey = null;
		Type tvalue = null;

		version (LOGSEMANTIC) {
			printf("AssocArrayLiteralExp.semantic('%s')\n", toChars());
		}

		// Run semantic() on each element
		for (size_t i = 0; i < keys.dim; i++)
		{	Expression key = cast(Expression)keys.data[i];
			Expression value = cast(Expression)values.data[i];

			key = key.semantic(sc);
			value = value.semantic(sc);

			keys.data[i] = cast(void *)key;
			values.data[i] = cast(void *)value;
		}
		expandTuples(keys);
		expandTuples(values);
		if (keys.dim != values.dim)
		{
			error("number of keys is %u, must match number of values %u", keys.dim, values.dim);
			keys.setDim(0);
			values.setDim(0);
		}
		for (size_t i = 0; i < keys.dim; i++)
		{	Expression key = cast(Expression)keys.data[i];
			Expression value = cast(Expression)values.data[i];

			if (!key.type)
				error("%s has no value", key.toChars());
			if (!value.type)
				error("%s has no value", value.toChars());
			key = resolveProperties(sc, key);
			value = resolveProperties(sc, value);

			if (!tkey)
				tkey = key.type;
			else
				key = key.implicitCastTo(sc, tkey);
			keys.data[i] = cast(void *)key;

			if (!tvalue)
				tvalue = value.type;
			else
				value = value.implicitCastTo(sc, tvalue);
			values.data[i] = cast(void *)value;
		}

		if (!tkey)
			tkey = Type.tvoid;
		if (!tvalue)
			tvalue = Type.tvoid;
		type = new TypeAArray(tvalue, tkey);
		type = type.semantic(loc, sc);
		return this;
	}

	bool isBool(bool result)
	{
		size_t dim = keys.dim;
		return result ? (dim != 0) : (dim == 0);
	}

	elem* toElem(IRState* irs)
	{
		assert(false);
	}

	bool checkSideEffect(int flag)
	{
		bool f = false;

		for (size_t i = 0; i < keys.dim; i++)
		{	Expression key = cast(Expression)keys.data[i];
			Expression value = cast(Expression)values.data[i];

			f |= key.checkSideEffect(2);
			f |= value.checkSideEffect(2);
		}
		if (flag == 0 && f == 0)
			Expression.checkSideEffect(0);
		return f;
	}

	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
	{
		buf.writeByte('[');
		for (size_t i = 0; i < keys.dim; i++)
		{	Expression key = cast(Expression)keys.data[i];
			Expression value = cast(Expression)values.data[i];

			if (i)
				buf.writeByte(',');
			expToCBuffer(buf, hgs, key, PREC.PREC_assign);
			buf.writeByte(':');
			expToCBuffer(buf, hgs, value, PREC.PREC_assign);
		}
		buf.writeByte(']');
	}

	void toMangleBuffer(OutBuffer buf)
	{
		size_t dim = keys.dim;
		buf.printf("A%u", dim);
		for (size_t i = 0; i < dim; i++)
		{	Expression key = cast(Expression)keys.data[i];
			Expression value = cast(Expression)values.data[i];

			key.toMangleBuffer(buf);
			value.toMangleBuffer(buf);
		}
	}

	void scanForNestedRef(Scope sc)
	{
		assert(false);
	}

	Expression optimize(int result)
	{
		assert(false);
	}

	Expression interpret(InterState istate)
	{
		assert(false);
	}

	MATCH implicitConvTo(Type t)
	{
		assert(false);
	}

	Expression castTo(Scope sc, Type t)
	{
		assert(false);
	}

	bool canThrow()
	{
		return true;
	}

	int inlineCost(InlineCostState* ics)
	{
		assert(false);
	}

	Expression doInline(InlineDoState ids)
	{
		assert(false);
	}

	Expression inlineScan(InlineScanState* iss)
	{
		assert(false);
	}
}