public static ILispNode Lambda(ILispNode functor, IList <ILispNode> arguments, CallStack callStack, params object[] args) { #if TRACE_FLOW try { #endif try { if (arguments.Count < 2) { throw new Exception("LAMBDA requires at least 2 arguments"); } if (!(arguments[0] is LispList)) { throw new Exception("A lambda must have a LIST of formal parameters as its first argument"); } var result = new LispList { (arguments[0] as LispList) }; foreach (var argument in arguments.Skip(1)) { result.Add(argument); } return(result); } catch { return(new LispNil()); } #if TRACE_FLOW } catch (Exception ex) { Console.WriteLine("lambda threw Exception: " + ex.Message); throw; } finally { Console.WriteLine("(lambda {0}) done", arguments.ToLispArgString()); } #endif }
public static ILispNode List(ILispNode functor, IList <ILispNode> arguments, CallStack callStack, params object[] args) { #if TRACE_FLOW try { #endif if (arguments.Count < 1) { return(new LispNil()); } var missing = new LispMissing(); var result = new LispList(); foreach (var xEval in arguments.Select(x => x.Eval(callStack, true))) { if (xEval is LispMissing) { missing.Merge(xEval); } else { result.Add(xEval); } } return((missing.Count() > 0) ? missing : result as ILispNode); #if TRACE_FLOW } catch (Exception ex) { Console.WriteLine("list threw Exception: " + ex.Message); throw; } finally { Console.WriteLine("(list {0}) done", arguments.ToLispArgString()); } #endif }
public static ILispNode Map(ILispNode functor, IList <ILispNode> arguments, CallStack callStack, params object[] args) { #if TRACE_FLOW try { #endif try { if (arguments.Count < 1) { throw new Exception("MAP requires at least 1 argument"); } var result = new LispList(); var mapFunctor = arguments[0].Eval(callStack, args); // run through the arguments list one at a time and map them to the result with the lambda arguments.Skip(1).ToList().ForEach(x => result.Add(Functor.Apply(mapFunctor, new LispList().Add(x), callStack, args))); return(result); } catch { return(new LispNil()); } #if TRACE_FLOW } catch (Exception ex) { Console.WriteLine("map threw Exception: " + ex.Message); throw; } finally { Console.WriteLine("(map {0}) done", arguments.ToLispArgString()); } #endif }
public static ILispNode Cons(ILispNode functor, IList <ILispNode> arguments, CallStack callStack, params object[] args) { #if TRACE_FLOW try { #endif var missing = new LispMissing(); var result = new LispList(); if (arguments.Count != 2) { throw new Exception("CONS requires exactly 2 arguments"); } do { var car = arguments[0].Eval(callStack, true); if (car is LispMissing) { missing.Merge(car); break; } result.Add(car); var cdr = arguments[1].Eval(callStack, true); if (cdr is LispNil) { break; } if ((cdr is LispAtom) && (cdr as LispAtom).IsNil) { break; } if (cdr is LispMissing) { missing.Merge(cdr); break; } if (cdr is LispList) { if ((cdr as LispList).IsNil) { break; } (cdr as LispList).ForEach( x => { try { var xEval = x.Eval(callStack, true); missing.Merge(xEval); if (xEval is LispMissing) { throw new Exception(); } result.Add(xEval); } catch { result.Add(x); } }); } else { result.IsImproperList = true; result.Add(cdr); } } while (false); return((missing.Count() > 0) ? missing : result as ILispNode); #if TRACE_FLOW } catch (Exception ex) { Console.WriteLine("cons threw Exception: " + ex.Message); throw; } finally { Console.WriteLine("(cons {0}) done", arguments.ToLispArgString()); } #endif }