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 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 }