示例#1
0
 /// <summary>
 /// Create a <see cref="PersistentHashSet">PersistentHashSet</see> initialized from an <see cref="ISeq">ISeq</see> of items.
 /// </summary>
 /// <param name="items">An <see cref="ISeq">ISeq</see> of items</param>
 /// <returns>A <see cref="PersistentHashSet">PersistentHashSet</see>.</returns>
 public static PersistentHashSet create(ISeq items)
 {
     PersistentHashSet ret = EMPTY;
     for (; items != null; items = items.next())
         ret = (PersistentHashSet)ret.cons(items.first());
     return ret;
 }
 public static PersistentHashSet create(ISeq items)
 {
     ITransientSet ret = (ITransientSet)EMPTY.asTransient(); 
     for (; items != null; items = items.next())
         ret = (ITransientSet)ret.conj(items.first());
     return (PersistentHashSet)ret.persistent();
 }
示例#3
0
 public static Expr Parse(ISeq form)
 {
     Expr fexpr = Compiler.GenerateAST(form.first(),false);
     IPersistentVector args = PersistentVector.EMPTY;
     for ( ISeq s = RT.seq(form.next()); s != null; s = s.next())
         args = args.cons(Compiler.GenerateAST(s.first(),false));
     return new InvokeExpr((string)Compiler.SOURCE.deref(),(int)Compiler.LINE.deref(),Compiler.TagOf(form),fexpr,args);
 }
示例#4
0
 public static Expr Parse(ISeq form)
 {
     Expr fexpr = Compiler.GenerateAST(form.first());
     IPersistentVector args = PersistentVector.EMPTY;
     for ( ISeq s = RT.seq(form.next()); s != null; s = s.next())
         args = args.cons(Compiler.GenerateAST(s.first()));
     return new InvokeExpr(Compiler.TagOf(form),fexpr,args);
 }
示例#5
0
        public void VerifyISeqContents(ISeq s, IList<object> values)
        {
            int i=0;

            for (; s != null; s = s.rest(), i++)
                Expect(s.first(), EqualTo(values[i]));

            Expect(i, EqualTo(values.Count));
        }
 /// <summary>
 /// Create a struct from a struct definition and values (in order) for the fixed keys.
 /// </summary>
 /// <param name="def">A struct definition</param>
 /// <param name="valseq">A sequence of values for the fixed keys (in definition order).</param>
 /// <returns>A <see cref="PersistentStructMap">PersistentStructMap</see>.</returns>
 public static PersistentStructMap construct(Def def, ISeq valseq)
 {
     object[] vals = new object[def.Keyslots.count()];
     IPersistentMap ext = PersistentHashMap.EMPTY;
     for (int i = 0; i < vals.Length && valseq != null; valseq = valseq.rest(), i++)
     {
         vals[i] = valseq.first();
     }
     if (valseq != null)
         throw new ArgumentException("Too many arguments to struct constructor");
     return new PersistentStructMap(null, def, vals, ext);
 }
示例#7
0
        public ITransientMap conj(object val)
        {
            EnsureEditable();

            {
                IMapEntry e = val as IMapEntry;
                if (e != null)
                {
                    return(assoc(e.key(), e.val()));
                }
            }

            if (val is DictionaryEntry)
            {
                DictionaryEntry de = (DictionaryEntry)val;
                return(assoc(de.Key, de.Value));
            }

            {
                IPersistentVector v = val as IPersistentVector;
                if (v != null)
                {
                    if (v.count() != 2)
                    {
                        throw new ArgumentException("Vector arg to map conj must be a pair");
                    }
                    return(assoc(v.nth(0), v.nth(1)));
                }
            }

            // TODO: also handle KeyValuePair?
            ITransientMap ret = this;

            for (ISeq es = RT.seq(val); es != null; es = es.next())
            {
                IMapEntry e = (IMapEntry)es.first();
                ret = ret.assoc(e.key(), e.val());
            }
            return(ret);
        }
示例#8
0
        /// <summary>
        /// Determine if an object is equivalent to this (handles all collections).
        /// </summary>
        /// <param name="o">The object to compare.</param>
        /// <returns><c>true</c> if the object is equivalent; <c>false</c> otherwise.</returns>
        /// <remarks>
        /// In Java Rev 1215, Added equiv.  Same as the definition in Equals, as in they took out the hashcode comparison.
        /// Different, as in Util.Equal above became Util.equals. and below it is Util.equiv.
        /// </remarks>
        public bool equiv(object o)
        {
            //if(!(obj instanceof Map))
            //    return false;
            //Map m = (Map) obj;

            if (o is IPersistentMap && !(o is MapEquivalence))
            {
                return(false);
            }

            IDictionary d = o as IDictionary;

            if (d == null)
            {
                return(false);
            }

            // Java had the following.
            // This works on other APersistentMap implementations, but not on
            //  arbitrary dictionaries.
            //if (d.Count != this.Count || d.GetHashCode() != this.GetHashCode())
            //    return false;

            if (d.Count != this.Count)
            {
                return(false);
            }

            for (ISeq s = seq(); s != null; s = s.next())
            {
                IMapEntry me    = (IMapEntry)s.first();
                bool      found = d.Contains(me.key());
                if (!found || !Util.equiv(me.val(), d[me.key()]))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#9
0
        public static bool mapEquals(IPersistentMap m1, Object obj)
        {
            if (m1 == obj)
            {
                return(true);
            }

            //if(!(obj instanceof Map))
            //    return false;
            //Map m = (Map) obj;

            IDictionary d = obj as IDictionary;

            if (d == null)
            {
                return(false);
            }

            // Java had the following.
            // This works on other APersistentMap implementations, but not on
            //  arbitrary dictionaries.
            //if (d.Count != m1.Count || d.GetHashCode() != m1.GetHashCode())
            //    return false;

            if (d.Count != m1.count())
            {
                return(false);
            }

            for (ISeq s = m1.seq(); s != null; s = s.next())
            {
                IMapEntry me    = (IMapEntry)s.first();
                bool      found = d.Contains(me.key());
                if (!found || !Util.equals(me.val(), d[me.key()]))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#10
0
        public static Expr Parse(ParserContext pcon, IPersistentSet form)
        {
            ParserContext pconToUse = pcon.EvalOrExpr();
            bool          constant  = true;

            IPersistentVector keys = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                object e    = s.first();
                Expr   expr = Compiler.Analyze(pconToUse, e);
                keys = (IPersistentVector)keys.cons(expr);
                if (!(expr is LiteralExpr))
                {
                    constant = false;
                }
            }
            Expr ret      = new SetExpr(keys);
            IObj iobjForm = form as IObj;

            if (iobjForm != null && iobjForm.meta() != null)
            {
                return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret));
            }
            else if (constant)
            {
                IPersistentSet set = PersistentHashSet.EMPTY;
                for (int i = 0; i < keys.count(); i++)
                {
                    LiteralExpr ve = (LiteralExpr)keys.nth(i);
                    set = (IPersistentSet)set.cons(ve.Val);
                }
                return(new ConstantExpr(set));
            }
            else
            {
                return(ret);
            }
        }
示例#11
0
        public virtual void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            //emitting a Fn means constructing an instance, feeding closed-overs from enclosing scope, if any
            //objx arg is enclosing objx, not this

            if (IsDefType)
            {
                ilg.Emit(OpCodes.Ldnull);
            }
            else
            {
                if (SupportsMeta)
                {
                    ilg.Emit(OpCodes.Ldnull);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                }

                for (ISeq s = RT.keys(Closes); s != null; s = s.next())
                {
                    LocalBinding lb = (LocalBinding)s.first();
                    if (lb.PrimitiveType != null)
                    {
                        objx.EmitUnboxedLocal(ilg, lb);
                    }
                    else
                    {
                        objx.EmitLocal(ilg, lb);
                    }
                }

                ilg.Emit(OpCodes.Newobj, _ctorInfo);
            }

            if (rhc == RHC.Statement)
            {
                ilg.Emit(OpCodes.Pop);
            }
        }
示例#12
0
        protected override void GenerateMethods(GenContext context)
        {
            for (ISeq s = RT.seq(Methods); s != null; s = s.next())
            {
                FnMethod method = (FnMethod)s.first();
                method.GenerateCode(this, context);
            }

            if (IsVariadic)
            {
                GenerateGetRequiredArityMethod(TypeBuilder, _variadicMethod.RequiredArity);
            }

            List <int> supportedArities = new List <int>();

            for (ISeq s = RT.seq(Methods); s != null; s = s.next())
            {
                FnMethod method = (FnMethod)s.first();
                supportedArities.Add(method.NumParams);
            }

            GenerateHasArityMethod(TypeBuilder, supportedArities, IsVariadic, IsVariadic ? _variadicMethod.RequiredArity : 0);
        }
示例#13
0
        private static void DefineMethod(TypeBuilder proxyTB, IPersistentVector sig)
        {
            Symbol mname = (Symbol)sig.nth(0);

            Type[] paramTypes = GenClass.CreateTypeArray((ISeq)sig.nth(1));
            Type   retType    = (Type)sig.nth(2);
            ISeq   pmetas     = (ISeq)(sig.count() >= 4 ? sig.nth(3) : null);

            MethodBuilder mb = proxyTB.DefineMethod(mname.Name, MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.Virtual, retType, paramTypes);

            SetCustomAttributes(mb, GenInterface.ExtractAttributes(RT.meta(mname)));
            int i = 1;

            for (ISeq s = pmetas; s != null; s = s.next(), i++)
            {
                IPersistentMap meta = GenInterface.ExtractAttributes((IPersistentMap)s.first());
                if (meta != null && meta.count() > 0)
                {
                    ParameterBuilder pb = mb.DefineParameter(i, ParameterAttributes.None, String.Format("p_{0}", i));
                    GenInterface.SetCustomAttributes(pb, meta);
                }
            }
        }
示例#14
0
        public static Expr Parse(ParserContext pcon, IPersistentSet form)
        {
            ParserContext pconToUse = pcon.EvalOrExpr();
            bool          constant  = true;

            IPersistentVector keys = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                object e    = s.first();
                Expr   expr = Compiler.Analyze(pconToUse, e);
                keys = (IPersistentVector)keys.cons(expr);
                if (!(expr is LiteralExpr))
                {
                    constant = false;
                }
            }
            Expr ret = new SetExpr(keys);

            if (form is IObj iobjForm && iobjForm.meta() != null)
            {
                return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret));
            }
