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; }
public static Pair List(IEnumerable args) { Pair c = null; foreach (object arg in args) { c = new Pair(arg, c); } return (Pair)Reverse(c); }
public virtual Pair ToList() { Pair result = null; foreach (object o in this) { result = new Pair(o, result); } return (Pair)result.Reverse(); }
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; }
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; }
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(); }
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; }
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; }
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); }
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; } }