internal override void AddInitializingElementAssignmentsTo(ICollection<Statement> statements, Expression array, VccArrayTypeExpression/*?*/ arrTypeExp) { TypeExpression elemTypeExp = null; if (arrTypeExp != null) { elemTypeExp = arrTypeExp.ElementType; } // If we have a multiple dimensional array, and the element is not a VccInitializer, // then we will compute the number of constants needed for array[i], say, x, and bundle // x constant together for array[i], which may be further an array, in which case, the above // process repeat. int i = 0, n = this.expressions.Count; int lengthForFirstDimensionIfNotProvided = 0; bool elementIsVccInitializer = (n == 0) ? true : expressions[0] is VccInitializer; int rownum = 0; // For multidimensional array, // i may be increased by the total number of embedded array elements per loop, rownum always by 1. while (i < n){ Expression arrayLine = array; List<Expression> indices = new List<Expression>(1) {new CompileTimeConstant(rownum++, true, SourceDummy.SourceLocation)}; VccIndexer element = new VccIndexer(arrayLine, indices.AsReadOnly(), SourceDummy.SourceLocation); // Construct the initial value for one element of the array. Expression/*?*/ initialValueForOneElement = null; int sizeOfEmbeddedArrays = arrTypeExp.SizeOfEmbeddedArrays; VccArrayTypeExpression embeddedArrayType = elemTypeExp as VccArrayTypeExpression; //^ assert sizeOfEmbeddedArrays >=0; // TODO: C doesnt allow sizeOfEmbeddedArrays to be zero, in which case we should report an error if (sizeOfEmbeddedArrays ==0 || elementIsVccInitializer || embeddedArrayType == null) { initialValueForOneElement = this.expressions[i++]; } else { List<Expression> exprs = new List<Expression>(sizeOfEmbeddedArrays); for (int j = 0; j < sizeOfEmbeddedArrays; j++) { exprs.Add(i < n ? expressions[i++] : new CompileTimeConstant(0, this.SourceLocation)); } initialValueForOneElement = new VccInitializer(exprs, false, this.SourceLocation); } //^ assert initialValueForOneElement != null; AddInitializationTo(statements, initialValueForOneElement, element, elemTypeExp, this.ContainingBlock); lengthForFirstDimensionIfNotProvided++; } // In C, it is possible to initialize an array when its first dimension's length is not // specified, in which case, the initializer provides information of the length. if (arrTypeExp.Size != null) { arrTypeExp.ResetSizeWhenProvidedByInitializer(new CompileTimeConstant(lengthForFirstDimensionIfNotProvided, arrTypeExp.SourceLocation)); } }
//^ requires template.ContainingBlock != containingBlock; //^ ensures this.containingBlock == containingBlock; /// <summary> /// A copy constructor that allocates an instance that is the same as the given template, except for its containing block. /// </summary> /// <param name="containingBlock">A new value for containing block. This replaces template.ContainingBlock in the resulting copy of template.</param> /// <param name="template">The template to copy.</param> private VccIndexer(BlockStatement containingBlock, VccIndexer template) : base(containingBlock, template) { }