示例#15
0
            /// <summary>
            /// The creator method.
            /// </summary>
            /// <param name="args">A sequence of elements.</param>
            /// <returns>A new list.</returns>
            protected override object doInvoke(object args)
            {
                IArraySeq ias = args as IArraySeq;

                if (ias != null)
                {
                    object[]        argsarray = (object[])ias.ToArray();
                    IPersistentList ret       = EMPTY;
                    for (int i = argsarray.Length - 1; i >= ias.index(); i--)
                    {
                        ret = (IPersistentList)ret.cons(argsarray[i]);
                    }
                    return(ret);
                }

                List <object> list = new List <object>();

                for (ISeq s = RT.seq(args); s != null; s = s.next())
                {
                    list.Add(s.first());
                }
                return(create(list));
            }
示例#16
0
        protected override void EmitMethods(TypeBuilder tb)
        {
            for (ISeq s = RT.seq(_methods); s != null; s = s.next())
            {
                FnMethod method = (FnMethod)s.first();
                method.Emit(this, tb);
            }

            if (IsVariadic)
            {
                EmitGetRequiredArityMethod(_typeBuilder, _variadicMethod.RequiredArity);
            }

            List <int> supportedArities = new List <int>();

            for (ISeq s = RT.seq(_methods); s != null; s = s.next())
            {
                FnMethod method = (FnMethod)s.first();
                supportedArities.Add(method.NumParams);
            }

            EmitHasArityMethod(_typeBuilder, supportedArities, IsVariadic, IsVariadic ? _variadicMethod.RequiredArity : 0);
        }
示例#17
0
            static public object invokeStatic(ISeq args)
            {
                IArraySeq ias = args as IArraySeq;

                if (ias != null)
                {
                    object[]        argsarray = (object[])ias.ToArray();
                    IPersistentList ret       = EMPTY;
                    for (int i = argsarray.Length - 1; i >= 0; i--)
                    {
                        ret = (IPersistentList)ret.cons(argsarray[i]);
                    }
                    return(ret);
                }

                List <object> list = new List <object>();

                for (ISeq s = RT.seq(args); s != null; s = s.next())
                {
                    list.Add(s.first());
                }
                return(create(list));
            }
示例#18
0
        Type Generate(Type superclass, ISeq interfaces, IPersistentMap attributes, string className)
        {
            // define the class
            List <Type> interfaceTypes = new List <Type>
            {
                typeof(IProxy)
            };

            for (ISeq s = interfaces; s != null; s = s.next())
            {
                interfaceTypes.Add((Type)s.first());
            }

            TypeBuilder proxyTB = _context.ModuleBuilder.DefineType(
                className,
                TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed,
                superclass,
                interfaceTypes.ToArray());

            GenInterface.SetCustomAttributes(proxyTB, attributes);

            DefineCtors(proxyTB, superclass);
            MaybeImplementISerializable(proxyTB, interfaceTypes);
            FieldBuilder mapField = AddIProxyMethods(proxyTB);

            HashSet <Type>          allInterfaces  = GetAllInterfaces(interfaces);
            HashSet <MethodBuilder> specialMethods = new HashSet <MethodBuilder>();

            AddInterfaceMethods(proxyTB, mapField, superclass, allInterfaces, specialMethods);
            AddInterfaceProperties(proxyTB, superclass, allInterfaces, specialMethods);  // Must follow AddInterfaceMethods

            Type t = proxyTB.CreateType();

            //if (Compiler.IsCompiling)
            //    SaveProxyContext();
            return(t);
        }
示例#19
0
        /// <summary>
        /// Is one value preferred over another?
        /// </summary>
        /// <param name="x">The first dispatch value.</param>
        /// <param name="y">The second dispatch value.</param>
        /// <returns><value>true</value> if <paramref name="x"/> is preferred over <paramref name="y"/></returns>
        private bool Prefers(object x, object y)
        {
            IPersistentSet xprefs = (IPersistentSet)PreferTable.valAt(x);

            if (xprefs != null && xprefs.contains(y))
            {
                return(true);
            }
            for (ISeq ps = RT.seq(_parents.invoke(y)); ps != null; ps = ps.next())
            {
                if (Prefers(x, ps.first()))
                {
                    return(true);
                }
            }
            for (ISeq ps = RT.seq(_parents.invoke(x)); ps != null; ps = ps.next())
            {
                if (Prefers(ps.first(), y))
                {
                    return(true);
                }
            }
            return(false);
        }
示例#20
0
文件: FnExpr.cs 项目: ryrency/Misc
        private Expression GenerateImmediateLambda(GenContext context, Type baseClass)
        {
            //   ParameterExpression p1 = ThisParam ?? Expression.Parameter(baseClass, "____x");
            ParameterExpression p1 = Expression.Parameter(baseClass, "____x");

            _thisParam = p1;
            List <Expression> exprs = new List <Expression>();

            if (baseClass == typeof(RestFnImpl))
            {
                exprs.Add(Expression.Assign(p1,
                                            Expression.New(Compiler.Ctor_RestFnImpl_1, Expression.Constant(_variadicMethod.RequiredArity))));
            }
            else
            {
                exprs.Add(Expression.Assign(p1, Expression.New(p1.Type)));
            }

            GenContext newContext = CreateContext(context, null, baseClass);

            for (ISeq s = RT.seq(_methods); s != null; s = s.next())
            {
                FnMethod         method    = (FnMethod)s.first();
                LambdaExpression lambda    = method.GenerateImmediateLambda(newContext);
                string           fieldName = IsVariadic && method.IsVariadic
                    ? "_fnDo" + method.RequiredArity
                    : "_fn" + method.NumParams;
                exprs.Add(Expression.Assign(Expression.Field(p1, fieldName), lambda));
            }

            exprs.Add(p1);

            Expression expr = Expression.Block(new ParameterExpression[] { p1 }, exprs);

            return(expr);
        }
        protected override void EmitMethods(TypeBuilder tb)
        {
            HashSet <MethodInfo> implemented = new HashSet <MethodInfo>();

            for (ISeq s = RT.seq(Methods); s != null; s = s.next())
            {
                NewInstanceMethod method = (NewInstanceMethod)s.first();
                method.Emit(this, tb);
                implemented.UnionWith(method.MethodInfos);
            }

            foreach (List <MethodInfo> ms in _methodMap.Values)
            {
                foreach (MethodInfo mi in ms)
                {
                    if (NeedsDummy(mi, implemented))
                    {
                        EmitDummyMethod(tb, mi, true);
                    }
                }
            }

            EmitHasArityMethod(TypeBuilder, null, false, 0);
        }
示例#22
0
 public object this[int index]
 {
     get
     {
         //Java has this: return RT.nth(this, index);
         // THis causes an infinite loop in my code.
         // When this was introduces, a change was made in RT.nth that changed the List test in its type dispatch to RandomAccess.
         // CLR does not have the equivalent notion, so I just left it at IList.  BOOM!
         // So, I have to do a sequential search, duplicating some of the code in RT.nth.
         ISeq seq = this;
         for (int i = 0; i <= index && seq != null; ++i, seq = seq.next())
         {
             if (i == index)
             {
                 return(seq.first());
             }
         }
         throw new ArgumentOutOfRangeException("index");
     }
     set
     {
         throw new InvalidOperationException("Cannot modify an immutable sequence");
     }
 }
示例#23
0
        /// <summary>
        /// Determines whether the specified Object is equal to the current object.
        /// </summary>
        /// <param name="obj">The Object to compare to the current object.</param>
        /// <returns><c>true</c> if the specified Object is equal to the current object; otherwise <c>false</c></returns>
        /// <remarks>Equality is value-based, ie.e. depends on the sequence of items.</remarks>
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }

            if (!(obj is Sequential || obj is IList))
            {
                return(false);
            }

            ISeq ms = RT.seq(obj);

            for (ISeq s = seq(); s != null; s = s.next(), ms = ms.next())
            {
                if (ms == null || !Util.equals(s.first(), ms.first()))
                {
                    return(false);
                }
            }

            return(ms == null); // hit end of sequence on both sequences
        }
示例#24
0
        protected override void GenerateMethods(GenContext context)
        {
            HashSet <MethodInfo> implemented = new HashSet <MethodInfo>();

            for (ISeq s = RT.seq(Methods); s != null; s = s.next())
            {
                NewInstanceMethod method = (NewInstanceMethod)s.first();
                method.GenerateCode(this, context);
                implemented.UnionWith(method.MethodInfos);
            }

            foreach (List <MethodInfo> ms in _methodMap.Values)
            {
                foreach (MethodInfo mi in ms)
                {
                    if (NeedsDummy(mi, implemented))
                    {
                        GenerateDummyMethod(context, mi);
                    }
                }
            }

            GenerateHasArityMethod(TypeBuilder, null, false, 0);
        }
示例#25
0
文件: FnExpr.cs 项目: ryrency/Misc
        //private MethodBuilder GenerateConstants(TypeBuilder fnTB, Type baseType)
        //{
        //    try
        //    {
        //        Var.pushThreadBindings(RT.map(RT.PRINT_DUP, RT.T));

        //        List<Expression> inits = new List<Expression>();
        //        for (int i = 0; i < _constants.count(); i++)
        //        {
        //            object o = _constants.nth(i);
        //            string stringValue = null;
        //            if (o is string)
        //                stringValue = (string)o;
        //            else
        //            {
        //                try
        //                {
        //                    stringValue = RT.printString(o);
        //                }
        //                catch (Exception)
        //                {
        //                    throw new Exception(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", o));
        //                }
        //                if (stringValue.Length == 0)
        //                    throw new Exception(String.Format("Can't embed unreadable object in code: " + o));
        //                if (stringValue.StartsWith("#<"))
        //                    throw new Exception(String.Format("Can't embed unreadable object in code: " + stringValue));
        //            }
        //            Expression init =
        //                Expression.Assign(
        //                    Expression.Field(null, baseType, ConstantName(i)),
        //                    Expression.Convert(Expression.Call(Compiler.Method_RT_readString, Expression.Constant(stringValue)),
        //                                       ConstantType(i)));
        //            inits.Add(init);
        //        }
        //        inits.Add(Expression.Default(typeof(void)));

        //        Expression block = Expression.Block(inits);
        //        LambdaExpression lambda = Expression.Lambda(block);
        //        MethodBuilder methodBuilder = fnTB.DefineMethod(STATIC_CTOR_HELPER_NAME, MethodAttributes.Private | MethodAttributes.Static);
        //        lambda.CompileToMethod(methodBuilder);
        //        return methodBuilder;
        //    }
        //    finally
        //    {
        //        Var.popThreadBindings();
        //    }

        //}

        private ConstructorBuilder GenerateConstructor(TypeBuilder fnTB, Type baseType)
        {
            ConstructorBuilder cb  = fnTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, CtorTypes());
            ILGenerator        gen = cb.GetILGenerator();
            //Call base constructor
            ConstructorInfo baseCtorInfo = baseType.GetConstructor(EMPTY_TYPE_ARRAY);

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Call, baseCtorInfo);

            int a = 0;

            for (ISeq s = RT.keys(_closes); s != null; s = s.next(), a++)
            {
                LocalBinding lb = (LocalBinding)s.first();
                FieldBuilder fb = _closedOverFields[a];

                gen.Emit(OpCodes.Ldarg_0);
                gen.Emit(OpCodes.Ldarg, a + 1);
                gen.Emit(OpCodes.Stfld, fb);
            }
            gen.Emit(OpCodes.Ret);
            return(cb);
        }
