comparison dmd/BinExp.d @ 179:cd48cb899aee

Updated to dmd2.040
author korDen
date Sun, 17 Oct 2010 20:56:07 +0400
parents e3afd1303184
children b0d41ff5e0df
comparison
equal deleted inserted replaced
178:e3afd1303184 179:cd48cb899aee
785 Expression e2 = this.e2.interpret(istate); 785 Expression e2 = this.e2.interpret(istate);
786 if (e2 is EXP_CANT_INTERPRET) 786 if (e2 is EXP_CANT_INTERPRET)
787 return e2; 787 return e2;
788 788
789 // Chase down rebinding of out and ref. 789 // Chase down rebinding of out and ref.
790 if (e1.op == TOKvar) 790 if (e1.op == TOKvar)
791 { 791 {
792 VarExp ve = cast(VarExp)e1; 792 VarExp ve = cast(VarExp)e1;
793 VarDeclaration v = ve.var.isVarDeclaration(); 793 VarDeclaration v = ve.var.isVarDeclaration();
794 if (v && v.value && v.value.op == TOKvar) 794 if (v && v.value && v.value.op == TOKvar)
795 { 795 {
811 } 811 }
812 812
813 // To reduce code complexity of handling dotvar expressions, 813 // To reduce code complexity of handling dotvar expressions,
814 // extract the aggregate now. 814 // extract the aggregate now.
815 Expression aggregate; 815 Expression aggregate;
816 if (e1.op == TOKdotvar) { 816 if (e1.op == TOKdotvar)
817 {
817 aggregate = (cast(DotVarExp)e1).e1; 818 aggregate = (cast(DotVarExp)e1).e1;
818 // Get rid of 'this'. 819 // Get rid of 'this'.
819 if (aggregate.op == TOKthis && istate.localThis) 820 if (aggregate.op == TOKthis && istate.localThis)
820 aggregate = istate.localThis; 821 aggregate = istate.localThis;
821 } 822 }
823 if (e1.op == TOKthis && istate.localThis)
824 e1 = istate.localThis;
822 825
823 /* Assignment to variable of the form: 826 /* Assignment to variable of the form:
824 * v = e2 827 * v = e2
825 */ 828 */
826 if (e1.op == TOKvar) 829 if (e1.op == TOKvar)
855 e2 = Cast(v.type, v.type, e2); 858 e2 = Cast(v.type, v.type, e2);
856 } 859 }
857 if (e2 is EXP_CANT_INTERPRET) 860 if (e2 is EXP_CANT_INTERPRET)
858 return e2; 861 return e2;
859 862
860 addVarToInterstate(istate, v); 863 if (istate)
864 addVarToInterstate(istate, v);
861 v.value = e2; 865 v.value = e2;
862 e = Cast(type, type, post ? ev : e2); 866 e = Cast(type, type, post ? ev : e2);
863 } 867 }
864 } 868 }
865 else if (e1.op == TOKdotvar && aggregate.op == TOKdotvar) 869 else if (e1.op == TOKdotvar && aggregate.op == TOKdotvar)
906 * values, it is valid here to use the default initializer. 910 * values, it is valid here to use the default initializer.
907 * No attempt is made to determine if someone actually relies 911 * No attempt is made to determine if someone actually relies
908 * on the void value - to do that we'd need a VoidExp. 912 * on the void value - to do that we'd need a VoidExp.
909 * That's probably a good enhancement idea. 913 * That's probably a good enhancement idea.
910 */ 914 */
911 v.value = v.type.defaultInit(Loc(0)); 915 v.value = v.type.defaultInitLiteral(Loc(0));
912 } 916 }
913 Expression vie = v.value; 917 Expression vie = v.value;
918 assert(vie !is EXP_CANT_INTERPRET);
914 if (vie.op == TOKvar) 919 if (vie.op == TOKvar)
915 { 920 {
916 Declaration d = (cast(VarExp)vie).var; 921 Declaration d = (cast(VarExp)vie).var;
917 vie = getVarExp(e1.loc, istate, d); 922 vie = getVarExp(e1.loc, istate, d);
918 } 923 }
919 if (vie.op != TOKstructliteral) 924 if (vie.op != TOKstructliteral)
920 return EXP_CANT_INTERPRET; 925 {
926 error("Cannot assign %s=%s in CTFE", v.toChars(), vie.toChars());
927 return EXP_CANT_INTERPRET;
928 }
921 StructLiteralExp se = cast(StructLiteralExp)vie; 929 StructLiteralExp se = cast(StructLiteralExp)vie;
922 VarDeclaration vf = (cast(DotVarExp)e1).var.isVarDeclaration(); 930 VarDeclaration vf = (cast(DotVarExp)e1).var.isVarDeclaration();
923 if (!vf) 931 if (!vf)
924 return EXP_CANT_INTERPRET; 932 return EXP_CANT_INTERPRET;
925 int fieldi = se.getFieldIndex(type, vf.offset); 933 int fieldi = se.getFieldIndex(type, vf.offset);
1309 return EXP_CANT_INTERPRET; 1317 return EXP_CANT_INTERPRET;
1310 } 1318 }
1311 if (v.value.op == TOKarrayliteral) 1319 if (v.value.op == TOKarrayliteral)
1312 dim = (cast(ArrayLiteralExp)v.value).elements.dim; 1320 dim = (cast(ArrayLiteralExp)v.value).elements.dim;
1313 else if (v.value.op ==TOKstring) 1321 else if (v.value.op ==TOKstring)
1314 { 1322 dim = (cast(StringExp)v.value).len;
1315 error("String slice assignment is not yet supported in CTFE");
1316 return EXP_CANT_INTERPRET;
1317 }
1318 } 1323 }
1319 else 1324 else
1320 { 1325 {
1321 error("%s cannot be evaluated at compile time", toChars()); 1326 error("%s cannot be evaluated at compile time", toChars());
1322 return EXP_CANT_INTERPRET; 1327 return EXP_CANT_INTERPRET;
1323 } 1328 }
1324 int upperbound = upper ? cast(int)upper.toInteger() : dim; 1329 int upperbound = upper ? cast(int)upper.toInteger() : dim;
1325 int lowerbound = lower ? cast(int)lower.toInteger() : 0; 1330 int lowerbound = lower ? cast(int)lower.toInteger() : 0;
1326 1331
1327 ArrayLiteralExp existing;
1328 if ((cast(int)lowerbound < 0) || (upperbound > dim)) 1332 if ((cast(int)lowerbound < 0) || (upperbound > dim))
1329 { 1333 {
1330 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound); 1334 error("Array bounds [0..%d] exceeded in slice [%d..%d]", dim, lowerbound, upperbound);
1331 return EXP_CANT_INTERPRET; 1335 return EXP_CANT_INTERPRET;
1332 } 1336 }
1333 if (upperbound-lowerbound != dim) 1337 // Could either be slice assignment (v[] = e[]),
1334 { 1338 // or block assignment (v[] = val).
1335 // Only modifying part of the array. Must create a new array literal. 1339 // For the former, we check that the lengths match.
1336 // If the existing array is uninitialized (this can only happen 1340 bool isSliceAssignment = (e2.op == TOKarrayliteral)
1337 // with static arrays), create it. 1341 || (e2.op == TOKstring);
1338 if (v.value && v.value.op == TOKarrayliteral) 1342 size_t srclen = 0;
1339 existing = cast(ArrayLiteralExp)v.value; 1343 if (e2.op == TOKarrayliteral)
1340 else 1344 srclen = (cast(ArrayLiteralExp)e2).elements.dim;
1341 { 1345 else if (e2.op == TOKstring)
1342 // this can only happen with static arrays 1346 srclen = (cast(StringExp)e2).len;
1343 existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim); 1347 if (isSliceAssignment && srclen != (upperbound - lowerbound))
1344 } 1348 {
1345 } 1349 error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound);
1346 1350 return e;
1351 }
1347 if (e2.op == TOKarrayliteral) 1352 if (e2.op == TOKarrayliteral)
1348 { 1353 {
1349 // Static array assignment from literal 1354 // Static array assignment from literal
1350 ArrayLiteralExp ae = cast(ArrayLiteralExp)e2; 1355 ArrayLiteralExp ae = cast(ArrayLiteralExp)e2;
1351 if (ae.elements.dim != (upperbound - lowerbound))
1352 {
1353 error("Array length mismatch assigning [0..%d] to [%d..%d]", ae.elements.dim, lowerbound, upperbound);
1354 return e;
1355 }
1356 if (upperbound - lowerbound == dim) 1356 if (upperbound - lowerbound == dim)
1357 v.value = ae; 1357 v.value = ae;
1358 else 1358 else
1359 { 1359 {
1360 ArrayLiteralExp existing;
1361 // Only modifying part of the array. Must create a new array literal.
1362 // If the existing array is uninitialized (this can only happen
1363 // with static arrays), create it.
1364 if (v.value && v.value.op == TOKarrayliteral)
1365 existing = cast(ArrayLiteralExp)v.value;
1366 else // this can only happen with static arrays
1367 existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim);
1368
1360 // value[] = value[0..lower] ~ ae ~ value[upper..$] 1369 // value[] = value[0..lower] ~ ae ~ value[upper..$]
1361 existing.elements = spliceElements(existing.elements, ae.elements, lowerbound); 1370 existing.elements = spliceElements(existing.elements, ae.elements, lowerbound);
1362 v.value = existing; 1371 v.value = existing;
1363 } 1372 }
1364 return e2; 1373 return e2;
1365 } 1374 }
1375 else if (e2.op == TOKstring)
1376 {
1377 StringExp se = cast(StringExp)e2;
1378 if (upperbound-lowerbound == dim)
1379 v.value = e2;
1380 else
1381 {
1382 if (!v.value)
1383 v.value = createBlockDuplicatedStringLiteral(se.type, cast(dchar)se.type.defaultInit(Loc(0)).toInteger(), dim, se.sz);
1384 if (v.value.op==TOKstring)
1385 v.value = spliceStringExp(cast(StringExp)v.value, se, lowerbound);
1386 else
1387 error("String slice assignment is not yet supported in CTFE");
1388 }
1389 return e2;
1390 }
1366 else if (t.nextOf().ty == e2.type.ty) 1391 else if (t.nextOf().ty == e2.type.ty)
1367 { 1392 {
1368 // Static array block assignment 1393 // Static array block assignment
1369 if (upperbound-lowerbound ==dim) 1394 if (upperbound - lowerbound == dim)
1370 v.value = createBlockDuplicatedArrayLiteral(v.type, e2, dim); 1395 v.value = createBlockDuplicatedArrayLiteral(v.type, e2, dim);
1371 else 1396 else
1372 { 1397 {
1398 ArrayLiteralExp existing;
1399 // Only modifying part of the array. Must create a new array literal.
1400 // If the existing array is uninitialized (this can only happen
1401 // with static arrays), create it.
1402 if (v.value && v.value.op == TOKarrayliteral)
1403 existing = cast(ArrayLiteralExp)v.value;
1404 else // this can only happen with static arrays
1405 existing = createBlockDuplicatedArrayLiteral(v.type, v.type.defaultInit(Loc(0)), dim);
1373 // value[] = value[0..lower] ~ ae ~ value[upper..$] 1406 // value[] = value[0..lower] ~ ae ~ value[upper..$]
1374 existing.elements = spliceElements(existing.elements, createBlockDuplicatedArrayLiteral(v.type, e2, upperbound-lowerbound).elements, lowerbound); 1407 existing.elements = spliceElements(existing.elements,
1408 createBlockDuplicatedArrayLiteral(v.type, e2, upperbound-lowerbound).elements,
1409 lowerbound);
1375 v.value = existing; 1410 v.value = existing;
1376 } 1411 }
1377 return e2; 1412
1378 }
1379 else if (e2.op == TOKstring)
1380 {
1381 StringExp se = cast(StringExp)e2;
1382 // This is problematic. char[8] should be storing
1383 // values as a string literal, not
1384 // as an array literal. Then, for static arrays, we
1385 // could do modifications
1386 // in-place, with a dramatic memory and speed improvement.
1387 error("String slice assignment is not yet supported in CTFE");
1388 return e2; 1413 return e2;
1389 } 1414 }
1390 else 1415 else
1391 { 1416 {
1392 error("Slice operation %s cannot be evaluated at compile time", toChars()); 1417 error("Slice operation %s cannot be evaluated at compile time", toChars());