public object ApplyLambda(IList<object> arguments, Environment environment) { var parameterList = arguments.First() as IList<object>; var body = arguments.Skip(1); if (parameterList == null) { throw new ArgumentException("Missing parameter list in lambda!"); } if (!parameterList.All(x => x is SymbolNode)) { throw new ArgumentException("Parameters must be symbols!"); } return new ProcedureNode(parameterList.Cast<SymbolNode>(), body, environment.CreateChildEnvironment()); }
public object ApplyLet(IList<object> arguments, Environment environment) { /* * (let ((var-a form-a) (var-b form-b)) (+ var-a var-b)) */ var bindingList = (IList<object>) arguments.First(); var bodyforms = arguments.Skip(1).AsEnumerable(); var localEnv = environment.CreateChildEnvironment(); foreach (var binding in bindingList.OfType<IList<object>>()) { var symbol = (SymbolNode)binding.First(); var form = binding.ElementAt(1); var value = evaluator.Evaluate(form, localEnv); localEnv.DefineSymbol(symbol, value); } return evaluator.Evaluate(bodyforms, localEnv); }
public object ApplyDefMacro(IList<object> arguments, Environment environment) { if (arguments.Count != 3) { throw new ArgumentException("Wrong number of arguments given to defmacro! Expected: " + 3); } var symbol = arguments.ElementAt(0) as SymbolNode; if (symbol == null) { throw new ArgumentException("First argument to defmacro not a symbol!"); } var parameterList = arguments.ElementAt(1) as IList<object>; if (parameterList == null) { throw new ArgumentException("Second argument to defmacro not a parameterlist!"); } var body = arguments.ElementAt(2); var macro = new ProcedureNode(parameterList.Cast<SymbolNode>(), new[] { body }, environment.CreateChildEnvironment(), true); environment.DefineSymbol(symbol, macro); return symbol; }