示例#26
0
        public object this[int index]
        {
            get
            {
                if (index < 0)
                {
                    throw new ArgumentOutOfRangeException("index", "Index must be non-negative.");
                }

                ISeq s = seq();
                for (int i = 0; s != null; s = s.next(), i++)
                {
                    if (i == index)
                    {
                        return(s.first());
                    }
                }
                throw new ArgumentOutOfRangeException("index", "Index past end of sequence.");
            }
            set
            {
                throw new InvalidOperationException();
            }
        }
示例#27
0
 private static Object process_output(Object o, int level)
 {
     if (o is IPersistentCollection)
     {
         o = ((IPersistentCollection)o).seq();
     }
     if (o is ISeq)
     {
         ISeq     r2     = (ISeq)o;
         object[] outArr = new object[r2.count()];
         int      i      = 0;
         while (r2 != null)
         {
             outArr[i] = level == 1 ? process_output(r2.first(), 0) : cleanValue(r2.first());
             i++;
             r2 = r2.next();
         }
         return(level == 1 ? pack(outArr) : outArr);
     }
     else
     {
         return(level == 1 ? pack(cleanValue(o)) : cleanValue(o));
     }
 }
示例#28
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                string         source  = (string)Compiler.SourceVar.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();  // Compiler.GetSourceSpanMap(form);

                ISeq form = (ISeq)frm;

                IPersistentVector loopLocals = (IPersistentVector)Compiler.LoopLocalsVar.deref();

                if (pcon.Rhc != RHC.Return || loopLocals == null)
                {
                    throw new ParseException("Can only recur from tail position");
                }

                if (Compiler.NoRecurVar.deref() != null)
                {
                    throw new ParseException("Cannot recur across try");
                }

                IPersistentVector args = PersistentVector.EMPTY;

                for (ISeq s = RT.seq(form.next()); s != null; s = s.next())
                {
                    args = args.cons(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), s.first()));
                }
                if (args.count() != loopLocals.count())
                {
                    throw new ParseException(string.Format("Mismatched argument count to recur, expected: {0} args, got {1}",
                                                           loopLocals.count(), args.count()));
                }

                for (int i = 0; i < loopLocals.count(); i++)
                {
                    LocalBinding lb    = (LocalBinding)loopLocals.nth(i);
                    Type         primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        bool mismatch = false;
                        Type pt       = Compiler.MaybePrimitiveType((Expr)args.nth(i));
                        if (primt == typeof(long))
                        {
                            if (!(pt == typeof(long) || pt == typeof(int) || pt == typeof(short) || pt == typeof(uint) || pt == typeof(ushort) || pt == typeof(ulong) ||
                                  pt == typeof(char) || pt == typeof(byte) || pt == typeof(sbyte)))
                            {
                                mismatch = true;
                            }
                        }
                        else if (primt == typeof(double))
                        {
                            if (!(pt == typeof(double) || pt == typeof(float)))
                            {
                                mismatch = true;
                            }
                        }

                        if (mismatch)
                        {
                            lb.RecurMismatch = true;
                            if (RT.booleanCast(RT.WarnOnReflectionVar.deref()))
                            {
                                RT.errPrintWriter().WriteLine("{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                                              source, spanMap != null ? (int)spanMap.valAt(RT.StartLineKey, 0) : 0,
                                                              lb.Name, pt != null ? pt.Name : "Object", primt.Name);
                            }
                        }
                    }
                }


                return(new RecurExpr(source, spanMap, loopLocals, args));
            }
示例#29
0
        public override object applyTo(ISeq args)
        {
            int reqArity = getRequiredArity();

            if (RT.BoundedLength(args, reqArity) <= reqArity)
                return AFn.ApplyToHelper(this, Util.Ret1(args, args = null));

            switch (reqArity)
            {
                case 0:
                    return doInvoke(Util.Ret1(args, args = null));
                case 1:
                    return doInvoke(args.first()
                            , Util.Ret1(args.next(), args = null));
                case 2:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 3:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 4:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 5:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 6:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 7:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 8:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 9:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 10:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 11:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 12:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 13:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 14:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 15:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 16:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 17:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 18:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 19:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));
                case 20:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , Util.Ret1(args.next(), args = null));

            }
            throw WrongArityException(-1);
        }
示例#30
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvalOrExpr();

            Expr    fexpr    = Compiler.Analyze(pcon, form.first());
            VarExpr varFexpr = fexpr as VarExpr;

            if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar))
            {
                if (RT.second(form) is Symbol)
                {
                    Type t = HostExpr.MaybeType(RT.second(form), false);
                    if (t != null)
                    {
                        return(new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), t, Compiler.Analyze(pcon, RT.third(form))));
                    }
                }
            }

            if (varFexpr != null && pcon.Rhc != RHC.Eval)
            {
                Var    v        = varFexpr.Var;
                object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword);
                int    arity    = RT.count(form.next());
                for (ISeq s = RT.seq(arglists); s != null; s = s.next())
                {
                    IPersistentVector sargs = (IPersistentVector)s.first();
                    if (sargs.count() == arity)
                    {
                        string primc = FnMethod.PrimInterface(sargs);
                        if (primc != null)
                        {
                            return(Compiler.Analyze(pcon,
                                                    RT.listStar(Symbol.intern(".invokePrim"),
                                                                ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))),
                                                                form.next())));
                        }
                        break;
                    }
                }
            }

            KeywordExpr kwFexpr = fexpr as KeywordExpr;

            if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound)
            {
                Expr target = Compiler.Analyze(pcon, RT.second(form));
                return(new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target));
            }

            IPersistentVector args = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form.next()); s != null; s = s.next())
            {
                args = args.cons(Compiler.Analyze(pcon, s.first()));
            }

            //if (args.count() > Compiler.MAX_POSITIONAL_ARITY)
            //    throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY));

            return(new InvokeExpr((string)Compiler.SourceVar.deref(),
                                  (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form),
                                  Compiler.TagOf(form),
                                  fexpr,
                                  args));
        }
示例#31
0
        internal static ObjExpr Build(
            IPersistentVector interfaceSyms,
            IPersistentVector fieldSyms,
            Symbol thisSym,
            string tagName,
            Symbol className,
            Symbol typeTag,
            ISeq methodForms,
            Object frm)
        {
            NewInstanceExpr ret = new NewInstanceExpr(null);

            ret._src         = frm;
            ret._name        = className.ToString();
            ret._classMeta   = GenInterface.ExtractAttributes(RT.meta(className));
            ret.InternalName = ret.Name;  // ret.Name.Replace('.', '/');
            // Java: ret.objtype = Type.getObjectType(ret.internalName);

            if (thisSym != null)
            {
                ret._thisName = thisSym.Name;
            }

            if (fieldSyms != null)
            {
                IPersistentMap fmap      = PersistentHashMap.EMPTY;
                object[]       closesvec = new object[2 * fieldSyms.count()];
                for (int i = 0; i < fieldSyms.count(); i++)
                {
                    Symbol       sym = (Symbol)fieldSyms.nth(i);
                    LocalBinding lb  = new LocalBinding(-1, sym, null, new MethodParamExpr(Compiler.TagType(Compiler.TagOf(sym))), false, false);
                    fmap                 = fmap.assoc(sym, lb);
                    closesvec[i * 2]     = lb;
                    closesvec[i * 2 + 1] = lb;
                }
                // Java TODO: inject __meta et al into closes - when?
                // use array map to preserve ctor order
                ret._closes = new PersistentArrayMap(closesvec);
                ret._fields = fmap;
                for (int i = fieldSyms.count() - 1; i >= 0 && ((Symbol)fieldSyms.nth(i)).Name.StartsWith("__"); --i)
                {
                    ret._altCtorDrops++;
                }
            }

            // Java TODO: set up volatiles
            //ret._volatiles = PersistentHashSet.create(RT.seq(RT.get(ret._optionsMap, volatileKey)));

            IPersistentVector interfaces = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(interfaceSyms); s != null; s = s.next())
            {
                Type t = (Type)Compiler.Resolve((Symbol)s.first());
                if (!t.IsInterface)
                {
                    throw new ParseException("only interfaces are supported, had: " + t.Name);
                }
                interfaces = interfaces.cons(t);
            }
            Type superClass = typeof(Object);

            Dictionary <IPersistentVector, List <MethodInfo> > overrideables;

            GatherMethods(superClass, RT.seq(interfaces), out overrideables);

            ret._methodMap = overrideables;

            //string[] inames = InterfaceNames(interfaces);

            Type   stub    = CompileStub(superClass, ret, SeqToTypeArray(interfaces), frm);
            Symbol thisTag = Symbol.intern(null, stub.FullName);
            //Symbol stubTag = Symbol.intern(null,stub.FullName);
            //Symbol thisTag = Symbol.intern(null, tagName);

            // Needs its own GenContext so it has its own DynInitHelper
            // Can't reuse Compiler.EvalContext if it is a DefType because we have to use the given name and will get a conflict on redefinition
            GenContext context = Compiler.CompilerContextVar.get() as GenContext ?? (ret.IsDefType ? GenContext.CreateWithExternalAssembly("deftype" + RT.nextID().ToString(), ".dll", true) : Compiler.EvalContext);
            GenContext genC    = context.WithNewDynInitHelper(ret.InternalName + "__dynInitHelper_" + RT.nextID().ToString());

            //genC.FnCompileMode = FnMode.Full;

            try
            {
                Var.pushThreadBindings(
                    RT.map(
                        Compiler.ConstantsVar, PersistentVector.EMPTY,
                        Compiler.ConstantIdsVar, new IdentityHashMap(),
                        Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                        Compiler.VarsVar, PersistentHashMap.EMPTY,
                        Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                        Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                        Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                        Compiler.NoRecurVar, null,
                        Compiler.CompilerContextVar, genC
                        ));

                if (ret.IsDefType)
                {
                    Var.pushThreadBindings(
                        RT.map(
                            Compiler.MethodVar, null,
                            Compiler.LocalEnvVar, ret._fields,
                            Compiler.CompileStubSymVar, Symbol.intern(null, tagName),
                            Compiler.CompileStubClassVar, stub
                            ));
                    ret._hintedFields = RT.subvec(fieldSyms, 0, fieldSyms.count() - ret._altCtorDrops);
                }
                // now (methodname [args] body)*
                // TODO: SourceLocation?
                //ret.line = (Integer)LINE.deref();
                IPersistentCollection methods = null;
                for (ISeq s = methodForms; s != null; s = RT.next(s))
                {
                    NewInstanceMethod m = NewInstanceMethod.Parse(ret, (ISeq)RT.first(s), thisTag, overrideables);
                    methods = RT.conj(methods, m);
                }

                ret.Methods           = methods;
                ret.Keywords          = (IPersistentMap)Compiler.KeywordsVar.deref();
                ret.Vars              = (IPersistentMap)Compiler.VarsVar.deref();
                ret.Constants         = (PersistentVector)Compiler.ConstantsVar.deref();
                ret._constantsID      = RT.nextID();
                ret.KeywordCallsites  = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                ret.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                ret.VarCallsites      = (IPersistentSet)Compiler.VarCallsitesVar.deref();
            }
            finally
            {
                if (ret.IsDefType)
                {
                    Var.popThreadBindings();
                }
                Var.popThreadBindings();
            }

            // TOD:  Really, the first stub here should be 'superclass' but can't handle hostexprs nested in method bodies -- reify method compilation takes place before this sucker is compiled, so can't replace the call.
            // Might be able to flag stub classes and not try to convert, leading to a dynsite.
            ret.Compile(stub, stub, interfaces, false, genC);
            Compiler.RegisterDuplicateType(ret.CompiledType);

            return(ret);
        }
