diff dmd/BinExp.d @ 179:cd48cb899aee

Updated to dmd2.040
author korDen
date Sun, 17 Oct 2010 20:56:07 +0400
parents e3afd1303184
children b0d41ff5e0df
line wrap: on
line diff
--- a/dmd/BinExp.d	Sun Oct 17 07:42:00 2010 +0400
+++ b/dmd/BinExp.d	Sun Oct 17 20:56:07 2010 +0400
@@ -787,7 +787,7 @@
 			return e2;
 
 		// Chase down rebinding of out and ref.
-		if (e1.op == TOKvar)
+		if (e1.op == TOKvar) 
 		{
 			VarExp ve = cast(VarExp)e1;
 			VarDeclaration v = ve.var.isVarDeclaration();
@@ -813,12 +813,15 @@
 		// To reduce code complexity of handling dotvar expressions,
 		// extract the aggregate now.
 		Expression aggregate;
-		if (e1.op == TOKdotvar) {
+		if (e1.op == TOKdotvar)
+		{
 			aggregate = (cast(DotVarExp)e1).e1;
 		// Get rid of 'this'.
 			if (aggregate.op == TOKthis && istate.localThis)
 				aggregate = istate.localThis;
 		}
+	    if (e1.op == TOKthis && istate.localThis)
+			e1 = istate.localThis;
 
 		/* Assignment to variable of the form:
 		 *	v = e2
@@ -857,7 +860,8 @@
 				if (e2 is EXP_CANT_INTERPRET)
 					return e2;
 
-				addVarToInterstate(istate, v);
+			    if (istate)
+					addVarToInterstate(istate, v);
 				v.value = e2;
 				e = Cast(type, type, post ? ev : e2);
 			}
@@ -908,16 +912,20 @@
 				 * on the void value - to do that we'd need a VoidExp.
 				 * That's probably a good enhancement idea.
 				 */
-				v.value = v.type.defaultInit(Loc(0));
+			    v.value = v.type.defaultInitLiteral(Loc(0));
 			}
 			Expression vie = v.value;
+			assert(vie !is EXP_CANT_INTERPRET);
 			if (vie.op == TOKvar)
 			{
 				Declaration d = (cast(VarExp)vie).var;
 				vie = getVarExp(e1.loc, istate, d);
 			}
 			if (vie.op != TOKstructliteral)
+			{
+				error("Cannot assign %s=%s in CTFE", v.toChars(), vie.toChars());
 				return EXP_CANT_INTERPRET;
+			}
 			StructLiteralExp se = cast(StructLiteralExp)vie;
 			VarDeclaration vf = (cast(DotVarExp)e1).var.isVarDeclaration();
 			if (!vf)
@@ -1311,10 +1319,7 @@
 				if (v.value.op == TOKarrayliteral)
 					dim = (cast(ArrayLiteralExp)v.value).elements.dim;
 				else if (v.value.op ==TOKstring)
-				{
-					error("String slice assignment is not yet supported in CTFE");
-					return EXP_CANT_INTERPRET;
-				}
+					dim = (cast(StringExp)v.value).len;
 			}
 			else
 			{
@@ -1324,67 +1329,87 @@
 			int upperbound = upper ? cast(int)upper.toInteger() : dim;
 			int lowerbound = lower ? cast(int)lower.toInteger() : 0;
 
-			ArrayLiteralExp existing;
 			if ((cast(int)lowerbound < 0) || (upperbound > dim))
 			{
 				error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound);
 				return EXP_CANT_INTERPRET;
 			}
