public static CGExpr BuildExpression(FullCellAddr addr,
											 Dictionary<FullCellAddr, Variable> addressToVariable) {
			Cell cell;
			if (!addr.TryGetCell(out cell)) {
				return new CGTextConst(TextValue.EMPTY);
			}
			else if (cell is NumberCell) {
				return new CGNumberConst(((NumberCell)cell).value);
			}
			else if (cell is TextCell) {
				return new CGTextConst(((TextCell)cell).value);
			}
			else if (cell is QuoteCell) {
				return new CGTextConst(((QuoteCell)cell).value);
			}
			else if (cell is BlankCell) {
				return new CGError("#FUNERR: Blank cell in function");
			}
			else if (cell is Formula) {
				// Translate the expr relative to its containing cell at addr
				CGExpressionBuilder cgBuilder = new CGExpressionBuilder(addressToVariable, addr);
				Expr expr = ((Formula)cell).Expr;
				expr.VisitorCall(cgBuilder);
				return cgBuilder.result;
			}
			else if (cell is ArrayFormula) {
				return new CGError("#FUNERR: Array formula in function");
			}
			else {
				throw new ImpossibleException("BuildExpression: " + cell);
			}
		}
Exemple #2
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));
        }
Exemple #3
0
        public static CGExpr BuildExpression(FullCellAddr addr,
                                             Dictionary <FullCellAddr, Variable> addressToVariable)
        {
            Cell cell;

            if (!addr.TryGetCell(out cell))
            {
                return(new CGTextConst(TextValue.EMPTY));
            }
            else if (cell is NumberCell)
            {
                return(new CGNumberConst(((NumberCell)cell).value));
            }
            else if (cell is TextCell)
            {
                return(new CGTextConst(((TextCell)cell).value));
            }
            else if (cell is QuoteCell)
            {
                return(new CGTextConst(((QuoteCell)cell).value));
            }
            else if (cell is BlankCell)
            {
                return(new CGError("#FUNERR: Blank cell in function"));
            }
            else if (cell is Formula)
            {
                // Translate the expr relative to its containing cell at addr
                CGExpressionBuilder cgBuilder = new CGExpressionBuilder(addressToVariable, addr);
                Expr expr = ((Formula)cell).Expr;
                expr.VisitorCall(cgBuilder);
                return(cgBuilder.result);
            }
            else if (cell is ArrayFormula)
            {
                return(new CGError("#FUNERR: Array formula in function"));
            }
            else
            {
                throw new ImpossibleException("BuildExpression: " + cell);
            }
        }