Example #1
0
        /// <summary>
        /// Emits all initializers that match indices on the stack recursively.
        /// 
        /// Example: 
        ///  if array has [0..2, 0..3, 0..2] shape
        ///  and we have {1, 2} indices on the stack
        ///  initializers for 
        ///              [1, 2, 0]
        ///              [1, 2, 1]
        ///              [1, 2, 2]
        /// 
        ///  will be emitted and the top index will be pushed off the stack 
        ///  as at that point we would be completely done with emitting initializers 
        ///  corresponding to that index.
        /// </summary>
        private void EmitAllElementInitializersRecursive(ArrayTypeSymbol arrayType,
                                                         ArrayBuilder<IndexDesc> indices,
                                                         bool includeConstants)
        {
            var top = indices.Peek();
            var inits = top.Initializers;

            if (IsMultidimensionalInitializer(inits))
            {
                // emit initializers for the less significant indices recursively
                for (int i = 0; i < inits.Length; i++)
                {
                    indices.Push(new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers));
                    EmitAllElementInitializersRecursive(arrayType, indices, includeConstants);
                }
            }
            else
            {
                // leaf case
                for (int i = 0; i < inits.Length; i++)
                {
                    var init = inits[i];
                    if (ShouldEmitInitExpression(includeConstants, init))
                    {
                        // emit array ref
                        _builder.EmitOpCode(ILOpCode.Dup);

                        Debug.Assert(indices.Count == arrayType.Rank - 1);

                        // emit values of all indices that are in progress
                        foreach (var row in indices)
                        {
                            _builder.EmitIntConstant(row.Index);
                        }

                        // emit the leaf index
                        _builder.EmitIntConstant(i);

                        var initExpr = inits[i];
                        EmitExpression(initExpr, true);
                        EmitArrayElementStore(arrayType, init.Syntax);
                    }
                }
            }

            indices.Pop();
        }