Mercurial > projects > ddmd
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