예제 #1
0
        public static ILispNode Cond(ILispNode functor, IList <ILispNode> arguments, CallStack callStack, params object[] args)
        {
#if TRACE_FLOW
            try
            {
#endif
            var missing = new LispMissing();
            if (arguments.Count < 1)
            {
                throw new Exception("COND requires at least 1 argument");
            }

            for (var i = 0; i <= arguments.Count; i++)
            {
                var _case = arguments[i];
                if (_case is LispMissing)
                {
                    missing.Merge(_case);
                    continue;
                }

                if (!(_case is LispList) && ((_case as LispList).Count != 2))
                {
                    throw new Exception("Each COND case requires exactly 2 arguments");
                }

                var test = (_case as LispList)[0].Eval(callStack, true);
                if (test is LispMissing)
                {
                    missing.Merge(test);
                    continue;
                }

                if ((test is LispNil) || (!(test as LispAtom).ValueAsBoolean))
                {
                    continue;
                }

                return((_case as LispList)[1].Eval(callStack, true));
            }

            return(new LispNil());

#if TRACE_FLOW
        }

        catch (Exception ex)
        {
            Console.WriteLine("cond threw Exception: " + ex.Message);
            throw;
        }
        finally
        {
            Console.WriteLine("(cond {0}) done", arguments.ToLispArgString());
        }
#endif
        }
예제 #2
0
        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
        }
예제 #3
0
        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
        }