Mercurial > projects > ddmd
diff dmd/StructLiteralExp.d @ 123:9e39c7de8438
Make dmd test suite compile
author | korDen |
---|---|
date | Fri, 03 Sep 2010 20:46:58 +0400 |
parents | e28b18c23469 |
children | af1bebfd96a4 |
line wrap: on
line diff
--- a/dmd/StructLiteralExp.d Thu Sep 02 23:37:49 2010 +0100 +++ b/dmd/StructLiteralExp.d Fri Sep 03 20:46:58 2010 +0400 @@ -2,11 +2,13 @@ import dmd.common; import dmd.Expression; +import dmd.GlobalExpressions; import dmd.MOD; import dmd.TypeStruct; import dmd.TypeSArray; import dmd.expression.Util; import dmd.ErrorExp; +import dmd.Array; import dmd.Dsymbol; import dmd.VarDeclaration; import dmd.StructDeclaration; @@ -63,7 +65,7 @@ override Expression syntaxCopy() { - assert(false); + return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements)); } override Expression semantic(Scope sc) @@ -459,12 +461,163 @@ override Expression interpret(InterState istate) { - assert(false); + Expressions expsx = null; + +version (LOG) { + printf("StructLiteralExp.interpret() %.*s\n", toChars()); +} + /* We don't know how to deal with overlapping fields + */ + if (sd.hasUnions) + { + error("Unions with overlapping fields are not yet supported in CTFE"); + return EXP_CANT_INTERPRET; + } + + if (elements) + { + foreach (size_t i, Expression e; elements) + { + if (!e) + continue; + + Expression ex = e.interpret(istate); + if (ex is EXP_CANT_INTERPRET) + { + delete expsx; + return EXP_CANT_INTERPRET; + } + + /* If any changes, do Copy On Write + */ + if (ex != e) + { + if (!expsx) + { + expsx = new Expressions(); + expsx.setDim(elements.dim); + for (size_t j = 0; j < elements.dim; j++) + { + expsx[j] = elements[j]; + } + } + expsx[i] = ex; + } + } + } + if (elements && expsx) + { + expandTuples(expsx); + if (expsx.dim != elements.dim) + { + delete expsx; + return EXP_CANT_INTERPRET; + } + StructLiteralExp se = new StructLiteralExp(loc, sd, expsx); + se.type = type; + return se; + } + return this; } override dt_t** toDt(dt_t** pdt) { - assert(false); + Array dts; + dt_t *dt; + dt_t *d; + uint offset; + + //printf("StructLiteralExp.toDt() %s)\n", toChars()); + dts.setDim(sd.fields.dim); + dts.zero(); + assert(elements.dim <= sd.fields.dim); + + foreach (uint i, Expression e; elements) + { + if (!e) + continue; + + dt = null; + e.toDt(&dt); + dts.data[i] = dt; + } + + offset = 0; + foreach (uint j, VarDeclaration v; sd.fields) + { + d = cast(dt_t*)dts.data[j]; + if (!d) + { // An instance specific initializer was not provided. + // Look to see if there's a default initializer from the + // struct definition + if (v.init) + { + d = v.init.toDt(); + } + else if (v.offset >= offset) + { + uint k; + uint offset2 = v.offset + cast(uint)v.type.size(); + // Make sure this field (v) does not overlap any explicitly + // initialized field. + for (k = j + 1; 1; k++) + { + if (k == dts.dim) // didn't find any overlap + { + v.type.toDt(&d); + break; + } + VarDeclaration v2 = sd.fields[k]; + + if (v2.offset < offset2 && dts.data[k]) + break; // overlap + } + } + } + if (d) + { + if (v.offset < offset) + error("duplicate union initialization for %s", v.toChars()); + else + { + uint sz = dt_size(d); + uint vsz = cast(uint)v.type.size(); + uint voffset = v.offset; + assert(sz <= vsz); + + uint dim = 1; + for (Type vt = v.type.toBasetype(); vt.ty == Tsarray; vt = vt.nextOf().toBasetype()) + { + TypeSArray tsa = cast(TypeSArray)vt; + dim *= tsa.dim.toInteger(); + } + + for (size_t i = 0; i < dim; i++) + { + if (offset < voffset) + pdt = dtnzeros(pdt, voffset - offset); + if (!d) + { + if (v.init) + d = v.init.toDt(); + else + v.type.toDt(&d); + } + pdt = dtcat(pdt, d); + d = null; + offset = voffset + sz; + voffset += vsz / dim; + if (sz == vsz) + break; + } + } + } + } + + if (offset < sd.structsize) + pdt = dtnzeros(pdt, sd.structsize - offset); + + return pdt; } version(DMDV2)