示例#32
0
        private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields)
        {
            for (ISeq s = RT.seq(exposesFields); s != null; s = s.next())
            {
                IMapEntry      me = (IMapEntry)s.first();
                Symbol         protectedFieldSym = (Symbol)me.key();
                IPersistentMap accessMap         = (IPersistentMap)me.val();

                string fieldName = protectedFieldSym.Name;
                Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null);
                Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null);

                FieldInfo fld = null;

                if (getterSym != null || setterSym != null)
                {
                    fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance);
                }


                if (getterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                    {
                        attribs |= MethodAttributes.Static;
                    }

                    MethodBuilder mb  = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes);
                    CljILGen      gen = new CljILGen(mb.GetILGenerator());
                    //if (fld.IsStatic)
                    //    gen.Emit(OpCodes.Ldsfld, fld);
                    //else
                    //{
                    //    gen.Emit(OpCodes.Ldarg_0);
                    //    gen.Emit(OpCodes.Ldfld, fld);
                    //}
                    if (!fld.IsStatic)
                    {
                        gen.EmitLoadArg(0);
                    }
                    gen.MaybeEmitVolatileOp(fld);
                    gen.EmitFieldGet(fld);

                    gen.Emit(OpCodes.Ret);
                }

                if (setterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                    {
                        attribs |= MethodAttributes.Static;
                    }

                    MethodBuilder mb  = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType });
                    CljILGen      gen = new CljILGen(mb.GetILGenerator());
                    if (fld.IsStatic)
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        //gen.Emit(OpCodes.Stsfld, fld);
                    }
                    else
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        gen.Emit(OpCodes.Ldarg_1);
                        //gen.Emit(OpCodes.Stfld, fld);
                    }
                    gen.MaybeEmitVolatileOp(fld);
                    gen.EmitFieldSet(fld);
                    gen.Emit(OpCodes.Ret);
                }
            }
        }
        static void GatherMethods(
            Type st,
            ISeq interfaces,
            out Dictionary<IPersistentVector, List<MethodInfo>> overrides)
        {
            Dictionary<IPersistentVector, List<MethodInfo>> allm = new Dictionary<IPersistentVector, List<MethodInfo>>();
            GatherMethods(st, allm);
            for (; interfaces != null; interfaces = interfaces.next())
                GatherMethods((Type)interfaces.first(), allm);

            overrides = allm;
        }
示例#34
0
        private static Expression GenerateLetExpr(ISeq form)
        {
            // form => (let [var1 val1 var2 val2 ... ] body ... )
            //      or (loop [var1 val1 var2 val2 ... ] body ... )

            bool isLoop = form.first().Equals(Compiler.LOOP);
            IPersistentVector bindings = RT.second(form) as IPersistentVector;

            if (bindings == null)
                throw new ArgumentException("Bad binding form, expected vector");

            if ((bindings.count() % 2) != 0)
                throw new ArgumentException("Bad binding form, expected matched symbol/value pairs.");

            ISeq body = RT.next(RT.next(form));

            // TODO: This is one place where context makes a difference.  Need to figure this out.
            //  Second test clause added in Rev 1216.
            //if (ctxt == C.EVAL || (context == c.EXPRESSION && isLoop))
            //    return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));

            // As of Rev 1216, I tried it out.
            // However, it goes into an infinite loop.  Still need to figure this out.
            //if (isLoop)
            //    Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));

            IPersistentMap dynamicBindings = PersistentHashMap.create(LOCAL_ENV, LOCAL_ENV.deref());

            if (isLoop)
                dynamicBindings = dynamicBindings.assoc(LOOP_LOCALS, null);

            try
            {
                Var.pushThreadBindings(dynamicBindings);
                IPersistentVector bindingInits = PersistentVector.EMPTY;
                IPersistentVector loopLocals = PersistentVector.EMPTY;

                for ( int i=0; i<bindings.count(); i+=2 )
                {
                    if (!(bindings.nth(i) is Symbol))
                        throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i));
                    Symbol sym = (Symbol) bindings.nth(i);
                    if ( sym.Namespace != null )
                        throw new Exception("Can't let qualified name: " + sym);
                    Expression init = Generate(/*C.EXPRESSION, */ bindings.nth(i+1) /* , sym.Name */);
                    // Sequential enhancement of env (like Lisp let*)
                    LocalBinding b = RegisterLocal(sym,TagOf(sym),init);
                    b.ParamExpression = Expression.Variable(typeof(object), b.Name);  //asdf-tag
                    bindingInits = bindingInits.cons(new BindingInit(b,init));

                    if ( isLoop )
                        loopLocals = loopLocals.cons(b);
                }
                if ( isLoop )
                    LOOP_LOCALS.set(loopLocals);

                LabelTarget loopLabel = Expression.Label();

                List<ParameterExpression> parms = new List<ParameterExpression>();
                List<Expression> forms = new List<Expression>();

                for ( int i=0; i<bindingInits.count(); i++ )
                {
                    BindingInit bi = (BindingInit) bindingInits.nth(i);
                    ParameterExpression parmExpr = (ParameterExpression) bi.Binding.ParamExpression;
                    parms.Add(parmExpr);
                    forms.Add(Expression.Assign(parmExpr,MaybeBox(bi.Init)));
                }

                forms.Add(Expression.Label(loopLabel));

                try
                {
                    if ( isLoop )
                        Var.pushThreadBindings(PersistentHashMap.create(LOOP_LABEL,loopLabel));

                    forms.Add(GenerateBodyExpr(  /* isLoop ? C.RETURN : context , */ body));
                }
                finally
                {
                    if ( isLoop )
                        Var.popThreadBindings();
                }

                Expression block = Expression.Block(parms,forms);
                return block;
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
示例#35
0
 /// <summary>
 /// Create a <see cref="PersistentVector">PersistentVector</see> from an <see cref="ISeq">ISeq</see>.
 /// </summary>
 /// <param name="items">A sequence of items.</param>
 /// <returns>An initialized vector.</returns>
 public static PersistentVector create(ISeq items)
 {
     IPersistentVector ret = EMPTY;
     for (; items != null; items = items.next())
         ret = ret.cons(items.first());
     return (PersistentVector)ret;
 }
示例#36
0
        //static string[] InterfaceNames(IPersistentVector interfaces)
        //{
        //    int icnt = interfaces.count();
        //    string[] inames = icnt > 0 ? new string[icnt] : null;
        //    for (int i = 0; i < icnt; i++)
        //        inames[i] = SlashName((Type)interfaces.nth(i));
        //    return inames;
        //}

        //static string SlashName(Type t)
        //{
        //    return t.FullName.Replace(',', '/');
        //}

        #endregion

        #region Method reflection

        static void GatherMethods(
            Type st,
            ISeq interfaces,
            out Dictionary<IPersistentVector, IList<MethodInfo>> overrides,
            out Dictionary<IPersistentVector, IList<MethodInfo>> explicits)
        {
            overrides = new Dictionary<IPersistentVector, IList<MethodInfo>>();
            explicits = new Dictionary<IPersistentVector, IList<MethodInfo>>();

            GatherMethods(st, overrides);
            for (; interfaces != null; interfaces = interfaces.next()) {
                GatherMethods((Type)interfaces.first(), overrides);
                GatherInterfaceExplicits((Type)interfaces.first(),explicits);
            }
        }
示例#37
0
 public static PersistentHashMap createWithCheck(ISeq items)
 {
     ITransientMap ret = (ITransientMap)EMPTY.asTransient();
     for (int i = 0; items != null; items = items.next().next(), ++i)
     {
         if (items.next() == null)
             throw new ArgumentException(String.Format("No value supplied for key: {0}", items.first()));
         ret = ret.assoc(items.first(), RT.second(items));
         if (ret.count() != i + 1)
             throw new ArgumentException("Duplicate key: " + items.first());
     }
     return (PersistentHashMap)ret.persistent();
 }
示例#38
0
 /// <summary>
 /// Create a <see cref="PersistentHashMap">PersistentHashMap</see> initialized from 
 /// an <see cref="ISeq">ISeq</see> of alternating keys and values.
 /// </summary>
 /// <param name="items">An <see cref="ISeq">ISeq</see> of alternating keys and values.</param>
 /// <returns>A <see cref="PersistentHashMap">PersistentHashMap</see>.</returns>
 public static PersistentHashMap create(ISeq items)
 {
     ITransientMap ret = (ITransientMap)EMPTY.asTransient();
     for (; items != null; items = items.next().next())
     {
         if ( items.next() == null )
             throw new ArgumentException(String.Format("No value supplied for key: {0}", items.first()));
         ret = ret.assoc(items.first(), RT.second(items) );
     }
     return (PersistentHashMap)ret.persistent();
 }
