Each node in a Lisp list is called a pair or cons cell. The first of the pair points to the element the pair is holding. The rest of the pair points to the next pair in the list, or null signifying the end of the list.
Наследование: Sequence
Пример #1
0
 public static ISequence Reverse(ISequence s)
 {
     Pair list = null;
     ISequence o = s;
     while (o != null)
     {
         list = new Pair(o.First(), list);
         o = o.Rest();
     }
     return list;
 }
Пример #2
0
        public static Pair List(IEnumerable args)
        {
            Pair c = null;

            foreach (object arg in args)
            {
                c = new Pair(arg, c);
            }

            return (Pair)Reverse(c);
        }
Пример #3
0
        public virtual Pair ToList()
        {
            Pair result = null;

            foreach (object o in this)
            {
                result = new Pair(o, result);
            }
            return (Pair)result.Reverse();
        }
Пример #4
0
        public static Pair FromArray(object[] os, int skip)
        {
            int i = 0;

            Pair x = null;

            foreach (object o in os)
            {
                if (i++ >= skip)
                    x = new Pair(o, x);
            }

            x = (Pair)Reverse(x);

            return x;
        }
Пример #5
0
        public static ISequence Join(IEnumerable os)
        {
            Pair foo = null;

            foreach (object o in os)
            {
                foo = new Pair(o, foo);
            }

            ISequence bar = null;

            foreach (object o in foo)
            {
                bar = Join(Seq(o), bar);
            }

            return bar;
        }
Пример #6
0
 public static ISequence Range(int start, int finish, int step)
 {
     Pair result = null;
     for (int i = start; i < finish; i += step)
     {
         result = new Pair(i, result);
     }
     return result.Reverse();
 }
Пример #7
0
        public static object QuasiQuote(Object form, Environment environment)
        {
            if (!(form is Pair))
                return form;

            Pair expression = (Pair)form;

            Pair result = null;
            foreach (object item in expression)
            {
                if (item is Pair)
                {
                    Pair list = (Pair)item;
                    if (list.First() == QUASIQUOTE)
                    {
                        result = new Pair(QuasiQuote(list.Second(), environment), result);
                    }
                    else if (list.First() == UNQUOTE)
                    {
                        result = new Pair(Compiler.Eval(QuasiQuote(list.Second(), environment), environment), result);
                    }
                    else if (list.First() == UNQUOTE_SPLICING)
                    {
                        object l = Compiler.Eval(QuasiQuote(list.Second(), environment), environment);

                        if (l is Sequence)
                        {
                            foreach (object o in (Sequence)l)
                            {
                                result = new Pair(o, result);
                            }
                        }

                    }
                    else
                    {
                        result = new Pair(QuasiQuote(item, environment), result);
                    }

                }
                else
                {
                    result = new Pair(item, result);
                }
            }

            if (result is Pair)
                result = (Pair)Reverse((ISequence)result);

            return result;
        }
Пример #8
0
        public static object CompileQuasiQuote(int level, object arg, Environment environment)
        {
            if (level == 0)
                return Compile1(arg, environment);

            if (arg is ISequence)
            {
                ISequence c = (ISequence)arg;
                if (c.First() == UNQUOTE)
                {
                     return new Pair(UNQUOTE,new Pair(CompileQuasiQuote(level - 1, Runtime.Car(Runtime.Cdr(arg)),environment)));
                }

                if ((level == 1) && (c.First() == UNQUOTE_SPLICING))
                {
                    return new Pair(UNQUOTE_SPLICING, new Pair(CompileQuasiQuote(level - 1, Runtime.Car(Runtime.Cdr(arg)), environment)));
                }

                if (c.First() == QUASIQUOTE)
                {
                    return new Pair(QUASIQUOTE, new Pair(CompileQuasiQuote(level + 1, Runtime.Car(Runtime.Cdr(arg)), environment)));
                }

                Pair r = null;
                foreach (object o in c)
                {
                    r = new Pair(CompileQuasiQuote(level, o,environment), r);
                }

                return r.Reverse();
            }

            return arg;
        }
Пример #9
0
        public static Expression CompileMac(object stuff, Environment environment)
        {
            object args = ((Pair)stuff).First();
            Pair body = (Pair)((Pair)stuff).Rest();

            string doc = "";

            if ((body.Length() > 1) && (body.First() is string))
            {
                doc = (string)body.First();
                body = (Pair)body.Rest();
            }

            Pair implicitProgn = new Pair(PROGN, body); // Dangerous if it gets redefined

            object v = Compile(implicitProgn, environment);

            return Expression.Call(null, makeMacroMethodInfo, Expression.Constant(args), Expression.Constant(v), Expression.Constant(doc), environmentParameter);
        }
Пример #10
0
        public static Expression CompileCall(Pair c, Environment environment)
        {
            string dotNetExpression = ((Symbol)c.First()).Name;

            int n = dotNetExpression.LastIndexOf('.');

            string typeName = dotNetExpression.Substring(0, n);
            string methodName = dotNetExpression.Substring(n + 1);

            Type t = ClrGlue.FindType(typeName, Runtime.Namespaces);

            MemberInfo m = ClrGlue.FindUnambiguousMember(methodName, t, c.Length() - 1);

            if (m == null)
            {
                // If we cant find an unambiguos MemberInfo then we'll
                // have to compile a call to CallStaticMethod instead.
                // This will look for a method again reflectively at
                // runtime, so this will be a performance hit
                Expression[] es = CompileArgs1(c.Rest(), environment);

                Expression[] ees = new Expression[3];

                ees[0] = Expression.Constant(methodName);
                ees[1] = Expression.Constant(t, typeof(Type));
                ees[2] = Expression.NewArrayInit(typeof(object), es);

                return Expression.Call(null, callStaticMethodMethodInfo, ees);
            }
            else
            {
                // We know what we're doing at compile time, so lets compile
                // up the call now.
                // No need for runtime reflection = better performance !!

                if (m is MethodInfo)
                {

                    if (((MethodInfo)m).IsStatic)
                    {
                        Expression[] es = CompileArgsX(c.Rest(), ((MethodInfo)m).GetParameters(), environment);
                        return Expression.Call(null, (MethodInfo)m, es);
                    }
                    else
                    {
                        // Its a virtual call
                        Expression[] es = CompileArgsX(c.Rest().Rest(), ((MethodInfo)m).GetParameters(), environment);
                        Expression o = Compile1(c.Rest().First(),environment);
                        return Expression.Call(o, (MethodInfo)m, es);
                    }
                }

                if (m is PropertyInfo)
                        return Expression.Property(null, (PropertyInfo)m);

                if (m is FieldInfo)
                    return Expression.Field(null, (FieldInfo)m);

                return null;
            }
        }