Пример #1
0
        /// <summary>
        /// Compiles the topologically sorted list of Expr to a list (program)
        /// of ComputeCells, encapsulating CGExprs.  Builds a map from cellAddr to
        /// local variable ids, for compiling sheet-internal cellrefs to ldloc instructions.
        /// </summary>
        public void AddComputeCells(DependencyGraph dpGraph, IList <FullCellAddr> cellList)
        {
            Debug.Assert(dpGraph.outputCell == cellList[cellList.Count - 1]);
            CGExpr outputExpr;

            if (cellList.Count == 0 || cellList.Count == 1 && dpGraph.inputCellSet.Contains(cellList.Single()))
            {
                // The output cell is also an input cell; load it:
                outputExpr = new CGCellRef(dpGraph.outputCell, addressToVariable[dpGraph.outputCell]);
            }
            else
            {
                // First process all non-output cells, and ignore all input cells:
                foreach (FullCellAddr cellAddr in cellList)
                {
                    if (cellAddr.Equals(dpGraph.outputCell))
                    {
                        continue;
                    }
                    HashSet <FullCellAddr> dependents = dpGraph.GetDependents(cellAddr);
                    int minUses = dependents.Count;
                    if (minUses == 1)
                    {
                        FullCellAddr fromFca = dependents.First();
                        minUses = Math.Max(minUses, GetCount(fromFca, cellAddr));
                    }
                    // Now if minUses==1 then there is at most one use of the cell at cellAddr,
                    // and no local variable is needed.  Otherwise, allocate a local variable:
                    if (minUses > 1)
                    {
                        CGExpr   newExpr = CGExpressionBuilder.BuildExpression(cellAddr, addressToVariable);
                        Variable var     = new LocalVariable(cellAddr.ToString(), newExpr.Type());
                        AddComputeCell(cellAddr, new ComputeCell(newExpr, var, cellAddr));
                    }
                }
                // Then process the output cell:
                outputExpr = CGExpressionBuilder.BuildExpression(dpGraph.outputCell, addressToVariable);
            }
            // Add the output cell expression last, without a variable to bind it to; hence the null,
            // also indicating that (only) the output cell is in tail position:
            AddComputeCell(dpGraph.outputCell, new ComputeCell(outputExpr, null, dpGraph.outputCell));
        }