示例#39
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvalOrExpr();

            Expr fexpr = Compiler.Analyze(pcon,form.first());
            VarExpr varFexpr = fexpr as VarExpr;

            if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar))
            {
                if ( RT.second(form) is Symbol )
                {
                    Type t = HostExpr.MaybeType(RT.second(form),false);
                    if ( t != null )
                        return new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), t, Compiler.Analyze(pcon,RT.third(form)));
                }
            }

            if (varFexpr != null && pcon.Rhc != RHC.Eval)
            {
                Var v = varFexpr.Var;
                object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword);
                int arity = RT.count(form.next());
                for (ISeq s = RT.seq(arglists); s != null; s = s.next())
                {
                    IPersistentVector sargs = (IPersistentVector)s.first();
                    if (sargs.count() == arity)
                    {
                        string primc = FnMethod.PrimInterface(sargs);
                        if (primc != null)
                            return Compiler.Analyze(pcon,
                                RT.listStar(Symbol.intern(".invokePrim"),
                                            ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))),
                                            form.next()));
                        break;
                    }
                }
            }

            KeywordExpr kwFexpr = fexpr as KeywordExpr;

            if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound)
            {
                Expr target = Compiler.Analyze(pcon, RT.second(form));
                return new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target);
            }

            IPersistentVector args = PersistentVector.EMPTY;
            for ( ISeq s = RT.seq(form.next()); s != null; s = s.next())
                args = args.cons(Compiler.Analyze(pcon,s.first()));

            //if (args.count() > Compiler.MAX_POSITIONAL_ARITY)
            //    throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY));

            return new InvokeExpr((string)Compiler.SourceVar.deref(),
                (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form),
                Compiler.TagOf(form),
                fexpr,
                args);
        }
示例#40
0
 public static PersistentHashSet createWithCheck(ISeq items)
 {
     ITransientSet ret = (ITransientSet)EMPTY.asTransient(); 
     for (int i = 0; items != null; items = items.next(), ++i)
     {
         ret = (ITransientSet)ret.conj(items.first());
         if (ret.count() != i + 1)
             throw new ArgumentException("Duplicate key: " + items.first());
     }
     return (PersistentHashSet)ret.persistent();
 }
示例#41
0
        public static Type GenerateClass(string className,
                                         Type superclass,
                                         ISeq interfaces, // of Types
                                         ISeq ctors,
                                         ISeq ctorTypes,
                                         ISeq methods,
                                         IPersistentMap exposesFields,
                                         IPersistentMap exposesMethods,
                                         string prefix,
                                         bool hasMain,
                                         string factoryName,
                                         string stateName,
                                         string initName,
                                         string postInitName,
                                         string implCname,
                                         string implNamespace,
                                         bool loadImplNamespace,
                                         IPersistentMap attributes)
        {
            className = className.Replace('-', '_');

            string path = (string)Compiler.CompilePathVar.deref();

            if (path == null)
            {
                throw new InvalidOperationException("*compile-path* not set");
            }

            string extension = hasMain ? ".exe" : ".dll";


            GenContext context = GenContext.CreateWithExternalAssembly(Compiler.munge(className), extension, true);

            // define the class
            List <Type> interfaceTypes = new List <Type>();

            for (ISeq s = interfaces; s != null; s = s.next())
            {
                interfaceTypes.Add((Type)s.first());
            }


            TypeBuilder proxyTB = context.ModuleBuilder.DefineType(
                className,
                TypeAttributes.Class | TypeAttributes.Public,
                superclass,
                interfaceTypes.ToArray());

            GenInterface.SetCustomAttributes(proxyTB, attributes);

            List <MethodSignature> sigs = GetAllSignatures(superclass, interfaceTypes, methods);
            Dictionary <string, List <MethodSignature> > overloads = ComputeOverloads(sigs);

            HashSet <string> varNames = ComputeOverloadNames(overloads);

            foreach (MethodSignature sig in sigs)
            {
                varNames.Add(sig.Name);
            }

            if (!String.IsNullOrEmpty(initName))
            {
                varNames.Add(initName);
            }
            if (!String.IsNullOrEmpty(postInitName))
            {
                varNames.Add(postInitName);
            }
            if (hasMain)
            {
                varNames.Add(_mainName);
            }

            Dictionary <string, FieldBuilder> varMap = DefineStaticFields(proxyTB, varNames);

            FieldBuilder stateFB = String.IsNullOrEmpty(stateName) ? null : DefineStateField(proxyTB, stateName);

            DefineStaticCtor(proxyTB, prefix, varMap, loadImplNamespace, implNamespace, implCname);

            varMap.TryGetValue(initName, out FieldBuilder initFB);
            varMap.TryGetValue(postInitName, out FieldBuilder postInitFB);
            varMap.TryGetValue(_mainName, out FieldBuilder mainFB);

            DefineCtors(proxyTB, superclass,
                        implNamespace + "." + prefix + initName,
                        implNamespace + "." + prefix + postInitName,
                        ctors, ctorTypes, initFB, postInitFB, stateFB, factoryName);

            EmitMethods(proxyTB, sigs, overloads, varMap, exposesMethods);
            EmitExposers(proxyTB, superclass, exposesFields);

            if (hasMain)
            {
                EmitMain(context, proxyTB, implNamespace + "." + prefix + _mainName, mainFB);
            }

            Type t = proxyTB.CreateType();

            context.SaveAssembly();

            return(t);
        }
示例#42
0
 // do we need this?
 protected static ISeq FindKey(object key, ISeq args)
 {
     while (args != null)
     {
         if (key == args.first())
             return args.next();
         args = RT.next(args);
         args = RT.next(args);
     }
     return null;
 }
示例#43
0
 public static PersistentVector create(ISeq items)
 {
     ITransientCollection ret = EMPTY.asTransient();
     for (; items != null; items = items.next())
         ret = ret.conj(items.first());
     return (PersistentVector)ret.persistent();
 }
 /// <summary>
 /// Create a <see cref="PersistentTreeMap">PersistentTreeMap</see> from a comparison method
 /// an <see cref="ISeq">ISeq</see> of alternating keys and values.
 /// </summary>
 /// <param name="comp">A comparison method.</param>
 /// <param name="items">The <see cref="ISeq">ISeq</see>  of alternating keys and values.</param>
 /// <returns>A <see cref="PersistentTreeMap">PersistentTreeMap</see>.</returns>
 public static PersistentTreeMap create(IComparer comp, ISeq items)
 {
     IPersistentMap ret = new PersistentTreeMap(comp);
     for (; items != null; items = items.rest().rest())
     {
         if (items.rest() == null)
             throw new ArgumentException(string.Format("No value supplied for key: %s", items.first()));
         ret = ret.assoc(items.first(), items.rest().first());
     }
     return (PersistentTreeMap)ret;
 }
示例#45
0
        /***
         * Current host interop uses reflection, which requires pre-existing classes
         * Work around this by:
         * Generate a stub class that has the same interfaces and fields as the class we are generating.
         * Use it as a type hint for this, and bind the simple name of the class to this stub (in resolve etc)
         * Unmunge the name (using a magic prefix) on any code gen for classes
         */
        static Type CompileStub(Type super, NewInstanceExpr ret, Type[] interfaces, Object frm)
        {
            GenContext  context = Compiler.CompilerContextVar.get() as GenContext ?? GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false);
            TypeBuilder tb      = context.ModuleBuilder.DefineType(Compiler.CompileStubPrefix + "." + ret.InternalName, TypeAttributes.Public | TypeAttributes.Abstract, super, interfaces);

            tb.DefineDefaultConstructor(MethodAttributes.Public);

            // instance fields for closed-overs
            for (ISeq s = RT.keys(ret.Closes); s != null; s = s.next())
            {
                LocalBinding    lb     = (LocalBinding)s.first();
                FieldAttributes access = FieldAttributes.Public;

                // TODO: FIgure out Volatile
                if (!ret.IsVolatile(lb))
                {
                    access |= FieldAttributes.InitOnly;
                }

                if (lb.PrimitiveType != null)
                {
                    tb.DefineField(lb.Name, lb.PrimitiveType, access);
                }
                else
                {
                    tb.DefineField(lb.Name, typeof(Object), access);
                }
            }

            // ctor that takes closed-overs and does nothing
            if (ret.CtorTypes().Length > 0)
            {
                ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, ret.CtorTypes());
                ILGen ilg             = new ILGen(cb.GetILGenerator());
                ilg.EmitLoadArg(0);
                ilg.Emit(OpCodes.Call, super.GetConstructor(Type.EmptyTypes));
                ilg.Emit(OpCodes.Ret);


                if (ret._altCtorDrops > 0)
                {
                    Type[] ctorTypes = ret.CtorTypes();
                    int    newLen    = ctorTypes.Length - ret._altCtorDrops;
                    if (newLen > 0)
                    {
                        Type[] altCtorTypes = new Type[newLen];
                        for (int i = 0; i < altCtorTypes.Length; i++)
                        {
                            altCtorTypes[i] = ctorTypes[i];
                        }
                        ConstructorBuilder cb2 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, altCtorTypes);
                        ILGen ilg2             = new ILGen(cb2.GetILGenerator());
                        ilg2.EmitLoadArg(0);
                        for (int i = 0; i < newLen; i++)
                        {
                            ilg2.EmitLoadArg(i + 1);
                        }
                        for (int i = 0; i < ret._altCtorDrops; i++)
                        {
                            ilg2.EmitNull();
                        }
                        ilg2.Emit(OpCodes.Call, cb);
                        ilg2.Emit(OpCodes.Ret);
                    }
                }
            }

            Type t = tb.CreateType();

            Compiler.RegisterDuplicateType(t);
            return(t);
        }
 /// <summary>
 /// Create a <see cref="PersistentHashMap">PersistentHashMap</see> initialized from 
 /// an <see cref="ISeq">ISeq</see> of alternating keys and values.
 /// </summary>
 /// <param name="items">An <see cref="ISeq">ISeq</see> of alternating keys and values.</param>
 /// <returns>A <see cref="PersistentHashMap">PersistentHashMap</see>.</returns>
 public static PersistentHashMap create(ISeq items)
 {
     IPersistentMap ret = EMPTY;
     for ( ; items != null; items = items.rest().rest() )
     {
         if ( items.rest() == null )
             throw new ArgumentException(String.Format("No value supplied for key: {0}", items.first()));
         ret = ret.assoc(items.first(), items.rest().first() );
     }
     return (PersistentHashMap)ret;
 }
