public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) { // Partial evaluation may encounter a cached expression in conditionals // etc, and should simply partially evaluate the expression inside the cache. // No duplication of cached expression happens in the residual program because // a cached expression appears only once in the regular code, and no occurrence // from evaluation conditions is added to the residual program; see ComputeCell.PEval. // New evaluation conditions are added later; see ProgramLines.CompileToDelegate. return(expr.PEval(pEnv, hasDynamicControl)); }
// Returns residual ComputeCell or null if no cell needed public ComputeCell PEval(PEnv pEnv) { CGExpr rCond = null; if (evalCond != null) // Never the case for an output cell { rCond = evalCond.PEval(pEnv, false /* not dynamic control */); } if (rCond is CGNumberConst) { if ((rCond as CGNumberConst).number.value != 0.0) { rCond = null; // eval cond constant TRUE, discard eval cond } else { return(null); // eval cond constant FALSE, discard entire compute cell } } // If residual eval cond is not TRUE then expr has dynamic control CGExpr rExpr = expr.PEval(pEnv, rCond != null); if (rExpr is CGConst && var != null) { // If cell's value is constant and it is not an output cell just put in PEnv pEnv[cellAddr] = rExpr; return(null); } else { // Else create fresh local variable for the residual cell, and make // PEnv map cell address to that local variable: Variable newVar = var != null?var.Fresh() : null; pEnv[cellAddr] = new CGCellRef(cellAddr, newVar); ComputeCell result = new ComputeCell(rExpr, newVar, cellAddr); // result.EvalCond = rCond; // Don't save residual eval cond, we compute it accurately later... return(result); } }