diff dmd/AddAssignExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 832f71e6f96c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmd/AddAssignExp.d	Sat Oct 24 08:42:06 2009 +0400
@@ -0,0 +1,175 @@
+module dmd.AddAssignExp;
+
+import dmd.BinExp;
+import dmd.Loc;
+import dmd.Expression;
+import dmd.Scope;
+import dmd.InterState;
+import dmd.OutBuffer;
+import dmd.ArrayTypes;
+import dmd.Identifier;
+import dmd.IRState;
+import dmd.TOK;
+import dmd.Type;
+import dmd.TY;
+import dmd.AddExp;
+import dmd.CastExp;
+import dmd.AssignExp;
+import dmd.Global;
+import dmd.Id;
+
+import dmd.backend.OPER;
+import dmd.backend.elem;
+
+class AddAssignExp : BinExp
+{
+    this(Loc loc, Expression e1, Expression e2)
+	{
+		super(loc, TOK.TOKaddass, AddAssignExp.sizeof, e1, e2);
+	}
+	
+    Expression semantic(Scope sc)
+	{
+		Expression e;
+
+		if (type)
+			return this;
+
+		BinExp.semantic(sc);
+		e2 = resolveProperties(sc, e2);
+
+		e = op_overload(sc);
+		if (e)
+			return e;
+
+		Type tb1 = e1.type.toBasetype();
+		Type tb2 = e2.type.toBasetype();
+
+		if (e1.op == TOK.TOKslice)
+		{
+			typeCombine(sc);
+			type = e1.type;
+			return arrayOp(sc);
+		}
+		else
+		{
+			e1 = e1.modifiableLvalue(sc, e1);
+		}
+
+		if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray) && tb1.nextOf().equals(tb2.nextOf()))
+		{
+			type = e1.type;
+			typeCombine(sc);
+			e = this;
+		}
+		else
+		{
+			e1.checkScalar();
+			e1.checkNoBool();
+			if (tb1.ty == TY.Tpointer && tb2.isintegral())
+				e = scaleFactor(sc);
+			else if (tb1.ty == TY.Tbit || tb1.ty == TY.Tbool)
+			{
+static if (false) {
+				// Need to rethink this
+				if (e1.op != TOK.TOKvar)
+				{   
+					// Rewrite e1+=e2 to (v=&e1),*v=*v+e2
+					VarDeclaration v;
+					Expression ea;
+					Expression ex;
+
+					Identifier id = Lexer.uniqueId("__name");
+
+					v = new VarDeclaration(loc, tb1.pointerTo(), id, null);
+					v.semantic(sc);
+					if (!sc.insert(v))
+						assert(0);
+
+					v.parent = sc.func;
+
+					ea = new AddrExp(loc, e1);
+					ea = new AssignExp(loc, new VarExp(loc, v), ea);
+
+					ex = new VarExp(loc, v);
+					ex = new PtrExp(loc, ex);
+					e = new AddExp(loc, ex, e2);
+					e = new CastExp(loc, e, e1.type);
+					e = new AssignExp(loc, ex.syntaxCopy(), e);
+
+					e = new CommaExp(loc, ea, e);
+				}
+				else
+				{
+					// Rewrite e1+=e2 to e1=e1+e2
+					// BUG: doesn't account for side effects in e1
+					// BUG: other assignment operators for bits aren't handled at all
+					e = new AddExp(loc, e1, e2);
+					e = new CastExp(loc, e, e1.type);
+					e = new AssignExp(loc, e1.syntaxCopy(), e);
+				}
+} else {
+				// Rewrite e1+=e2 to e1=e1+e2
+				// BUG: doesn't account for side effects in e1
+				// BUG: other assignment operators for bits aren't handled at all
+				e = new AddExp(loc, e1, e2);
+				e = new CastExp(loc, e, e1.type);
+				e = new AssignExp(loc, e1.syntaxCopy(), e);
+}
+				e = e.semantic(sc);
+			}
+			else
+			{
+				type = e1.type;
+				typeCombine(sc);
+				e1.checkArithmetic();
+				e2.checkArithmetic();
+
+				if (type.isreal() || type.isimaginary())
+				{
+					assert(global.errors || e2.type.isfloating());
+					e2 = e2.castTo(sc, e1.type);
+				}
+				e = this;
+			}
+		}
+		return e;
+	}
+	
+    Expression interpret(InterState* istate)
+	{
+		assert(false);
+	}
+	
+    void buildArrayIdent(OutBuffer buf, Expressions arguments)
+	{
+		assert(false);
+	}
+	
+    Expression buildArrayLoop(Arguments fparams)
+	{
+		assert(false);
+	}
+
+    Identifier opId()    /* For operator overloading */
+	{
+		return Id.addass;
+	}
+
+    elem* toElem(IRState* irs)
+	{
+		//printf("AddAssignExp::toElem() %s\n", toChars());
+		elem *e;
+		Type tb1 = e1.type.toBasetype();
+		Type tb2 = e2.type.toBasetype();
+
+		if ((tb1.ty == TY.Tarray || tb1.ty == TY.Tsarray) && (tb2.ty == TY.Tarray || tb2.ty == TY.Tsarray))
+		{
+			error("Array operations not implemented");
+		}
+		else
+			e = toElemBin(irs, OPER.OPaddass);
+
+		return e;
+	}
+}
\ No newline at end of file