示例#47
0
        protected override void GenerateStatics(GenContext context)
        {
            if (IsDefType)
            {
                TypeBuilder tb = TypeBuilder;

                // getBasis()
                MethodBuilder    mbg    = tb.DefineMethod("getBasis", MethodAttributes.Public | MethodAttributes.Static, typeof(IPersistentVector), Type.EmptyTypes);
                LambdaExpression lambda = Expression.Lambda(GenerateValue(_hintedFields));
                lambda.CompileToMethod(mbg, context.IsDebuggable);

                if (_fields.count() > _hintedFields.count())
                {
                    // create(IPersistentMap)
                    MethodBuilder mbc = tb.DefineMethod("create", MethodAttributes.Public | MethodAttributes.Static, tb, new Type[] { typeof(IPersistentMap) });
                    ILGen         gen = new ILGen(mbc.GetILGenerator());

                    LocalBuilder        kwLocal = gen.DeclareLocal(typeof(Keyword));
                    List <LocalBuilder> locals  = new List <LocalBuilder>();
                    for (ISeq s = RT.seq(_hintedFields); s != null; s = s.next())
                    {
                        string bName = ((Symbol)s.first()).Name;
                        Type   t     = Compiler.TagType(Compiler.TagOf(s.first()));

                        // local_kw = Keyword.intern(bname)
                        // local_i = arg_0.valAt(kw,null)
                        gen.EmitLoadArg(0);
                        gen.EmitString(bName);
                        gen.EmitCall(Compiler.Method_Keyword_intern_string);
                        gen.Emit(OpCodes.Dup);
                        gen.Emit(OpCodes.Stloc, kwLocal.LocalIndex);
                        gen.EmitNull();
                        gen.EmitCall(Compiler.Method_IPersistentMap_valAt2);
                        LocalBuilder lb = gen.DeclareLocal(t);
                        locals.Add(lb);
                        if (t.IsPrimitive)
                        {
                            gen.EmitUnbox(t);
                        }
                        gen.Emit(OpCodes.Stloc, lb.LocalIndex);

                        // arg_0 = arg_0.without(local_kw);
                        gen.EmitLoadArg(0);
                        gen.Emit(OpCodes.Ldloc, kwLocal.LocalIndex);
                        gen.EmitCall(Compiler.Method_IPersistentMap_without);
                        gen.EmitStoreArg(0);
                    }

                    foreach (LocalBuilder lb in locals)
                    {
                        gen.Emit(OpCodes.Ldloc, lb.LocalIndex);
                    }
                    gen.EmitNull();
                    gen.EmitLoadArg(0);
                    gen.EmitCall(Compiler.Method_RT_seqOrElse);
                    gen.EmitNew(CtorInfo);

                    gen.Emit(OpCodes.Ret);
                }
            }
        }
 /// <summary>
 /// Create a struct from a struct definition and a sequence of alternating keys and values.
 /// </summary>
 /// <param name="def">The struct definition</param>
 /// <param name="keyvals">A sequence of alternating keys and values.</param>
 /// <returns>A <see cref="PersistentStructMap">PersistentStructMap</see>.</returns>
 public static PersistentStructMap create(Def def, ISeq keyvals)
 {
     object[] vals = new object[def.Keyslots.count()];
     IPersistentMap ext = PersistentHashMap.EMPTY;
     for (; keyvals != null; keyvals = keyvals.rest().rest())
     {
         if (keyvals.rest() == null)
             throw new ArgumentException(String.Format("No value supplied for key: {0}", keyvals.first()));
         object k = keyvals.first();
         object v = keyvals.rest().first();
         IMapEntry me = def.Keyslots.entryAt(k);
         if (me != null)
             vals[Util.ConvertToInt(me.val())] = v;
         else
             ext = ext.assoc(k, v);
     }
     return new PersistentStructMap(null, def, vals, ext);
 }
示例#49
0
        public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args)
        {
            _source  = source;
            _spanMap = spanMap;
            _fexpr   = fexpr;
            _args    = args;

            VarExpr varFexpr = fexpr as VarExpr;

            if (varFexpr != null)
            {
                Var fvar = varFexpr.Var;
                Var pvar = (Var)RT.get(fvar.meta(), Compiler.ProtocolKeyword);
                if (pvar != null && Compiler.ProtocolCallsitesVar.isBound)
                {
                    _isProtocol = true;
                    _siteIndex  = Compiler.RegisterProtocolCallsite(fvar);
                    Object pon = RT.get(pvar.get(), _onKey);
                    _protocolOn = HostExpr.MaybeType(pon, false);
                    if (_protocolOn != null)
                    {
                        IPersistentMap mmap    = (IPersistentMap)RT.get(pvar.get(), _methodMapKey);
                        Keyword        mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym));
                        if (mmapVal == null)
                        {
                            throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)",
                                                                      _protocolOn.FullName, fvar.Symbol, pvar.Symbol));
                        }
                        String mname = Compiler.munge(mmapVal.Symbol.ToString());

                        IList <MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false);
                        if (methods.Count != 1)
                        {
                            throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}",
                                                                      mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol));
                        }
                        _onMethod = (MethodInfo)methods[0];
                    }
                }
            }

            if (tag != null)
            {
                _tag = tag;
            }
            else if (varFexpr != null)
            {
                object arglists = RT.get(RT.meta(varFexpr.Var), Compiler.ArglistsKeyword);
                object sigTag   = null;
                for (ISeq s = RT.seq(arglists); s != null; s = s.next())
                {
                    APersistentVector sig = (APersistentVector)s.first();
                    int restOffset        = sig.IndexOf(Compiler.AmpersandSym);
                    if (args.count() == sig.count() || (restOffset > -1 && args.count() >= restOffset))
                    {
                        sigTag = Compiler.TagOf(sig);
                        break;
                    }
                }
                _tag = sigTag ?? varFexpr.Tag;
            }
            else
            {
                _tag = null;
            }
        }
示例#50
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvEx();

            // TODO: DO we need the recur context here and below?
            Expr fexpr = Compiler.Analyze(pcon,form.first());

            if ( fexpr is VarExpr && ((VarExpr)fexpr).Var.Equals(Compiler.INSTANCE))
            {
                if ( RT.second(form) is Symbol )
                {
                    Type t = HostExpr.MaybeType(RT.second(form),false);
                    if ( t != null )
                        return new InstanceOfExpr((string)Compiler.SOURCE.deref(), (IPersistentMap)Compiler.SOURCE_SPAN.deref(), t, Compiler.Analyze(pcon,RT.third(form)));
                }
            }

            if (fexpr is VarExpr && pcon.Rhc != RHC.Eval)
            {
                Var v = ((VarExpr)fexpr).Var;
                object arglists = RT.get(RT.meta(v), Compiler.ARGLISTS_KEY);
                int arity = RT.count(form.next());
                for (ISeq s = RT.seq(arglists); s != null; s = s.next())
                {
                    IPersistentVector sargs = (IPersistentVector)s.first();
                    if (sargs.count() == arity)
                    {
                        string primc = FnMethod.PrimInterface(sargs);
                        if (primc != null)
                            return Compiler.Analyze(pcon,
                                RT.listStar(Symbol.intern(".invokePrim"),
                                            ((Symbol)form.first()).withMeta(RT.map(RT.TAG_KEY, Symbol.intern(primc))),
                                            form.next()));
                        break;
                    }
                }
            }

            if (fexpr is KeywordExpr && RT.count(form) == 2 && Compiler.KEYWORD_CALLSITES.isBound)
            {
                Expr target = Compiler.Analyze(pcon, RT.second(form));
                return new KeywordInvokeExpr((string)Compiler.SOURCE.deref(), (IPersistentMap)Compiler.SOURCE_SPAN.deref(), Compiler.TagOf(form), (KeywordExpr)fexpr, target);
            }

            IPersistentVector args = PersistentVector.EMPTY;
            for ( ISeq s = RT.seq(form.next()); s != null; s = s.next())
                args = args.cons(Compiler.Analyze(pcon,s.first()));

            //if (args.count() > Compiler.MAX_POSITIONAL_ARITY)
            //    throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY));

            return new InvokeExpr((string)Compiler.SOURCE.deref(),
                (IPersistentMap)Compiler.SOURCE_SPAN.deref(), //Compiler.GetSourceSpanMap(form),
                Compiler.TagOf(form),
                fexpr,
                args);
        }
示例#51
0
 public static object ApplyToHelper(IFn fn, ISeq argList)
 {
     switch (RT.BoundedLength(argList, 20))
     {
         case 0:
             argList = null;
             return fn.invoke();
         case 1:
             return fn.invoke(Util.Ret1(argList.first(),argList=null));
         case 2:
             return fn.invoke(argList.first()
                     , Util.Ret1((argList = argList.next()).first(),argList = null)
             );
         case 3:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 4:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 5:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 6:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 7:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 8:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 9:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 10:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 11:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 12:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 13:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 14:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 15:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 16:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 17:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 18:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 19:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         case 20:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , Util.Ret1((argList = argList.next()).first(), argList = null)
             );
         default:
             return fn.invoke(argList.first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , (argList = argList.next()).first()
                     , RT.SeqToArray<object>(Util.Ret1(argList.next(),argList=null)));
     }
 }
示例#52
0
 public static object ApplyToHelper(IFn ifn, ISeq arglist)
 {
     switch (RT.BoundedLength(arglist, 20))
     {
         case 0:
             return ifn.invoke();
         case 1:
             return ifn.invoke(arglist.first());
         case 2:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
             );
         case 3:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 4:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 5:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 6:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 7:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 8:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 9:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 10:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 11:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 12:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 13:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 14:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 15:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 16:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 17:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 18:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 19:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         case 20:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
             );
         default:
             return ifn.invoke(arglist.first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , (arglist = arglist.rest()).first()
                     , RT.SeqToArray<object>(arglist.rest()));
     }
 }
