public Expression Visit <A>(IRecExpression <A> rec) where A : Expression { var input = (NumExpression)rec.Input.Accept(this); var start = (A)rec.Start.Accept(this); if (rec.NumVariableName != VariableName && rec.AccVariableName != VariableName) { var step = (A)rec.Step.Accept(this); return(rec.Construct(input, start, rec.NumVariableName, rec.AccVariableName, step)); } else // our variable is shadowed by one of the two binders in rec { return(rec.Construct(input, start, rec.NumVariableName, rec.AccVariableName, rec.Step)); } }
public async Task <Value> Visit <A>(IRecExpression <A> rec) where A : Expression { // A rec has an input, a start, and a step, which itself has two free vars // The idea is to find out what value the input is. // if it is zero we return the start // otherwise we evaluate the rec with an input one less, then put this through the step Value input = await Run(rec.Input); // we need this if (input is NumValue) { NumValue num = input as NumValue; if (num.Value == 0) { return(await Run(rec.Start)); } else { // this looks bad. Fix it int predecessor = num.Value - 1; NumValue newNum = new NumValue(predecessor); VariableSubstituter substNum = new VariableSubstituter(rec.NumVariableName, new NumConstant(predecessor)); Expression newRec = rec.Construct(new NumConstant(predecessor), rec.Start, rec.NumVariableName, rec.AccVariableName, rec.Step); VariableSubstituter substAcc = new VariableSubstituter(rec.AccVariableName, newRec); Expression temp = substNum.Substitute(rec.Step); Expression temp2 = substAcc.Substitute(temp); return(await Run(temp2)); } } else { throw new ArgumentException("In rec the input should evaluate to a Num"); } throw new NotImplementedException(); }