public override Val interp(Environment env) { if (func is IdC && ((IdC)func).sym == "copyArr") { Console.WriteLine("HERE"); } // Only should be invoked for function calls // BindC handles closure definitions CloV called = func.interp(env) as CloV; if (called != null) // (is a closure) { Environment callingContext = env; Environment cloEnv = addArgsToEnv(called.parms, args, called.env, env); cloEnv.scopeDepth++; Val retVal = called.body.interp(cloEnv); cloEnv.scopeDepth--; // Propogate changes up to caller /*foreach (KeyValuePair<string, Val> pair in cloEnv) * { * // Only for vars originally in scope; don't copy parameters * if (callingContext.ContainsKey(pair.Key) && !called.parms.Contains(pair.Key)) * { * callingContext[pair.Key] = pair.Value; * } * }*/ return(retVal); } else { throw new InterpException("Calling a non-closure"); } }
public CloV DeepCopy() { CloV result = new CloV((Environment)env.Clone(), body, parms); return(result); }
public override Val interp(Environment env) { Val result; if (lexpr is IdC) // binding a variable { result = rexpr.interp(env); env[((IdC)lexpr).sym] = result; } else if (lexpr is FuncC) // defining a function { FuncC lexprFunc = (FuncC)lexpr; if (lexprFunc.func is IdC) { List <string> parms = new List <string>(); foreach (ExprC parm in lexprFunc.args) { if (parm is IdC) { parms.Add(((IdC)parm).sym); } else { throw new InterpException("Malformed function definition params"); } } result = new CloV((Environment)env.Clone(), rexpr, parms); ((CloV)result).env.SetLocal(((IdC)lexprFunc.func).sym, result); // allow recursion env[((IdC)lexprFunc.func).sym] = result; } else { throw new InterpException("Malformed function definition name"); } } else if (lexpr is IndexC) // defining an array or setting an element { IndexC lexprArray = (IndexC)lexpr; if (lexprArray.arr is IdC) { List <long> indices = new List <long>(); foreach (ExprC idx in lexprArray.indices) { Val idxVal = idx.interp(env); if (idxVal is NumV) { indices.Add(((NumV)idxVal).num); } else { throw new InterpException("Non-numeric array index"); } } if (env.ContainsKey(((IdC)lexprArray.arr).sym)) // setting element { ArrV arr = lexprArray.arr.interp(env) as ArrV; if (arr == null) { throw new InterpException("Indexing non-array"); } result = rexpr.interp(env); arr.SetValue(indices, result); } else // defining new array { result = new ArrV(indices, rexpr.interp(env)); env[((IdC)lexprArray.arr).sym] = result; } } else { throw new InterpException("Malformed array definition name"); } } else { throw new InterpException("Binding with invalid lvalue"); } return(result); }