public async Task <Value> Visit(Apply apply) { // Find out what the lambda is, then evaluate it with the given expression // Do we do a syntactic substitution? // evaluate our lambda until we get an LambdaValue. Then we substitute and continue. var lambda = await apply.Lambda.Accept(this); if (lambda is LambdaValue) { LambdaValue val = (LambdaValue)lambda; VariableSubstituter subst = new VariableSubstituter(val.VariableName, apply.Expression); var newExpr = subst.Substitute(val.Expression); return(await newExpr.Accept(this)); } else { throw new ArgumentException("Value cannot be evaluated to a Lambda"); } //VariableSubstituter subst = new VariableSubstituter(apply.va) throw new NotImplementedException(); }
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(); }