public static ILispNode MergeAsBoolean(this ILispNode root, IList <ILispNode> arguments, CallStack callStack, int arity, IMerger merger) { if (arguments.Count < arity) { throw new Exception("Not enough arguments"); } var fFirst = true; var fUnary = (arity == 1); return(new LispAtom( arguments.Aggregate( false, (result, xArg) => { var xEval = xArg.Eval(callStack); // nil is treated as false if (xEval is LispNil) { xEval = new LispAtom(false); } if ((xEval is LispMissing) && (merger.MergeMissing != null)) { return (bool)merger.MergeMissing(result, xEval as LispMissing); } if ((xEval is LispList) && (merger.MergeList != null)) { return (bool)merger.MergeList(result, xEval as LispList); } Debug.Assert(xEval is LispAtom, "Argument does not evaluate to an Atom!"); try { if (!(xEval as LispAtom).IsBoolean) { throw new Exception(); } // if fUnary, it means the function has only the first argument, which must be merged // otherwise, we can prime the pump with the value of the first argument if (fFirst && !fUnary) { result = (xEval as LispAtom).ValueAsBoolean; fFirst = false; return result; } return (bool)merger.MergeAtom(result, (xEval as LispAtom).ValueAsBoolean); } catch { throw new Exception("Argument does not evaluate to a Boolean"); } }))); }
private static void ParseEventHandler(ParseEventArgs e) { var pctx = e.ParserContext as ListBuilderContext; if (pctx == null) { return; } switch (e.Token) { case Token.CommentStart: return; case Token.SExprStart: { // a new list child pctx.Current = new LispList(pctx.Current as LispList); if (pctx.Root == null) { pctx.Root = pctx.Current; } } return; case Token.SExprFinish: { // pop back one level pctx.Current = pctx.Current.Parent; } return; } switch (e.State) { case ParseState.Atom: { // a new atom child var atom = new LispAtom(pctx.Current as LispList, e.TokenValue, e.Token); if (pctx.Current == null) { pctx.Current = atom; } if (pctx.Root == null) { pctx.Root = pctx.Current; } } return; case ParseState.Failure: { throw new ParseException( String.Format("*** FAILURE {0}] : [ {1} ], {2}, {3}", e.ErrorDescription, e.TokenValue, e.State, e.Token)); } } }
public LispAtom Copy(LispAtom source) { RawValue = source.RawValue; Token = source.Token; TokenValue = source.TokenValue; EvalComplete = source.EvalComplete; return(this); }