Mercurial > projects > ddmd
view dmd/ArrayInitializer.d @ 83:ee670dd808a8
malloc -> GC.malloc change, plus compilation issues fixed (always check before commiting stuff!!!)
author | korDen |
---|---|
date | Mon, 30 Aug 2010 18:42:04 +0400 |
parents | 43073c7c7769 |
children | be2ab491772e |
line wrap: on
line source
module dmd.ArrayInitializer; import dmd.ArrayTypes; import dmd.Type; import dmd.TypeAArray; import dmd.TypeNext; import dmd.Array; import dmd.Loc; import dmd.Initializer; import dmd.WANT; import dmd.Util; import dmd.TY; import dmd.TypeSArray; import dmd.IntegerExp; import dmd.Expression; import dmd.ArrayLiteralExp; import dmd.Scope; import dmd.ErrorExp; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.backend.dt_t; import dmd.backend.Util; import dmd.codegen.Util; import dmd.backend.TYM; import dmd.backend.Symbol; class ArrayInitializer : Initializer { Expressions index; // indices Initializers value; // of Initializer *'s uint dim = 0; // length of array being initialized Type type = null; // type that array will be used to initialize int sem = 0; // !=0 if semantic() is run this(Loc loc) { super(loc); index = new Expressions(); value = new Initializers(); } override Initializer syntaxCopy() { //printf("ArrayInitializer.syntaxCopy()\n"); ArrayInitializer ai = new ArrayInitializer(loc); assert(index.dim == value.dim); ai.index.setDim(index.dim); ai.value.setDim(value.dim); for (int i = 0; i < ai.value.dim; i++) { Expression e = cast(Expression)index.data[i]; if (e) e = e.syntaxCopy(); ai.index.data[i] = cast(void*)e; Initializer init = cast(Initializer)value.data[i]; init = init.syntaxCopy(); ai.value.data[i] = cast(void*)init; } return ai; } void addInit(Expression index, Initializer value) { this.index.push(cast(void*)index); this.value.push(cast(void*)value); dim = 0; type = null; } override Initializer semantic(Scope sc, Type t) { uint i; uint length; //printf("ArrayInitializer.semantic(%s)\n", t.toChars()); if (sem) // if semantic() already run return this; sem = 1; type = t; t = t.toBasetype(); switch (t.ty) { case Tpointer: case Tsarray: case Tarray: break; default: error(loc, "cannot use array to initialize %s", type.toChars()); return this; } length = 0; for (i = 0; i < index.dim; i++) { Expression idx; Initializer val; idx = cast(Expression)index.data[i]; if (idx) { idx = idx.semantic(sc); idx = idx.optimize(WANTvalue | WANTinterpret); index.data[i] = cast(void*)idx; length = cast(uint)idx.toInteger(); } val = cast(Initializer)value.data[i]; val = val.semantic(sc, t.nextOf()); value.data[i] = cast(void*)val; length++; if (length == 0) error(loc, "array dimension overflow"); if (length > dim) dim = length; } uint amax = 0x80000000; if (cast(uint) (dim * t.nextOf().size()) >= amax) error(loc, "array dimension %u exceeds max of %ju", dim, amax / t.nextOf().size()); return this; } override Type inferType(Scope sc) { //printf("ArrayInitializer.inferType() %s\n", toChars()); type = Type.terror; for (size_t i = 0; i < value.dim; i++) { if (index.data[i]) goto Laa; } for (size_t i = 0; i < value.dim; i++) { Initializer iz = cast(Initializer)value.data[i]; if (iz) { Type t = iz.inferType(sc); if (i == 0) { t = new TypeSArray(t, new IntegerExp(value.dim)); t = t.semantic(loc, sc); type = t; } } } return type; Laa: /* It's possibly an associative array initializer */ Initializer iz = cast(Initializer)value.data[0]; Expression indexinit = cast(Expression)index.data[0]; if (iz && indexinit) { Type t = iz.inferType(sc); indexinit = indexinit.semantic(sc); Type indext = indexinit.type; t = new TypeAArray(t, indext); type = t.semantic(loc, sc); } else error(loc, "cannot infer type from this array initializer"); return type; } /******************************** * If possible, convert array initializer to array literal. * Otherwise return null. */ override Expression toExpression() { Expression e; //printf("ArrayInitializer.toExpression(), dim = %d\n", dim); //static int i; if (++i == 2) halt(); size_t edim; Type t = null; if (type) { if (type == Type.terror) return new ErrorExp(); t = type.toBasetype(); switch (t.ty) { case Tsarray: edim = cast(uint)(cast(TypeSArray)t).dim.toInteger(); break; case Tpointer: case Tarray: edim = dim; break; default: assert(0); } } else { edim = value.dim; for (size_t i = 0, j = 0; i < value.dim; i++, j++) { if (index.data[i]) j = cast(uint)(cast(Expression)index.data[i]).toInteger(); if (j >= edim) edim = j + 1; } } Expressions elements = new Expressions(); elements.setDim(edim); for (size_t i = 0, j = 0; i < value.dim; i++, j++) { if (index.data[i]) j = cast(uint)(cast(Expression)index.data[i]).toInteger(); assert(j < edim); Initializer iz = cast(Initializer)value.data[i]; if (!iz) goto Lno; Expression ex = iz.toExpression(); if (!ex) { goto Lno; } elements.data[j] = cast(void*)ex; } /* Fill in any missing elements with the default initializer */ { Expression init = null; for (size_t i = 0; i < edim; i++) { if (!elements.data[i]) { if (!type) goto Lno; if (!init) init = (cast(TypeNext)t).next.defaultInit(Loc(0)); elements.data[i] = cast(void*)init; } } Expression e2 = new ArrayLiteralExp(loc, elements); e2.type = type; return e2; } Lno: return null; } Initializer toAssocArrayInitializer() { assert(false); } override void toCBuffer(OutBuffer buf, HdrGenState* hgs) { assert(false); } override dt_t* toDt() { //printf("ArrayInitializer.toDt('%s')\n", toChars()); Type tb = type.toBasetype(); Type tn = tb.nextOf().toBasetype(); scope Array dts = new Array(); uint size; uint length; uint i; dt_t* dt; dt_t* d; dt_t** pdtend; //printf("\tdim = %d\n", dim); dts.setDim(dim); dts.zero(); size = cast(uint)tn.size(); length = 0; for (i = 0; i < index.dim; i++) { Expression idx; Initializer val; idx = cast(Expression)index.data[i]; if (idx) length = cast(uint)idx.toInteger(); //printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim); assert(length < dim); val = cast(Initializer)value.data[i]; dt = val.toDt(); if (dts.data[length]) error(loc, "duplicate initializations for index %d", length); dts.data[length] = cast(void*)dt; length++; } Expression edefault = tb.nextOf().defaultInit(Loc(0)); uint n = 1; for (Type tbn = tn; tbn.ty == Tsarray; tbn = tbn.nextOf().toBasetype()) { TypeSArray tsa = cast(TypeSArray)tbn; n *= tsa.dim.toInteger(); } d = null; pdtend = &d; for (i = 0; i < dim; i++) { dt = cast(dt_t*)dts.data[i]; if (dt) pdtend = dtcat(pdtend, dt); else { for (int j = 0; j < n; j++) pdtend = edefault.toDt(pdtend); } } switch (tb.ty) { case Tsarray: { uint tadim; TypeSArray ta = cast(TypeSArray)tb; tadim = cast(uint)ta.dim.toInteger(); if (dim < tadim) { if (edefault.isBool(false)) // pad out end of array pdtend = dtnzeros(pdtend, size * (tadim - dim)); else { for (i = dim; i < tadim; i++) { for (int j = 0; j < n; j++) pdtend = edefault.toDt(pdtend); } } } else if (dim > tadim) { debug writef("1: "); error(loc, "too many initializers, %d, for array[%d]", dim, tadim); } break; } case Tpointer: case Tarray: // Create symbol, and then refer to it Symbol* s = static_sym(); s.Sdt = d; outdata(s); d = null; if (tb.ty == Tarray) dtdword(&d, dim); dtxoff(&d, s, 0, TYnptr); break; default: assert(0); } return d; } dt_t* toDtBit() // for bit arrays { assert(false); } override ArrayInitializer isArrayInitializer() { return this; } }