diff dmd/CondExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children a509c8688fbd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/CondExp.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,281 @@
+module dmd.CondExp;
+
+import dmd.BinExp;
+import dmd.Loc;
+import dmd.MATCH;
+import dmd.Expression;
+import dmd.Scope;
+import dmd.InterState;
+import dmd.OutBuffer;
+import dmd.HdrGenState;
+import dmd.Type;
+import dmd.InlineCostState;
+import dmd.InlineDoState;
+import dmd.InlineScanState;
+import dmd.IRState;
+import dmd.TOK;
+import dmd.TY;
+import dmd.WANT;
+import dmd.Global;
+
+import dmd.backend.elem;
+import dmd.backend.Util;
+import dmd.backend.OPER;
+import dmd.backend.mTY;
+import dmd.backend.TYM;
+import dmd.codegen.Util;
+
+class CondExp : BinExp
+{
+    Expression econd;
+
+    this(Loc loc, Expression econd, Expression e1, Expression e2)
+	{
+		super(loc, TOK.TOKquestion, CondExp.sizeof, e1, e2);
+		this.econd = econd;
+	}
+	
+    Expression syntaxCopy()
+	{
+		assert(false);
+	}
+
+    Expression semantic(Scope sc)
+	{
+		Type t1;
+		Type t2;
+		uint cs0;
+		uint cs1;
+
+	version (LOGSEMANTIC) {
+		printf("CondExp.semantic('%s')\n", toChars());
+	}
+		if (type)
+			return this;
+
+		econd = econd.semantic(sc);
+		econd = resolveProperties(sc, econd);
+		econd = econd.checkToPointer();
+		econd = econd.checkToBoolean();
+
+	static if (false) {
+		/* this cannot work right because the types of e1 and e2
+		 * both contribute to the type of the result.
+		 */
+		if (sc.flags & SCOPEstaticif)
+		{
+			/* If in static if, don't evaluate what we don't have to.
+			 */
+			econd = econd.optimize(WANTflags);
+			if (econd.isBool(TRUE))
+			{
+				e1 = e1.semantic(sc);
+				e1 = resolveProperties(sc, e1);
+				return e1;
+			}
+			else if (econd.isBool(FALSE))
+			{
+				e2 = e2.semantic(sc);
+				e2 = resolveProperties(sc, e2);
+				return e2;
+			}
+		}
+	}
+
+		cs0 = sc.callSuper;
+		e1 = e1.semantic(sc);
+		e1 = resolveProperties(sc, e1);
+		cs1 = sc.callSuper;
+		sc.callSuper = cs0;
+		e2 = e2.semantic(sc);
+		e2 = resolveProperties(sc, e2);
+		sc.mergeCallSuper(loc, cs1);
+
+		// If either operand is void, the result is void
+		t1 = e1.type;
+		t2 = e2.type;
+		if (t1.ty == Tvoid || t2.ty == Tvoid)
+			type = Type.tvoid;
+		else if (t1 == t2)
+			type = t1;
+		else
+		{
+			typeCombine(sc);
+			switch (e1.type.toBasetype().ty)
+			{
+				case Tcomplex32:
+				case Tcomplex64:
+				case Tcomplex80:
+					e2 = e2.castTo(sc, e1.type);
+					break;
+				default:
+					break;
+			}
+			switch (e2.type.toBasetype().ty)
+			{
+				case Tcomplex32:
+				case Tcomplex64:
+				case Tcomplex80:
+					e1 = e1.castTo(sc, e2.type);
+					break;
+				default:
+					break;
+			}
+			if (type.toBasetype().ty == Tarray)
+			{
+				e1 = e1.castTo(sc, type);
+				e2 = e2.castTo(sc, type);
+			}
+		}
+	static if (false) {
+		printf("res: %s\n", type.toChars());
+		printf("e1 : %s\n", e1.type.toChars());
+		printf("e2 : %s\n", e2.type.toChars());
+	}
+		return this;
+	}
+
+    Expression optimize(int result)
+	{
+		Expression e;
+
+		econd = econd.optimize(WANTflags | (result & WANTinterpret));
+		if (econd.isBool(true))
+			e = e1.optimize(result);
+		else if (econd.isBool(false))
+			e = e2.optimize(result);
+		else
+		{	
+			e1 = e1.optimize(result);
+			e2 = e2.optimize(result);
+			e = this;
+		}
+
+		return e;
+	}
+	
+    Expression interpret(InterState istate)
+	{
+		assert(false);
+	}
+
+    void checkEscape()
+	{
+		e1.checkEscape();
+		e2.checkEscape();
+	}
+
+    int isLvalue()
+	{
+		assert(false);
+	}
+
+    Expression toLvalue(Scope sc, Expression e)
+	{
+		assert(false);
+	}
+
+    Expression modifiableLvalue(Scope sc, Expression e)
+	{
+		assert(false);
+	}
+
+    Expression checkToBoolean()
+	{
+		assert(false);
+	}
+
+    bool checkSideEffect(int flag)
+	{
+		assert(false);
+	}
+
+    void toCBuffer(OutBuffer buf, HdrGenState* hgs)
+	{
+		assert(false);
+	}
+
+    MATCH implicitConvTo(Type t)
+	{
+		MATCH m1 = e1.implicitConvTo(t);
+		MATCH m2 = e2.implicitConvTo(t);
+		//printf("CondExp: m1 %d m2 %d\n", m1, m2);
+
+		// Pick the worst match
+		return (m1 < m2) ? m1 : m2;
+	}
+
+    Expression castTo(Scope sc, Type t)
+	{
+		Expression e = this;
+
+		if (type !is t)
+		{
+			if (1 || e1.op == TOKstring || e2.op == TOKstring)
+			{   
+				e = new CondExp(loc, econd, e1.castTo(sc, t), e2.castTo(sc, t));
+				e.type = t;
+			}
+			else
+				e = Expression.castTo(sc, t);
+		}
+		return e;
+	}
+
+    void scanForNestedRef(Scope sc)
+	{
+		assert(false);
+	}
+
+    bool canThrow()
+	{
+		return econd.canThrow() || e1.canThrow() || e2.canThrow();
+	}
+
+    int inlineCost(InlineCostState* ics)
+	{
+		return 1 + e1.inlineCost(ics) + e2.inlineCost(ics) + econd.inlineCost(ics);
+	}
+	
+    Expression doInline(InlineDoState ids)
+	{
+		CondExp ce = cast(CondExp)copy();
+
+		ce.econd = econd.doInline(ids);
+		ce.e1 = e1.doInline(ids);
+		ce.e2 = e2.doInline(ids);
+		return ce;
+	}
+	
+    Expression inlineScan(InlineScanState* iss)
+	{
+		econd = econd.inlineScan(iss);
+		e1 = e1.inlineScan(iss);
+		e2 = e2.inlineScan(iss);
+		return this;
+	}
+
+    elem* toElem(IRState* irs)
+	{
+		elem* eleft;
+		elem* eright;
+
+		elem* ec = econd.toElem(irs);
+
+		eleft = e1.toElem(irs);
+		tym_t ty = eleft.Ety;
+		if (global.params.cov && e1.loc.linnum)
+			eleft = el_combine(incUsageElem(irs, e1.loc), eleft);
+
+		eright = e2.toElem(irs);
+		if (global.params.cov && e2.loc.linnum)
+			eright = el_combine(incUsageElem(irs, e2.loc), eright);
+
+		elem* e = el_bin(OPcond, ty, ec, el_bin(OPcolon, ty, eleft, eright));
+		if (tybasic(ty) == TYstruct)
+			e.Enumbytes = cast(uint)e1.type.size();
+
+		el_setLoc(e, loc);
+		return e;
+	}
+}
\ No newline at end of file