示例#53
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));
            fn._src = form;

            if (((IMeta)form.first()).meta() != null)
            {
                fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE));
            }

            fn.ComputeNames(form, name);

            // Java: fn.objtype = Type.getObjectType(fn.internalName) -- makes no sense for us, this is ASM only.

            List<string> prims = new List<string>();

            try
            {
                Var.pushThreadBindings(RT.map(
                    Compiler.CONSTANTS, PersistentVector.EMPTY,
                    Compiler.CONSTANT_IDS, new IdentityHashMap(),
                    Compiler.KEYWORDS, PersistentHashMap.EMPTY,
                    Compiler.VARS, PersistentHashMap.EMPTY,
                    Compiler.KEYWORD_CALLSITES,PersistentVector.EMPTY,
                    Compiler.PROTOCOL_CALLSITES,PersistentVector.EMPTY,
                    Compiler.VAR_CALLSITES,Compiler.EmptyVarCallSites(),
                    Compiler.NO_RECUR,null));

                //arglist might be preceded by symbol naming this fn
                if (RT.second(form) is Symbol)
                {
                    Symbol nm = (Symbol)RT.second(form);
                    fn._thisName = nm.Name;
                    fn.IsStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY));
                    form = RT.cons(Compiler.FN, RT.next(RT.next(form)));
                }

                // Normalize body
                //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...)
                //turn former into latter
                if (RT.second(form) is IPersistentVector)
                    form = RT.list(Compiler.FN, RT.next(form));

                SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>();
                FnMethod variadicMethod = null;

                for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                {
                    FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s),fn.IsStatic);
                    if (f.IsVariadic)
                    {
                        if (variadicMethod == null)
                            variadicMethod = f;
                        else
                            throw new Exception("Can't have more than 1 variadic overload");
                    }
                    else if (!methods.ContainsKey(f.RequiredArity))
                        methods[f.RequiredArity] = f;
                    else
                        throw new Exception("Can't have 2 overloads with the same arity.");
                    if (f.Prim != null)
                        prims.Add(f.Prim);
                }

                if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams)
                    throw new Exception("Can't have fixed arity methods with more params than the variadic method.");

                if ( fn.IsStatic && fn.Closes.count() > 0 )
                    throw new ArgumentException("static fns can't be closures");

                IPersistentCollection allMethods = null;
                foreach (FnMethod method in methods.Values)
                    allMethods = RT.conj(allMethods, method);
                if (variadicMethod != null)
                    allMethods = RT.conj(allMethods, variadicMethod);

                fn._methods = allMethods;
                fn._variadicMethod = variadicMethod;
                fn.Keywords = (IPersistentMap)Compiler.KEYWORDS.deref();
                fn.Vars = (IPersistentMap)Compiler.VARS.deref();
                fn.Constants = (PersistentVector)Compiler.CONSTANTS.deref();
                fn.KeywordCallsites = (IPersistentVector)Compiler.KEYWORD_CALLSITES.deref();
                fn.ProtocolCallsites = (IPersistentVector)Compiler.PROTOCOL_CALLSITES.deref();
                fn.VarCallsites = (IPersistentSet)Compiler.VAR_CALLSITES.deref();

                fn._constantsID = RT.nextID();
            }
            finally
            {
                Var.popThreadBindings();
            }

            IPersistentMap fmeta = RT.meta(origForm);
            if (fmeta != null)
                fmeta = fmeta.without(RT.LINE_KEY).without(RT.FILE_KEY);
            fn._hasMeta = RT.count(fmeta) > 0;

            if (Compiler.IsCompiling || prims.Count > 0)
            {
                GenContext context = Compiler.COMPILER_CONTEXT.get() as GenContext ?? Compiler.EvalContext;
                GenContext genC = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());

                IPersistentVector primTypes = PersistentVector.EMPTY;
                foreach (string typename in prims)
                    primTypes = primTypes.cons(Type.GetType(typename));

                fn.Compile(
                    fn.IsVariadic ? typeof(RestFn) : typeof(AFunction),
                    null,
                    primTypes,
                    fn.OnceOnly,
                    genC);
            }
            else
            {
                fn.CompiledType = fn.GetPrecompiledType();
                fn.FnMode = FnMode.Light;
            }

            if (fn.SupportsMeta)
                return new MetaExpr(fn, MapExpr.Parse(pcon.EvEx(),fmeta));
            else
                return fn;
        }
示例#54
0
        public static PersistentVector create(ISeq items)
        {
            Object[] arr = new Object[32];
            int i = 0;
            for (; items != null && i < 32; items = items.next())
                arr[i++] = items.first();

            if (items != null)
            {
                // >32, construct with array directly
                PersistentVector start = new PersistentVector(32, 5, EmptyNode, arr);
                TransientVector ret = (TransientVector)start.asTransient();
                for (; items != null; items = items.next())
                    ret = (TransientVector)ret.conj(items.first());
                return (PersistentVector)ret.persistent();
            }
            else if (i == 32)
            {
                // exactly 32, skip copy
                return new PersistentVector(32, 5, EmptyNode, arr);
            }
            else
            {
                // <32, copy to minimum array and construct
                Object[] arr2 = new Object[i];
                Array.Copy(arr, 0, arr2, 0, i);

                return new PersistentVector(i, 5, EmptyNode, arr2);
            }
        }
示例#55
0
 private static ISeq sqExpandList(ISeq seq)
 {
     IPersistentVector ret = PersistentVector.EMPTY;
     for (; seq != null; seq = seq.next())
     {
         Object item = seq.first();
         //if (item is Unquote)
         //    ret = ret.cons(RT.list(LIST, ((Unquote)item).Obj));
         // REV 1184
         if (isUnquote(item))
             ret = ret.cons(RT.list(LIST, RT.second(item)));
         else if (isUnquoteSplicing(item))
             ret = ret.cons(RT.second(item));
         else
             ret = ret.cons(RT.list(LIST, syntaxQuote(item)));
     }
     return ret.seq();
 }
示例#56
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvEx();

            // TODO: DO we need the recur context here and below?
            Expr fexpr = Compiler.Analyze(pcon,form.first());

            if ( fexpr is VarExpr && ((VarExpr)fexpr).Var.Equals(Compiler.INSTANCE))
            {
                if ( RT.second(form) is Symbol )
                {
                    Type t = HostExpr.MaybeType(RT.second(form),false);
                    if ( t != null )
                        return new InstanceOfExpr((string)Compiler.SOURCE.deref(), (IPersistentMap)Compiler.SOURCE_SPAN.deref(), t, Compiler.Analyze(pcon,RT.third(form)));
                }
            }

            if (fexpr is VarExpr && pcon.Rhc != RHC.Eval)
            {
                Var v = ((VarExpr)fexpr).Var;
                if (RT.booleanCast(RT.get(RT.meta(v), Compiler.STATIC_KEY)))
                    return StaticInvokeExpr.Parse(v, RT.next(form), Compiler.TagOf(form));
            }

            if (fexpr is KeywordExpr && RT.count(form) == 2 && Compiler.KEYWORD_CALLSITES.isBound)
            {
                Expr target = Compiler.Analyze(pcon, RT.second(form));
                return new KeywordInvokeExpr((string)Compiler.SOURCE.deref(), (IPersistentMap)Compiler.SOURCE_SPAN.deref(), Compiler.TagOf(form), (KeywordExpr)fexpr, target);
            }

            IPersistentVector args = PersistentVector.EMPTY;
            for ( ISeq s = RT.seq(form.next()); s != null; s = s.next())
                args = args.cons(Compiler.Analyze(pcon,s.first()));
            return new InvokeExpr((string)Compiler.SOURCE.deref(),
                (IPersistentMap)Compiler.SOURCE_SPAN.deref(), //Compiler.GetSourceSpanMap(form),
                Compiler.TagOf(form),
                fexpr,
                args);
        }
示例#57
0
        protected void EmitValue(object value, CljILGen ilg)
        {
            bool partial = true;

            if (value == null)
            {
                ilg.Emit(OpCodes.Ldnull);
            }
            else if (value is String)
            {
                ilg.Emit(OpCodes.Ldstr, (String)value);
            }
            else if (value is Boolean)
            {
                ilg.EmitBoolean((Boolean)value);
                ilg.Emit(OpCodes.Box, typeof(bool));
            }
            else if (value is Int32)
            {
                ilg.EmitInt((int)value);
                ilg.Emit(OpCodes.Box, typeof(int));
            }
            else if (value is Int64)
            {
                ilg.EmitLong((long)value);
                ilg.Emit(OpCodes.Box, typeof(long));
            }
            else if (value is Double)
            {
                ilg.EmitDouble((double)value);
                ilg.Emit(OpCodes.Box, typeof(double));
            }
            else if (value is Char)
            {
                ilg.EmitChar((char)value);
                ilg.Emit(OpCodes.Box, typeof(char));
            }
            else if (value is Type)
            {
                Type t = (Type)value;
                if (t.IsValueType)
                {
                    ilg.EmitType(t);
                }
                else
                {
                    //ilg.EmitString(Compiler.DestubClassName(((Type)value).FullName));
                    ilg.EmitString(((Type)value).FullName);
                    ilg.EmitCall(Compiler.Method_RT_classForName);
                }
            }
            else if (value is Symbol)
            {
                Symbol sym = (Symbol)value;
                if (sym.Namespace == null)
                {
                    ilg.EmitNull();
                }
                else
                {
                    ilg.EmitString(sym.Namespace);
                }
                ilg.EmitString(sym.Name);
                ilg.EmitCall(Compiler.Method_Symbol_intern2);
            }
            else if (value is Keyword)
            {
                Keyword keyword = (Keyword)value;
                if (keyword.Namespace == null)
                {
                    ilg.EmitNull();
                }
                else
                {
                    ilg.EmitString(keyword.Namespace);
                }
                ilg.EmitString(keyword.Name);
                ilg.EmitCall(Compiler.Method_RT_keyword);
            }
            else if (value is Var)
            {
                Var var = (Var)value;
                ilg.EmitString(var.Namespace.Name.ToString());
                ilg.EmitString(var.Symbol.Name.ToString());
                ilg.EmitCall(Compiler.Method_RT_var2);
            }
            else if (value is IType)
            {
                IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes);

                for (ISeq s = RT.seq(fields); s != null; s = s.next())
                {
                    Symbol field = (Symbol)s.first();
                    Type   k     = Compiler.TagType(Compiler.TagOf(field));
                    object val   = Reflector.GetInstanceFieldOrProperty(value, field.Name);
                    EmitValue(val, ilg);
                    if (k.IsPrimitive)
                    {
                        ilg.Emit(OpCodes.Castclass, k);
                    }
                }

                ConstructorInfo cinfo = value.GetType().GetConstructors()[0];
                ilg.EmitNew(cinfo);
            }
            else if (value is IRecord)
            {
                //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public);
                EmitValue(PersistentArrayMap.create((IDictionary)value), ilg);

                MethodInfo createMI = value.GetType().GetMethod("create", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, new Type[] { typeof(IPersistentMap) }, null);
                ilg.EmitCall(createMI);
            }
            else if (value is IPersistentMap)
            {
                IPersistentMap map     = (IPersistentMap)value;
                List <object>  entries = new List <object>(map.count() * 2);
                foreach (IMapEntry entry in map)
                {
                    entries.Add(entry.key());
                    entries.Add(entry.val());
                }
                EmitListAsObjectArray(entries, ilg);
                ilg.EmitCall(Compiler.Method_RT_map);
            }
            else if (value is IPersistentVector)
            {
                EmitListAsObjectArray(value, ilg);
                ilg.EmitCall(Compiler.Method_RT_vector);
            }
            else if (value is PersistentHashSet)
            {
                ISeq vs = RT.seq(value);
                if (vs == null)
                {
                    ilg.EmitFieldGet(Compiler.Method_PersistentHashSet_EMPTY);
                }
                else
                {
                    EmitListAsObjectArray(vs, ilg);
                    ilg.EmitCall(Compiler.Method_PersistentHashSet_create);
                }
            }
            else if (value is ISeq || value is IPersistentList)
            {
                EmitListAsObjectArray(value, ilg);
                ilg.EmitCall(Compiler.Method_PersistentList_create);
            }
            else if (value is Regex)
            {
                ilg.EmitString(((Regex)value).ToString());
                ilg.EmitNew(Compiler.Ctor_Regex_1);
            }
            else
            {
                string cs = null;
                try
                {
                    cs = RT.printString(value);
                }
                catch (Exception)
                {
                    throw new InvalidOperationException(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value));
                }
                if (cs.Length == 0)
                {
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + value));
                }
                if (cs.StartsWith("#<"))
                {
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + cs));
                }

                ilg.EmitString(cs);
                ilg.EmitCall(Compiler.Method_RT_readString);
                partial = false;
            }

            if (partial)
            {
                if (value is IObj && RT.count(((IObj)value).meta()) > 0)
                {
                    ilg.Emit(OpCodes.Castclass, typeof(IObj));
                    Object m = ((IObj)value).meta();
                    EmitValue(Compiler.ElideMeta(m), ilg);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                    ilg.Emit(OpCodes.Callvirt, Compiler.Method_IObj_withMeta);
                }
            }
        }