-			if (upperbound-lowerbound != dim)
+			// Could either be slice assignment (v[] = e[]), 
+			// or block assignment (v[] = val). 
+			// For the former, we check that the lengths match.
+			bool isSliceAssignment = (e2.op == TOKarrayliteral)
+				|| (e2.op == TOKstring);
+			size_t srclen = 0;
+			if (e2.op == TOKarrayliteral)
+				srclen = (cast(ArrayLiteralExp)e2).elements.dim;
+			else if (e2.op == TOKstring)
+				srclen = (cast(StringExp)e2).len;
+			if (isSliceAssignment && srclen != (upperbound - lowerbound))
 			{
-				// Only modifying part of the array. Must create a new array literal.
-				// If the existing array is uninitialized (this can only happen
-				// with static arrays), create it.
-				if (v.value && v.value.op == TOKarrayliteral)
-					existing = cast(ArrayLiteralExp)v.value;
-				else
-				{
-					// this can only happen with static arrays
-					existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim);
-				}
+				error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound);
+				return e;
 			}
-
 			if (e2.op == TOKarrayliteral)
 			{
 				// Static array assignment from literal
 				ArrayLiteralExp ae = cast(ArrayLiteralExp)e2;
-				if (ae.elements.dim != (upperbound - lowerbound))
-				{
-					error("Array length mismatch assigning [0..%d] to [%d..%d]", ae.elements.dim, lowerbound, upperbound);
-					return e;
-				}
 				if (upperbound - lowerbound == dim)
 					v.value = ae;
 				else
 				{
+					ArrayLiteralExp existing;
+					// Only modifying part of the array. Must create a new array literal.
+					// If the existing array is uninitialized (this can only happen
+					// with static arrays), create it.
+					if (v.value && v.value.op == TOKarrayliteral)
+						existing = cast(ArrayLiteralExp)v.value;
+					else // this can only happen with static arrays
+						existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim);
+
 					// value[] = value[0..lower] ~ ae ~ value[upper..$]
 					existing.elements = spliceElements(existing.elements, ae.elements, lowerbound);
 					v.value = existing;
 				}
 				return e2;
 			}
-			else if (t.nextOf().ty == e2.type.ty)
-			{
-				 // Static array block assignment
-				if (upperbound-lowerbound ==dim)
-					v.value = createBlockDuplicatedArrayLiteral(v.type, e2, dim);
-				else
-				{
-					// value[] = value[0..lower] ~ ae ~ value[upper..$]
-					existing.elements = spliceElements(existing.elements, createBlockDuplicatedArrayLiteral(v.type, e2, upperbound-lowerbound).elements, lowerbound);
-					v.value = existing;
-				}
-				return e2;
-			}
 			else if (e2.op == TOKstring)
 			{
 				StringExp se = cast(StringExp)e2;
-				// This is problematic. char[8] should be storing
-				// values as a string literal, not
-				// as an array literal. Then, for static arrays, we
-				// could do modifications
-				// in-place, with a dramatic memory and speed improvement.
-				error("String slice assignment is not yet supported in CTFE");
+				if (upperbound-lowerbound == dim)
+					v.value = e2;		
+				else
+				{
+					if (!v.value)
+						v.value = createBlockDuplicatedStringLiteral(se.type, cast(dchar)se.type.defaultInit(Loc(0)).toInteger(), dim, se.sz);
+					if (v.value.op==TOKstring)
+						v.value = spliceStringExp(cast(StringExp)v.value, se, lowerbound);
+					else
+						error("String slice assignment is not yet supported in CTFE");
+				}
+				return e2;
+			}
+			else if (t.nextOf().ty == e2.type.ty)
+			{
+				// Static array block assignment
+				if (upperbound - lowerbound == dim)
+					v.value = createBlockDuplicatedArrayLiteral(v.type, e2, dim);
+				else
+				{
+					ArrayLiteralExp existing;
+					// Only modifying part of the array. Must create a new array literal.
+					// If the existing array is uninitialized (this can only happen
+					// with static arrays), create it.
+					if (v.value && v.value.op == TOKarrayliteral)
+						existing = cast(ArrayLiteralExp)v.value;
+					else // this can only happen with static arrays
+						existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim);
+					// value[] = value[0..lower] ~ ae ~ value[upper..$]
+					existing.elements = spliceElements(existing.elements, 
+						createBlockDuplicatedArrayLiteral(v.type, e2, upperbound-lowerbound).elements,
+						lowerbound);
+					v.value = existing;
+				}				
+
 				return e2;
 			}
 			else