示例#58
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));
            fn._src = form;

            if (((IMeta)form.first()).meta() != null)
            {
                fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE));
            }

            fn.ComputeNames(form, name);

            List<string> prims = new List<string>();

            //arglist might be preceded by symbol naming this fn
            if (RT.second(form) is Symbol)
            {
                Symbol nm = (Symbol)RT.second(form);
                fn._thisName = nm.Name;
                fn._isStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY));
                form = RT.cons(Compiler.FnSym, RT.next(RT.next(form)));
            }

            // Normalize body
            //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...)
            //turn former into latter
            if (RT.second(form) is IPersistentVector)
                form = RT.list(Compiler.FnSym, RT.next(form));

            fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();



            GenContext newContext = null;

            // Uncomment -if- to enable light compilation  (and see below)
            //bool hasPrimDecls = HasPrimDecls((ISeq)RT.next(form));
            //if (Compiler.IsCompiling || hasPrimDecls || fn.IsStatic)
            //{
                GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext;
                newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());
                Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext));
            //}

            try
            {
                try
                {
                    Var.pushThreadBindings(RT.mapUniqueKeys(
                        Compiler.ConstantsVar, PersistentVector.EMPTY,
                        Compiler.ConstantIdsVar, new IdentityHashMap(),
                        Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                        Compiler.VarsVar, PersistentHashMap.EMPTY,
                        Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                        Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                        Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                        Compiler.NoRecurVar, null));
                    SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>();
                    FnMethod variadicMethod = null;

                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                    {
                        FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), fn._isStatic);
                        if (f.IsVariadic)
                        {
                            if (variadicMethod == null)
                                variadicMethod = f;
                            else
                                throw new ParseException("Can't have more than 1 variadic overload");
                        }
                        else if (!methods.ContainsKey(f.RequiredArity))
                            methods[f.RequiredArity] = f;
                        else
                            throw new ParseException("Can't have 2 overloads with the same arity.");
                        if (f.Prim != null)
                            prims.Add(f.Prim);
                    }

                    if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams)
                        throw new ParseException("Can't have fixed arity methods with more params than the variadic method.");

                    if (fn._isStatic && fn.Closes.count() > 0)
                        throw new ParseException("static fns can't be closures");

                    IPersistentCollection allMethods = null;
                    foreach (FnMethod method in methods.Values)
                        allMethods = RT.conj(allMethods, method);
                    if (variadicMethod != null)
                        allMethods = RT.conj(allMethods, variadicMethod);

                    fn._methods = allMethods;
                    fn._variadicMethod = variadicMethod;
                    fn.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref();
                    fn.Vars = (IPersistentMap)Compiler.VarsVar.deref();
                    fn.Constants = (PersistentVector)Compiler.ConstantsVar.deref();
                    fn.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                    fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                    fn.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref();

                    fn._constantsID = RT.nextID();
                }
                finally
                {
                    Var.popThreadBindings();
                }


                IPersistentMap fmeta = RT.meta(origForm);
                if (fmeta != null)
                    fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey);
                fn._hasMeta = RT.count(fmeta) > 0;


                // Uncomment if/else to enable light compilation (and see above)
                //if (Compiler.IsCompiling || prims.Count > 0|| fn.IsStatic)
                //{

                    IPersistentVector primTypes = PersistentVector.EMPTY;
                    foreach (string typename in prims)
                        primTypes = primTypes.cons(Type.GetType(typename));

                        fn.Compile(
                            fn.IsVariadic ? typeof(RestFn) : typeof(AFunction),
                            null,
                            primTypes,
                            fn._onceOnly,
                            newContext);
                //}
                //else
                //{
                //    fn.FnMode = FnMode.Light;
                //    fn.LightCompile(fn.GetPrecompiledType(), Compiler.EvalContext);
                //}

                if (fn.SupportsMeta)
                    return new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta));
                else
                    return fn;

            }
            finally
            {
                if (newContext != null)
                    Var.popThreadBindings();
            }
        }
示例#59
0
        public override object applyTo(ISeq args)
        {
            if (RT.BoundedLength(args, _reqArity) <= _reqArity)
                return base.applyTo(args);

            switch (_reqArity)
            {
                case 0:
                    return doInvoke(args);
                case 1:
                    return doInvoke(args.first()
                            , args.next());
                case 2:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , args.next());
                case 3:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 4:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 5:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 6:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 7:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 8:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 9:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 10:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 11:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 12:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 13:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 14:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 15:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 16:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 17:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 18:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 19:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());
                case 20:
                    return doInvoke(args.first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , (args = args.next()).first()
                            , args.next());

            }
            throw WrongArityException();
        }
示例#60
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));
            fn.Src = form;

            Keyword retKey = Keyword.intern(null, "rettag");  // TODO: make static
            object retTag = RT.get(RT.meta(form), retKey);
            ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref();
            fn._hasEnclosingMethod = enclosingMethod != null;


            if (((IMeta)form.first()).meta() != null)
            {
                fn.OnceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE));
            }

            fn.ComputeNames(form, name);

            List<string> prims = new List<string>();

            //arglist might be preceded by symbol naming this fn
             Symbol nm = RT.second(form) as Symbol;
            if (nm != null)
            {
                fn.ThisName = nm.Name;
                form = RT.cons(Compiler.FnSym, RT.next(RT.next(form)));
            }

            // Normalize body
            //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...)
            //turn former into latter
            if (RT.second(form) is IPersistentVector)
                form = RT.list(Compiler.FnSym, RT.next(form));

            fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

            GenContext newContext = null;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext;
            newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());
            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext));


            try
            {
                try
                {
                    Var.pushThreadBindings(RT.mapUniqueKeys(
                        Compiler.ConstantsVar, PersistentVector.EMPTY,
                        Compiler.ConstantIdsVar, new IdentityHashMap(),
                        Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                        Compiler.VarsVar, PersistentHashMap.EMPTY,
                        Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                        Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                        Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                        Compiler.NoRecurVar, null));
                    SortedDictionary<int, FnMethod> methods = new SortedDictionary<int, FnMethod>();
                    FnMethod variadicMethod = null;
                    bool usesThis = false;

                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                    {
                        FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), retTag);
                        if ( f.UsesThis)
                        {
                            //Console.WriteLine("{0} uses this",fn.Name);
                            usesThis = true;
                        }
                        if (f.IsVariadic)
                        {
                            if (variadicMethod == null)
                                variadicMethod = f;
                            else
                                throw new ParseException("Can't have more than 1 variadic overload");
                        }
                        else if (!methods.ContainsKey(f.RequiredArity))
                            methods[f.RequiredArity] = f;
                        else
                            throw new ParseException("Can't have 2 overloads with the same arity.");
                        if (f.Prim != null)
                            prims.Add(f.Prim);
                    }

                    if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams)
                        throw new ParseException("Can't have fixed arity methods with more params than the variadic method.");

                    fn.CanBeDirect = !fn._hasEnclosingMethod && fn.Closes.count() == 0 && !usesThis;

                    IPersistentCollection allMethods = null;
                    foreach (FnMethod method in methods.Values)
                        allMethods = RT.conj(allMethods, method);
                    if (variadicMethod != null)
                        allMethods = RT.conj(allMethods, variadicMethod);

                    if ( fn.CanBeDirect )
                    {
                        for (ISeq s = RT.seq(allMethods); s != null; s = s.next())
                        {
                            FnMethod fm = s.first() as FnMethod;
                            if ( fm.Locals != null)
                            {
                                for (ISeq sl = RT.seq(RT.keys(fm.Locals)); sl != null; sl = sl.next())
                                {
                                    LocalBinding lb = sl.first() as LocalBinding;
                                    if ( lb.IsArg)
                                        lb.Index -= 1;
                                }
                            }
                        }
                    }

                    fn.Methods = allMethods;
                    fn._variadicMethod = variadicMethod;
                    fn.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref();
                    fn.Vars = (IPersistentMap)Compiler.VarsVar.deref();
                    fn.Constants = (PersistentVector)Compiler.ConstantsVar.deref();
                    fn.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                    fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                    fn.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref();

                    fn.ConstantsID = RT.nextID();
                }
                finally
                {
                    Var.popThreadBindings();
                }


                IPersistentMap fmeta = RT.meta(origForm);
                if (fmeta != null)
                    fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey).without(retKey);
                fn._hasMeta = RT.count(fmeta) > 0;


                IPersistentVector primTypes = PersistentVector.EMPTY;
                foreach (string typename in prims)
                    primTypes = primTypes.cons(Type.GetType(typename));

                fn.Compile(
                    fn.IsVariadic ? typeof(RestFn) : typeof(AFunction),
                    null,
                    primTypes,
                    fn.OnceOnly,
                    newContext);

                if (fn.SupportsMeta)
                    return new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta));
                else
                    return fn;

            }
            finally
            {
                if (newContext != null)
                    Var.popThreadBindings();
            }
        }