Beispiel #1
0
        private static void DefineMethod(TypeBuilder proxyTB, IPersistentVector sig)
        {
            string mname = (string)sig.nth(0);
            Type[] paramTypes = GenClass.CreateTypeArray((ISeq)sig.nth(1));
            Type retType = (Type)sig.nth(2);

            MethodBuilder mb = proxyTB.DefineMethod(mname, MethodAttributes.Abstract | MethodAttributes.Public| MethodAttributes.Virtual, retType, paramTypes);
        }
Beispiel #2
0
        public static Expr Parse(ParserContext pcon, IPersistentVector form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector args = PersistentVector.EMPTY;
            for (int i = 0; i < form.count(); i++ )
            {
                Expr v = Compiler.Analyze(pconToUse, form.nth(i));
                args = (IPersistentVector)args.cons(v);
                if ( !(v is LiteralExpr) )
                    constant = false;
            }

            Expr ret = new VectorExpr(args);
            if ( form is IObj && ((IObj)form).meta() != null )
                return Compiler.OptionallyGenerateMetaInit(pcon,form, ret);
            else if ( constant )
            {
                IPersistentVector rv = PersistentVector.EMPTY;
                for ( int i=0; i<args.count(); i++ )
                {
                    LiteralExpr ve = (LiteralExpr)args.nth(i);
                    rv = (IPersistentVector)rv.cons(ve.Val);
                }
                return new ConstantExpr(rv);
            }
            else
                return ret;
        }
Beispiel #3
0
 internal static Expression[] GenTypedArgs(GenContext context, ParameterInfo[] parms, IPersistentVector args)
 {
     Expression[] exprs = new Expression[parms.Length];
     for (int i = 0; i < parms.Length; i++)
         exprs[i] = GenTypedArg(context,parms[i].ParameterType, (Expr)args.nth(i));
     return exprs;
 }
Beispiel #4
0
        public static Expr Parse(IPersistentVector form)
        {
            IPersistentVector args = PersistentVector.EMPTY;
            for (int i = 0; i < form.count(); i++ )
                args = (IPersistentVector)args.cons(Compiler.GenerateAST(form.nth(i),false));

            Expr ret = new VectorExpr(args);
            return Compiler.OptionallyGenerateMetaInit(form, ret);
        }
        public void AssocNChangesForBig()
        {
            Range             r  = new Range(2, 100000);
            PersistentVector  v1 = PersistentVector.create((ISeq)r);
            IPersistentVector v2 = v1;

            for (int i = 0; i < 110000; i++)
            {
                v2 = v2.assocN(i, i + 20);
            }

            for (int i = 0; i < v1.count(); ++i)
            {
                Expect(v1.nth(i), EqualTo(i + 2));
            }

            for (int i = 0; i < v2.count(); ++i)
            {
                Expect(v2.nth(i), EqualTo(i + 20));
            }
        }
        public static Expr Parse(ParserContext pcon, IPersistentVector form)
        {
            ParserContext pconToUse = pcon.EvalOrExpr();
            bool          constant  = true;

            IPersistentVector args = PersistentVector.EMPTY;

            for (int i = 0; i < form.count(); i++)
            {
                Expr v = Compiler.Analyze(pconToUse, form.nth(i));
                args = (IPersistentVector)args.cons(v);
                if (!(v is LiteralExpr))
                {
                    constant = false;
                }
            }

            Expr ret      = new VectorExpr(args);
            IObj iobjForm = form as IObj;

            if (iobjForm != null && iobjForm.meta() != null)
            {
                return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret));
            }
            else if (constant)
            {
                IPersistentVector rv = PersistentVector.EMPTY;
                for (int i = 0; i < args.count(); i++)
                {
                    LiteralExpr ve = (LiteralExpr)args.nth(i);
                    rv = (IPersistentVector)rv.cons(ve.Val);
                }
                return(new ConstantExpr(rv));
            }
            else
            {
                return(ret);
            }
        }
Beispiel #7
0
        public static string PrimInterface(IPersistentVector arglist)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < arglist.count(); i++)
            {
                sb.Append(TypeChar(Compiler.TagOf(arglist.nth(i))));
            }
            sb.Append(TypeChar(Compiler.TagOf(arglist)));
            string ret  = sb.ToString();
            bool   prim = ret.Contains("L") || ret.Contains("D");

            if (prim && arglist.count() > 4)
            {
                throw new ArgumentException("fns taking primitives support only 4 or fewer args");
            }
            if (prim)
            {
                return("clojure.lang.primifs." + ret);
            }
            return(null);
        }
Beispiel #8
0
        public static bool IsPrimInterface(IPersistentVector arglist)
        {
            if (arglist.count() > 4)
            {
                return(false);
            }

            for (int i = 0; i < arglist.count(); i++)
            {
                if (IsPrimType(Compiler.TagOf(arglist.nth(i))))
                {
                    return(true);
                }
            }

            if (IsPrimType(Compiler.TagOf(arglist)))
            {
                return(true);
            }

            return(false);
        }
Beispiel #9
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);
            }
        }
        public void AssocNChangesForBig()
        {
            ISeq              r  = LongRange.create(2, 100000);
            PersistentVector  v1 = PersistentVector.create(r);
            IPersistentVector v2 = v1;

            for (int i = 0; i < 110000; i++)
            {
                v2 = v2.assocN(i, i + 20L);
            }

            for (int i = 0; i < v1.count(); ++i)
            {
                Expect((long)v1.nth(i)).To.Equal(i + 2L);
            }

            for (int i = 0; i < v2.count(); ++i)
            {
                object o = v2.nth(i);
                Expect(o).To.Be.An.Instance.Of <long>();
                Expect((long)o).To.Equal(i + 20L);
            }
        }
Beispiel #11
0
        public static Expr Parse(ParserContext pcon, IPersistentVector form)
        {
            ParserContext pconToUse = pcon.EvalOrExpr();
            bool          constant  = true;

            IPersistentVector args = PersistentVector.EMPTY;

            for (int i = 0; i < form.count(); i++)
            {
                Expr v = Compiler.Analyze(pconToUse, form.nth(i));
                args = (IPersistentVector)args.cons(v);
                if (!(v is LiteralExpr))
                {
                    constant = false;
                }
            }

            Expr ret = new VectorExpr(args);

            if (form is IObj iobjForm && iobjForm.meta() != null)
            {
                return(Compiler.OptionallyGenerateMetaInit(pcon, form, ret));
            }
Beispiel #12
0
 public object Eval()
 {
     try
     {
         IFn fn = (IFn)_fexpr.Eval();
         IPersistentVector argvs = PersistentVector.EMPTY;
         for (int i = 0; i < _args.count(); i++)
         {
             argvs = (IPersistentVector)argvs.cons(((Expr)_args.nth(i)).Eval());
         }
         return(fn.applyTo(RT.seq(Util.Ret1(argvs, argvs = null))));
     }
     catch (Compiler.CompilerException)
     {
         throw;
     }
     catch (Exception e)
     {
         throw new Compiler.CompilerException(_source, Compiler.GetLineFromSpanMap(_spanMap), e);
     }
 }
        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 ArgumentException("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.COMPILER_CONTEXT.get() as GenContext ?? (ret.IsDefType ? new GenContext("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.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, PersistentVector.EMPTY,
                        Compiler.COMPILER_CONTEXT, genC
                        ));

                if (ret.IsDefType)
                {
                    Var.pushThreadBindings(
                        RT.map(
                            Compiler.METHOD, null,
                            Compiler.LOCAL_ENV, ret._fields,
                            Compiler.COMPILE_STUB_SYM, Symbol.intern(null, tagName),
                            Compiler.COMPILE_STUB_CLASS, stub
                            ));
                }
                // 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.KEYWORDS.deref();
                ret.Vars = (IPersistentMap)Compiler.VARS.deref();
                ret.Constants = (PersistentVector)Compiler.CONSTANTS.deref();
                ret._constantsID = RT.nextID();
                ret.KeywordCallsites = (IPersistentVector)Compiler.KEYWORD_CALLSITES.deref();
                ret.ProtocolCallsites = (IPersistentVector)Compiler.PROTOCOL_CALLSITES.deref();
                ret.VarCallsites = (IPersistentVector)Compiler.VAR_CALLSITES.deref();
            }
            finally
            {
                if (ret.IsDefType)
                    Var.popThreadBindings();
                Var.popThreadBindings();
            }

            ret.Compile(stub, interfaces, false, genC);
            Compiler.RegisterDuplicateType(ret.CompiledType);

            return ret;
        }
Beispiel #14
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);
        }
        static bool doEquiv(IPersistentVector v, object obj)
        {
            if (obj is IList || obj is IPersistentVector)
            {
                ICollection ma = (ICollection)obj;
                if (ma.Count != v.count())
                    return false;
                IEnumerator ima = ma.GetEnumerator();
                foreach (object ov in ((IList)v))
                {
                    ima.MoveNext();
                    if (!Util.equiv(ov, ima.Current))
                        return false;
                }
                return true;
            }
            else
            {
                // Example in Java of Sequential / IPersistentCollection conflation
                //if (!(obj is Sequential))
                //    return false;
                //ISeq ms = ((IPersistentCollection)obj).seq();

                ISeq ms = obj as ISeq;
                if (ms == null)
                {
                    IPersistentCollection mc = obj as IPersistentCollection;
                    if (mc == null)
                        return false;
                    ms = mc.seq();
                }

                // Once we have the ISeq, we're ready to go.

                for (int i = 0; i < v.count(); i++, ms = ms.rest())
                {
                    if (ms == null || !Util.equiv(v.nth(i), ms.first()))
                        return false;
                }
                if (ms != null)
                    return false;
            }

            return true;
        }
 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;
 }
Beispiel #17
0
        public void NthOutOfRangeLowFails()
        {
            IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3);

            Expect(v.nth(-4)).To.Equal(1);
        }
Beispiel #18
0
        // There is a tremendous overlap between this and GenerateFnExpr+GenerateFnMethod.  TODO: DRY it.
        private static LambdaExpression GenerateTypedDelegateExpression(Type delegateType, Symbol name, IPersistentVector parms, ISeq body)
        {
            // Create the form that is more or less correct

            ISeq form = (name == null)
                ? RT.cons(Compiler.FN, RT.cons(parms, body))
                : RT.cons(Compiler.FN, RT.cons(name, RT.cons(parms, body)));

            FnDef fnDef = new FnDef(null); // compute tag from delegateType?
            fnDef.ComputeNames(form);

            MethodDef methodDef = new MethodDef(fnDef, (MethodDef)METHODS.deref());

            try
            {
                LabelTarget loopLabel = Expression.Label();

                Var.pushThreadBindings(PersistentHashMap.create(
                    METHODS, methodDef,
                    LOOP_LABEL, loopLabel,
                    LOCAL_ENV, LOCAL_ENV.deref(),
                    LOOP_LOCALS, null));

                // register 'this' as local 0
                LocalBinding thisB = RegisterLocal(Symbol.intern(fnDef.ThisName ?? "fn__" + RT.nextID()), null, null);
                thisB.ParamExpression = fnDef.ThisParam;

                IPersistentVector argLocals = PersistentVector.EMPTY;
                int parmsCount = parms.count();
                ParamParseState paramState = ParamParseState.Required;

                for (int i = 0; i < parmsCount; i++)
                {
                    if (!(parms.nth(i) is Symbol))
                        throw new ArgumentException("fn params must be Symbols");
                    Symbol p = parms.nth(i) as Symbol;
                    if (p.Namespace != null)
                        throw new Exception("Can't use qualified name as parameter: " + p);
                    if (p.Equals(Compiler._AMP_))
                    {
                        if (paramState == ParamParseState.Required)
                            paramState = ParamParseState.Rest;
                        else
                            throw new Exception("Invalid parameter list");
                    }
                    else
                    {
                        // TODO: Need more type inferencing to make this work.
                        //LocalBinding b = RegisterLocal(p, paramState == ParamParseState.Rest ? ISEQ : TagOf(p), null);
                        LocalBinding b = RegisterLocal(p, TagOf(p), null);

                        argLocals = argLocals.cons(b);
                        switch (paramState)
                        {
                            case ParamParseState.Required:
                                methodDef.ReqParms = methodDef.ReqParms.cons(b);
                                break;
                            case ParamParseState.Rest:
                                methodDef.RestParm = b;
                                paramState = ParamParseState.Done;
                                break;
                            default:
                                throw new Exception("Unexpected parameter");
                        }
                    }
                }

                MethodInfo invokeMI = delegateType.GetMethod("Invoke");
                Type returnType = invokeMI.ReturnType;
                ParameterInfo[] delParams = invokeMI.GetParameters();

                bool isVariadic = (invokeMI.CallingConvention & CallingConventions.VarArgs) != 0;
                if (isVariadic != methodDef.IsVariadic)
                    throw new ArgumentException("Arglist and delegate type must agree on being variadic.");

                if (delParams.Length != argLocals.count() )
                    throw new ArgumentException("Wrong number of parameters to generate typed delegate");

                if (methodDef.NumParams > MAX_POSITIONAL_ARITY)
                    throw new Exception(string.Format("Can't specify more than {0} parameters",MAX_POSITIONAL_ARITY));

                LOOP_LOCALS.set(argLocals);
                methodDef.ArgLocals = argLocals;

                List<ParameterExpression> parmExprs = new List<ParameterExpression>(argLocals.count());
                for (int i = 0; i < argLocals.count(); i++)
                {
                    LocalBinding b = (LocalBinding)argLocals.nth(i);
                    ParameterExpression pexpr = Expression.Parameter(delParams[i].ParameterType, b.Name);  //asdf-tag
                    b.ParamExpression = pexpr;
                    parmExprs.Add(pexpr);
                }

                methodDef.Lambda = Expression.Lambda(
                    delegateType,
                    Expression.Block(
                      Expression.Label(loopLabel),
                      Expression.Convert(GenerateBodyExpr(body),returnType)),
                      fnDef.Name,
                      parmExprs);

                return methodDef.Lambda;

            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #19
0
        internal static Expression GenArgArray(GenContext context, IPersistentVector args)
        {
            Expression[] exprs = new Expression[args.count()];

            for (int i = 0; i < args.count(); i++)
            {
                Expr arg = (Expr)args.nth(i);
                exprs[i] = Compiler.MaybeBox(arg.GenDlr(context));
            }

            Expression argArray = Expression.NewArrayInit(typeof(object), exprs);
            return argArray;
        }
Beispiel #20
0
        public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context)
        {
            if (CompiledType != null)
            {
                return(CompiledType);
            }

            string publicTypeName = IsDefType /* || (CanBeDirect && Compiler.IsCompiling) */ ? InternalName : InternalName + "__" + RT.nextID();

            TypeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true);
            context     = context.WithNewDynInitHelper().WithTypeBuilder(TypeBuilder);

            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context));

            try
            {
                if (interfaces != null)
                {
                    for (int i = 0; i < interfaces.count(); i++)
                    {
                        TypeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i));
                    }
                }

                ObjExpr.MarkAsSerializable(TypeBuilder);
                GenInterface.SetCustomAttributes(TypeBuilder, ClassMeta);

                try
                {
                    if (IsDefType)
                    {
                        Compiler.RegisterDuplicateType(TypeBuilder);

                        Var.pushThreadBindings(RT.map(
                                                   Compiler.CompileStubOrigClassVar, stubType,
                                                   Compiler.CompilingDefTypeVar, true
                                                   ));
                        //,
                        //Compiler.COMPILE_STUB_CLASS, _baseType));
                    }
                    EmitConstantFieldDefs(TypeBuilder);
                    EmitKeywordCallsiteDefs(TypeBuilder);

                    DefineStaticConstructor(TypeBuilder);

                    if (SupportsMeta)
                    {
                        MetaField = TypeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly);
                    }

                    // If this IsDefType, then it has already emitted the closed-over fields on the base class.
                    if (!IsDefType)
                    {
                        EmitClosedOverFields(TypeBuilder);
                    }
                    EmitProtocolCallsites(TypeBuilder);

                    CtorInfo = EmitConstructor(TypeBuilder, superType);

                    if (AltCtorDrops > 0)
                    {
                        EmitFieldOnlyConstructors(TypeBuilder, superType);
                    }

                    if (SupportsMeta)
                    {
                        EmitNonMetaConstructor(TypeBuilder, superType);
                        EmitMetaFunctions(TypeBuilder);
                    }

                    EmitStatics(TypeBuilder);
                    EmitMethods(TypeBuilder);

                    CompiledType = TypeBuilder.CreateType();

                    if (context.DynInitHelper != null)
                    {
                        context.DynInitHelper.FinalizeType();
                    }

                    CtorInfo = GetConstructorWithArgCount(CompiledType, CtorTypes().Length);

                    return(CompiledType);
                }
                finally
                {
                    if (IsDefType)
                    {
                        Var.popThreadBindings();
                    }
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #21
0
        static bool doEquiv(IPersistentVector v, object obj)
        {
            if (obj is IList || obj is IPersistentVector)
            {
                ICollection ma = (ICollection)obj;
                if (ma.Count != v.count())
                    return false;
                IEnumerator ima = ma.GetEnumerator();
                foreach (object ov in ((IList)v))
                {
                    ima.MoveNext();
                    if (!Util.equiv(ov, ima.Current))
                        return false;
                }
                return true;
            }
            else
            {
                if (!(obj is Sequential))
                    return false;

                ISeq ms = RT.seq(obj);

                for (int i = 0; i < v.count(); i++, ms = ms.next())
                {
                    if (ms == null || !Util.equiv(v.nth(i), ms.first()))
                        return false;
                }
                if (ms != null)
                    return false;
            }
            return true;
        }
Beispiel #22
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);
                }
            }
        }
Beispiel #23
0
        /// <summary>
        /// Compares an <see cref="IPersistentVector">IPersistentVector</see> to another object for equality.
        /// </summary>
        /// <param name="v">The <see cref="IPersistentVector">IPersistentVector</see> to compare.</param>
        /// <param name="obj">The other object to compare.</param>
        /// <returns><value>true</value> if the specified Object is equal to the current Object; 
        /// otherwise, <value>false</value>.
        /// </returns>
        public static bool doEquals(IPersistentVector v, object obj)
        {
            if (obj is IList || obj is IPersistentVector)
            {
                IList ma = obj as IList;

                if (ma.Count != v.count() || ma.GetHashCode() != v.GetHashCode())
                    return false;

                for (int i = 0; i < v.count(); i++)
                {
                    if (!Util.equals(v.nth(i), ma[i]))
                        return false;
                }
                return true;
            }
            else
            {
                if (!(obj is Sequential))
                    return false;

                ISeq ms = RT.seq(obj);

                for (int i = 0; i < v.count(); i++, ms = ms.next())
                {
                    if (ms == null || !Util.equals(v.nth(i), ms.first()))
                        return false;
                }
                if (ms != null)
                    return false;
            }
            return true;
        }
Beispiel #24
0
 public static string PrimInterface(IPersistentVector arglist)
 {
     StringBuilder sb = new StringBuilder();
     for (int i = 0; i < arglist.count(); i++)
         sb.Append(TypeChar(Compiler.TagOf(arglist.nth(i))));
     sb.Append(TypeChar(Compiler.TagOf(arglist)));
     string ret = sb.ToString();
     bool prim = ret.Contains("L") || ret.Contains("D");
     if (prim && arglist.count() > 4)
         throw new ArgumentException("fns taking primitives support only 4 or fewer args");
     if (prim)
         return "clojure.lang.primifs." + ret;
     return null;
 }
Beispiel #25
0
        public static bool IsPrimInterface(IPersistentVector arglist)
        {
            if (arglist.count() > 4)
                return false;

            for (int i = 0; i < arglist.count(); i++)
                if (IsPrimType(Compiler.TagOf(arglist.nth(i))))
                    return true;

            if (IsPrimType(Compiler.TagOf(arglist)))
                return true;

            return false;
        }
Beispiel #26
0
        public static NewInstanceMethod Parse(ObjExpr objx, ISeq form, Symbol thisTag, Dictionary <IPersistentVector, IList <MethodInfo> > overrideables, Dictionary <IPersistentVector, IList <MethodInfo> > explicits)
        {
            // (methodname [this-name args*] body...)
            // this-name might be nil

            NewInstanceMethod method = new NewInstanceMethod(objx, (ObjMethod)Compiler.MethodVar.deref());

            Symbol dotName = (Symbol)RT.first(form);
            Symbol name;
            string methodName;

            int idx = dotName.Name.LastIndexOf(".");

            if (idx >= 0)
            {
                // we have an explicit interface implementation
                string dotNameStr    = dotName.Name;
                string interfaceName = dotNameStr.Substring(0, idx);

                method.ExplicitInterface = RT.classForName(interfaceName);
                if (method.ExplicitInterface == null)
                {
                    throw new ParseException(String.Format("Unable to find interface {0} for explicit method implemntation: {1}", interfaceName, dotNameStr));
                }

                methodName = dotNameStr.Substring(idx + 1);
                name       = (Symbol)Symbol.intern(null, Compiler.munge(dotName.Name)).withMeta(RT.meta(dotName));
            }
            else
            {
                name       = (Symbol)Symbol.intern(null, Compiler.munge(dotName.Name)).withMeta(RT.meta(dotName));
                methodName = name.Name;
            }

            IPersistentVector parms = (IPersistentVector)RT.second(form);

            if (parms.count() == 0 || !(parms.nth(0) is Symbol))
            {
                throw new ParseException("Must supply at least one argument for 'this' in: " + dotName);
            }

            Symbol thisName = (Symbol)parms.nth(0);

            parms = RT.subvec(parms, 1, parms.count());
            ISeq body = RT.next(RT.next(form));

            try
            {
                method.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

                // register as the current method and set up a new env frame
                // PathNode pnade = new PathNode(PATHTYPE.PATH, (PathNode) CLEAR_PATH.get());
                Var.pushThreadBindings(
                    RT.mapUniqueKeys(
                        Compiler.MethodVar, method,
                        Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                        Compiler.LoopLocalsVar, null,
                        Compiler.NextLocalNumVar, 0
                        // CLEAR_PATH, pnode,
                        // CLEAR_ROOT, pnode,
                        // CLEAR_SITES, PersistentHashMap.EMPTY
                        ));

                // register 'this' as local 0
                //method._thisBinding = Compiler.RegisterLocalThis(((thisName == null) ? dummyThis : thisName), thisTag, null);
                Compiler.RegisterLocalThis(((thisName == null) ? dummyThis : thisName), thisTag, null);

                IPersistentVector argLocals = PersistentVector.EMPTY;
                method._retType  = Compiler.TagType(Compiler.TagOf(name));
                method._argTypes = new Type[parms.count()];
                bool     hinted = Compiler.TagOf(name) != null;
                Type[]   pTypes = new Type[parms.count()];
                Symbol[] pSyms  = new Symbol[parms.count()];
                bool[]   pRefs  = new bool[parms.count()];

                for (int i = 0; i < parms.count(); i++)
                {
                    // Param should be symbol or (by-ref symbol)
                    Symbol p;
                    bool   isByRef = false;

                    object pobj = parms.nth(i);
                    if (pobj is Symbol)
                    {
                        p = (Symbol)pobj;
                    }
                    else if (pobj is ISeq)
                    {
                        ISeq   pseq   = (ISeq)pobj;
                        object first  = RT.first(pseq);
                        object second = RT.second(pseq);
                        if (!(first is Symbol && ((Symbol)first).Equals(HostExpr.ByRefSym)))
                        {
                            throw new ParseException("First element in parameter pair must be by-ref");
                        }
                        if (!(second is Symbol))
                        {
                            throw new ParseException("Params must be Symbols");
                        }
                        isByRef = true;
                        p       = (Symbol)second;
                        hinted  = true;
                    }
                    else
                    {
                        throw new ParseException("Params must be Symbols or of the form (by-ref Symbol)");
                    }

                    object tag = Compiler.TagOf(p);
                    if (tag != null)
                    {
                        hinted = true;
                    }
                    if (p.Namespace != null)
                    {
                        p = Symbol.intern(p.Name);
                    }
                    Type pType = Compiler.TagType(tag);
                    if (isByRef)
                    {
                        pType = pType.MakeByRefType();
                    }

                    pTypes[i] = pType;
                    pSyms[i]  = p;
                    pRefs[i]  = isByRef;
                }

                Dictionary <IPersistentVector, IList <MethodInfo> > matches =
                    method.IsExplicit
                    ? FindMethodsWithNameAndArity(method.ExplicitInterface, methodName, parms.count(), overrideables, explicits)
                    : FindMethodsWithNameAndArity(methodName, parms.count(), overrideables);

                IPersistentVector  mk = MSig(methodName, pTypes, method._retType);
                IList <MethodInfo> ms = null;
                if (matches.Count > 0)
                {
                    // multiple matches
                    if (matches.Count > 1)
                    {
                        // must be hinted and match one method
                        if (!hinted)
                        {
                            throw new ParseException("Must hint overloaded method: " + name.Name);
                        }
                        if (!matches.TryGetValue(mk, out ms))
                        {
                            throw new ParseException("Can't find matching overloaded method: " + name.Name);
                        }

                        method._minfos = ms;
                    }
                    else // one match
                    {
                        // if hinted, validate match,
                        if (hinted)
                        {
                            if (!matches.TryGetValue(mk, out ms))
                            {
                                throw new ParseException("Can't find matching method: " + name.Name + ", leave off hints for auto match.");
                            }

                            method._minfos = ms;

                            //if (m.ReturnType != method._retType)
                            //    throw new ArgumentException(String.Format("Mismatched return type: {0}, expected {1}, had: {2}",
                            //        name.Name, m.ReturnType.Name, method._retType.Name));
                        }
                        else // adopt found method sig
                        {
                            using (var e = matches.GetEnumerator())
                            {
                                e.MoveNext();
                                mk = e.Current.Key;
                                ms = e.Current.Value;
                            }
                            MethodInfo m = ms[0];
                            method._retType = m.ReturnType;
                            pTypes          = Compiler.GetTypes(m.GetParameters());
                            method._minfos  = ms;
                        }
                    }
                }
                else
                {
                    throw new ParseException("Can't define method not in interfaces: " + name.Name);
                }

                if (method.IsExplicit)
                {
                    method.ExplicitMethodInfo = ms[0];
                }

                // validate unique name + arity among additional methods

                for (int i = 0; i < parms.count(); i++)
                {
                    LocalBinding lb = Compiler.RegisterLocal(pSyms[i], null, new MethodParamExpr(pTypes[i]), true, pRefs[i]);
                    argLocals           = argLocals.assocN(i, lb);
                    method._argTypes[i] = pTypes[i];
                }

                Compiler.LoopLocalsVar.set(argLocals);
                method._name      = name.Name;
                method.MethodMeta = GenInterface.ExtractAttributes(RT.meta(name));
                method.Parms      = parms;
                method.ArgLocals  = argLocals;
                method.Body       = (new BodyExpr.Parser()).Parse(new ParserContext(RHC.Return), body);
                return(method);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #27
0
            public Expr Parse(object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (let  [var1 val1 var2 val2 ... ] body ... )
                //      or (loop [var1 val1 var2 val2 ... ] body ... )

                bool isLoop = RT.first(form).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 tjos 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 = RT.map(
                    Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(),
                    Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref());

                if (isLoop)
                {
                    dynamicBindings = dynamicBindings.assoc(Compiler.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);
                        }

                        Expr init = Compiler.GenerateAST(bindings.nth(i + 1));
                        // Sequential enhancement of env (like Lisp let*)
                        LocalBinding b  = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init);
                        BindingInit  bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);

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

                    return(new LetExpr(bindingInits,
                                       new BodyExpr.Parser().Parse(body),
                                       isLoop));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
            //(case* expr shift mask  default map<minhash, [test then]> table-type test-type skip-check?)
            //prepared by case macro and presumed correct
            //case macro binds actual expr in let so expr is always a local,
            //no need to worry about multiple evaluation
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                if (pcon.Rhc == RHC.Eval)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "case__" + RT.nextID()));
                }

                IPersistentVector args = LazilyPersistentVector.create(form.next());

                object         exprForm    = args.nth(0);
                int            shift       = Util.ConvertToInt(args.nth(1));
                int            mask        = Util.ConvertToInt(args.nth(2));
                object         defaultForm = args.nth(3);
                IPersistentMap caseMap     = (IPersistentMap)args.nth(4);
                Keyword        switchType  = (Keyword)args.nth(5);
                Keyword        testType    = (Keyword)args.nth(6);
                IPersistentSet skipCheck   = RT.count(args) < 8 ? null : (IPersistentSet)args.nth(7);

                ISeq             keys     = RT.keys(caseMap);
                int              low      = Util.ConvertToInt(RT.first(keys));
                int              high     = Util.ConvertToInt(RT.nth(keys, RT.count(keys) - 1));
                LocalBindingExpr testexpr = (LocalBindingExpr)Compiler.Analyze(pcon.SetRhc(RHC.Expression), exprForm);


                SortedDictionary <int, Expr> tests = new SortedDictionary <int, Expr>();
                Dictionary <int, Expr>       thens = new Dictionary <int, Expr>();

                foreach (IMapEntry me in caseMap)
                {
                    int    minhash  = Util.ConvertToInt(me.key());
                    object pair     = me.val(); // [test-val then-expr]
                    object first    = RT.first(pair);
                    Expr   testExpr = testType == _intKey
                        ? NumberExpr.Parse(Util.ConvertToInt(first))
                        : (first == null ? Compiler.NilExprInstance : new ConstantExpr(first));

                    tests[minhash] = testExpr;
                    Expr thenExpr;
                    thenExpr       = Compiler.Analyze(pcon, RT.second(pair));
                    thens[minhash] = thenExpr;
                }

                Expr defaultExpr;

                defaultExpr = Compiler.Analyze(pcon, defaultForm);

                return(new CaseExpr(
                           (IPersistentMap)Compiler.SourceSpanVar.deref(),
                           testexpr,
                           shift,
                           mask,
                           low,
                           high,
                           defaultExpr,
                           tests,
                           thens,
                           switchType,
                           testType,
                           skipCheck));
            }
Beispiel #29
0
        static public bool doEquals(IPersistentVector v, object obj)
        {
            if (v == obj)
            {
                return(true);
            }

            IPersistentVector ipv = obj as IPersistentVector;

            if (ipv != null)
            {
                if (ipv.count() != v.count())
                {
                    return(false);
                }

                for (int i = 0; i < v.count(); i++)
                {
                    if (!Util.equals(v.nth(i), ipv.nth(i)))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            IList ilist = obj as IList;

            if (ilist != null)
            {
                if (ilist.Count != v.count())   // THis test in the JVM code can't be right:  || ma.GetHashCode() != v.GetHashCode())
                {
                    return(false);
                }

                for (int i = 0; i < v.count(); i++)
                {
                    if (!Util.equals(v.nth(i), ilist[i]))
                    {
                        return(false);
                    }
                }
                return(true);
            }

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

            ISeq ms = RT.seq(obj);

            for (int i = 0; i < v.count(); i++, ms = ms.next())
            {
                if (ms == null || !Util.equals(v.nth(i), ms.first()))
                {
                    return(false);
                }
            }
            if (ms != null)
            {
                return(false);
            }

            return(true);
        }
Beispiel #30
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label?loopLabel = (Label)Compiler.LoopLabelVar.deref();

            if (loopLabel == null)
            {
                throw new InvalidOperationException("Recur not in proper context.");
            }

            {
                for (int i = 0; i < _loopLocals.count(); i++)
                {
                    LocalBinding lb  = (LocalBinding)_loopLocals.nth(i);
                    Expr         arg = (Expr)_args.nth(i);

                    Type primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr;
                        Type pt = Compiler.MaybePrimitiveType(arg);
                        if (pt == primt)
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                        }
                        else if (primt == typeof(long) && pt == typeof(int))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_I8);
                        }
                        else if (primt == typeof(double) && pt == typeof(float))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R8);
                        }
                        else if (primt == typeof(int) && pt == typeof(long))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.EmitCall(Compiler.Method_RT_intCast_long);
                        }
                        else if (primt == typeof(float) && pt == typeof(double))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R4);
                        }
                        else
                        {
                            throw new ArgumentException(String.Format(
                                                            "{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, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name));
                        }
                    }
                    else
                    {
                        arg.Emit(RHC.Expression, objx, ilg);
                    }
                }
            }
            for (int i = _loopLocals.count() - 1; i >= 0; i--)
            {
                LocalBinding lb = (LocalBinding)_loopLocals.nth(i);
                //Type primt = lb.PrimitiveType;
                if (lb.IsArg)
                {
                    //ilg.Emit(OpCodes.Starg, lb.Index - (objx.IsStatic ? 0 : 1));
                    ilg.EmitStoreArg(lb.Index);
                }
                else
                {
                    ilg.Emit(OpCodes.Stloc, lb.LocalVar);
                }
            }

            ilg.Emit(OpCodes.Br, loopLabel.Value);
        }
Beispiel #31
0
 /// <summary>
 /// Gets the first item.
 /// </summary>
 /// <returns>The first item.</returns>
 public override object first()
 {
     return(_v.nth(_i));
 }
Beispiel #32
0
        MethodBuilder GenerateStaticMethod(ObjExpr objx, GenContext context)
        {
            string      methodName = StaticMethodName;
            TypeBuilder tb         = objx.TypeBuilder;

            List <ParameterExpression> parms = new List <ParameterExpression>(_argLocals.count() + 1);
            List <Type> parmTypes            = new List <Type>(_argLocals.count() + 1);

            ParameterExpression thisParm = Expression.Parameter(objx.BaseType, "this");

            if (_thisBinding != null)
            {
                _thisBinding.ParamExpression = thisParm;
                _thisBinding.Tag             = Symbol.intern(null, objx.BaseType.FullName);
            }
            objx.ThisParam = thisParm;
            parms.Add(thisParm);
            parmTypes.Add(objx.BaseType);

            try
            {
                LabelTarget loopLabel = Expression.Label("top");

                Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this));

                Type[] argTypes = StaticMethodArgTypes;

                for (int i = 0; i < _argLocals.count(); i++)
                {
                    LocalBinding        lb   = (LocalBinding)_argLocals.nth(i);
                    ParameterExpression parm = Expression.Parameter(argTypes[i], lb.Name);
                    lb.ParamExpression = parm;
                    parms.Add(parm);
                    parmTypes.Add(argTypes[i]);
                }

                Expression body =
                    Expression.Block(
                        //maybeLoadVarsExpr,
                        Expression.Label(loopLabel),
                        GenBodyCode(StaticReturnType, objx, context));

                //Expression convBody = Compiler.MaybeConvert(body, ReturnType);
                Expression convBody = HostExpr.GenUnboxArg(body, StaticReturnType);

                LambdaExpression lambda = Expression.Lambda(convBody, parms);
                // JVM: Clears locals here.


                // TODO: Cache all the CreateObjectTypeArray values
                MethodBuilder mb = tb.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, StaticReturnType, parmTypes.ToArray());

                //Console.Write("StMd: {0} {1}(", ReturnType.Name, methodName);
                //foreach (Type t in parmTypes)
                //    Console.Write("{0}, ", t.Name);
                //Console.WriteLine(")");

                lambda.CompileToMethod(mb, context.IsDebuggable);

                _staticMethodBuilder = mb;
                return(mb);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
        internal static ObjExpr Build(
            IPersistentVector interfaceSyms, 
            IPersistentVector fieldSyms, 
            Symbol thisSym,
            string tagName, 
            Symbol className, 
            Symbol typeTag, 
            ISeq methodForms,
            Object frm,
            IPersistentMap opts)
        {
            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);
            ret.Opts = opts;

            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, 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.Equals("__meta") || ((Symbol)fieldSyms.nth(i)).Name.Equals("__extmap")); --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, IList<MethodInfo>> overrideables;
            Dictionary<IPersistentVector, IList<MethodInfo>> explicits;
            GatherMethods(superClass, RT.seq(interfaces), out overrideables, out explicits);

            ret._methodMap = overrideables;

  
            GenContext context = Compiler.IsCompiling
                ? Compiler.CompilerContextVar.get() as GenContext
                : (ret.IsDefType
                    ? GenContext.CreateWithExternalAssembly("deftype" + RT.nextID().ToString(), ".dll", true)
                    : (Compiler.CompilerContextVar.get() as GenContext
                        ??
                        Compiler.EvalContext));

            GenContext genC = context.WithNewDynInitHelper(ret.InternalName + "__dynInitHelper_" + RT.nextID().ToString());

            Type baseClass = ret.CompileBaseClass(genC, superClass, SeqToTypeArray(interfaces), frm);
            Symbol thisTag = Symbol.intern(null, baseClass.FullName);

            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,
                        Compiler.CompilerContextVar, genC
                        ));

                if (ret.IsDefType)
                {
                    Var.pushThreadBindings(
                        RT.mapUniqueKeys(
                            Compiler.MethodVar, null,
                            Compiler.LocalEnvVar, ret.Fields,
                            Compiler.CompileStubSymVar, Symbol.intern(null, tagName),
                            Compiler.CompileStubClassVar, baseClass
                            ));
                    ret.HintedFields = RT.subvec(fieldSyms, 0, fieldSyms.count() - ret.AltCtorDrops);
                }
                // now (methodname [args] body)*

                ret.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.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, explicits);
                    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 baseclass 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 baseclass classes and not try to convert, leading to a dynsite.

            ret.Compile(baseClass, baseClass, interfaces, false, genC);

            Compiler.RegisterDuplicateType(ret.CompiledType);

            return ret;
        }
Beispiel #34
0
        private static Expression GenerateVectorExpr(IPersistentVector v)
        {
            int n = v.count();
            Expression[] args = new Expression[v.count()];
            for (int i = 0; i < n; i++)
                args[i] = Generate(v.nth(i));

            Expression arrayExpr = Expression.NewArrayInit(typeof(object), MaybeBox(args));
            Expression ret = Expression.Call(Method_RT_vector, arrayExpr);
            ret = OptionallyGenerateMetaInit(v,ret);

            return ret;
        }
Beispiel #35
0
    object DrawStaticWidget(object key, object val)
    {
        if (val is string)
        {
            return(EditorGUILayout.TextField(key.ToString(), (string)val));
        }
        else if (val is bool)
        {
            return(EditorGUILayout.Toggle(key.ToString(), (bool)val));
        }
        else if (val is int)
        {
            return(EditorGUILayout.IntField(key.ToString(), (int)val));
        }
        else if (val is long)
        {
            return(EditorGUILayout.IntField(key.ToString(), (int)(long)val));
        }
        else if (val is Vector2)
        {
            return(EditorGUILayout.Vector2Field(key.ToString(), (Vector2)val));
        }
        else if (val is Vector3)
        {
            return(EditorGUILayout.Vector3Field(key.ToString(), (Vector3)val));
        }
        else if (val is Vector4)
        {
            return(EditorGUILayout.Vector4Field(key.ToString(), (Vector4)val));
        }
        else if (val is float)
        {
            return(EditorGUILayout.FloatField(key.ToString(), (float)val));
        }
        else if (val is double)
        {
            return(EditorGUILayout.FloatField(key.ToString(), (float)(double)val));
        }
        else if (val is Symbol)
        {
            return(Symbol.intern(EditorGUILayout.TextField(key.ToString(), val.ToString())));
        }
        else if (val is Keyword)
        {
            return(Keyword.intern(EditorGUILayout.TextField(key.ToString(), ((Keyword)val).ToString().Substring(1))));
        }
        else if (val is IPersistentMap)
        {
            IPersistentMap map = val as IPersistentMap;

            EditorGUILayout.LabelField(key.ToString(), "{");

            EditorGUI.indentLevel++;
            foreach (var entry in map)
            {
                map = map.assoc(entry.key(), DrawStaticWidget(entry.key(), entry.val()));
            }
            // EditorGUILayout.LabelField("", "}");
            EditorGUI.indentLevel--;
            return(map);
        }
        else if (val is IPersistentVector)
        {
            IPersistentVector vector = val as IPersistentVector;
            EditorGUILayout.LabelField(key.ToString(), "[");
            EditorGUI.indentLevel++;
            for (int i = 0; i < vector.count(); i++)
            {
                vector = vector.assocN(i, DrawStaticWidget(i.ToString(), vector.nth(i)));
            }
            // EditorGUILayout.LabelField("", "]");
            EditorGUI.indentLevel--;
            return(vector);
        }
        else
        {
            EditorGUILayout.LabelField(key.ToString(), "val.GetType().ToString()");
            return(val);
        }
    }
Beispiel #36
0
        internal static FnMethod Parse(FnExpr fn, ISeq form, object retTag)
        {
            // ([args] body ... )

            IPersistentVector parms = (IPersistentVector)RT.first(form);
            ISeq body = RT.next(form);

            try
            {
                FnMethod method = new FnMethod(fn, (ObjMethod)Compiler.MethodVar.deref());
                method.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

                Var.pushThreadBindings(RT.mapUniqueKeys(
                                           Compiler.MethodVar, method,
                                           Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                                           Compiler.LoopLocalsVar, null,
                                           Compiler.NextLocalNumVar, 0));

                method._prim = PrimInterface(parms);
                //if (method._prim != null)
                //    method._prim = method._prim.Replace('.', '/');


                if (retTag is String)
                {
                    retTag = Symbol.intern(null, (string)retTag);
                }
                if (!(retTag is Symbol))
                {
                    retTag = null;
                }
                if (retTag != null)
                {
                    string retStr = ((Symbol)retTag).Name;
                    if (!(retStr.Equals("long") || retStr.Equals("double")))
                    {
                        retTag = null;
                    }
                }
                method._retType = Compiler.TagType(Compiler.TagOf(parms) ?? retTag);

                if (method._retType.IsPrimitive)
                {
                    if (!(method._retType == typeof(double) || method._retType == typeof(long)))
                    {
                        throw new ParseException("Only long and double primitives are supported");
                    }
                }
                else
                {
                    method._retType = typeof(object);
                }

                // register 'this' as local 0
                Compiler.RegisterLocalThis(Symbol.intern(fn.ThisName ?? "fn__" + RT.nextID()), null, null);

                ParamParseState   paramState = ParamParseState.Required;
                IPersistentVector argLocals  = PersistentVector.EMPTY;
                List <Type>       argTypes   = new List <Type>();

                int parmsCount = parms.count();

                for (int i = 0; i < parmsCount; i++)
                {
                    if (!(parms.nth(i) is Symbol))
                    {
                        throw new ParseException("fn params must be Symbols");
                    }
                    Symbol p = (Symbol)parms.nth(i);
                    if (p.Namespace != null)
                    {
                        throw new ParseException("Can't use qualified name as parameter: " + p);
                    }
                    if (p.Equals(Compiler.AmpersandSym))
                    {
                        if (paramState == ParamParseState.Required)
                        {
                            paramState = ParamParseState.Rest;
                        }
                        else
                        {
                            throw new ParseException("Invalid parameter list");
                        }
                    }
                    else
                    {
                        Type pt = Compiler.PrimType(Compiler.TagType(Compiler.TagOf(p)));

                        if (pt.IsPrimitive && !(pt == typeof(double) || pt == typeof(long)))
                        {
                            throw new ParseException("Only long and double primitives are supported: " + p);
                        }

                        if (paramState == ParamParseState.Rest && Compiler.TagOf(p) != null)
                        {
                            throw new ParseException("& arg cannot have type hint");
                        }
                        if (paramState == ParamParseState.Rest && method.Prim != null)
                        {
                            throw new ParseException("fns taking primitives cannot be variadic");
                        }
                        if (paramState == ParamParseState.Rest)
                        {
                            pt = typeof(ISeq);
                        }
                        argTypes.Add(pt);
                        LocalBinding b = pt.IsPrimitive
                            ? Compiler.RegisterLocal(p, null, new MethodParamExpr(pt), pt, true)
                            : Compiler.RegisterLocal(p,
                                                     paramState == ParamParseState.Rest ? Compiler.ISeqSym : Compiler.TagOf(p),
                                                     null, pt, true);

                        argLocals = argLocals.cons(b);
                        switch (paramState)
                        {
                        case ParamParseState.Required:
                            method._reqParms = method._reqParms.cons(b);
                            break;

                        case ParamParseState.Rest:
                            method._restParm = b;
                            paramState       = ParamParseState.Done;
                            break;

                        default:
                            throw new ParseException("Unexpected parameter");
                        }
                    }
                }

                if (method.RequiredArity > Compiler.MaxPositionalArity)
                {
                    throw new ParseException(string.Format("Can't specify more than {0} parameters", Compiler.MaxPositionalArity));
                }
                Compiler.LoopLocalsVar.set(argLocals);
                method.ArgLocals = argLocals;
                method._argTypes = argTypes.ToArray();
                method.Body      = (new BodyExpr.Parser()).Parse(new ParserContext(RHC.Return), body);
                return(method);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #37
0
            public Expr Parse(object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (letfn*  [var1 (fn [args] body) ... ] body ... )

                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.
                // if (ctxt == C.EVAL)
                //    return Generate(RT.list(RT.list(Compiler.FN, PersistentVector.EMPTY, form)));


                IPersistentMap dynamicBindings = RT.map(
                    Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(),
                    Compiler.NEXT_LOCAL_NUM, Compiler.NEXT_LOCAL_NUM.deref());

                try
                {
                    Var.pushThreadBindings(dynamicBindings);

                    // pre-seed env (like Lisp labels)
                    IPersistentVector lbs = 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);
                        }

                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null);
                        lbs = lbs.cons(b);
                    }

                    IPersistentVector bindingInits = PersistentVector.EMPTY;

                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        Symbol sym  = (Symbol)bindings.nth(i);
                        Expr   init = Compiler.GenerateAST(bindings.nth(i + 1), sym.Name);
                        // Sequential enhancement of env (like Lisp let*)
                        LocalBinding b = (LocalBinding)lbs.nth(i / 2);
                        b.Init = init;
                        BindingInit bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);
                    }

                    return(new LetFnExpr(bindingInits, new BodyExpr.Parser().Parse(body)));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
        /// <summary>
        /// Compares an <see cref="IPersistentVector">IPersistentVector</see> to another object for equality.
        /// </summary>
        /// <param name="v">The <see cref="IPersistentVector">IPersistentVector</see> to compare.</param>
        /// <param name="obj">The other object to compare.</param>
        /// <returns><value>true</value> if the specified Object is equal to the current Object; 
        /// otherwise, <value>false</value>.
        /// </returns>
        public static bool doEquals(IPersistentVector v, object obj)
        {
            if ( obj is IList || obj is IPersistentVector )
            {
                IList ma = obj as IList;

                if (ma.Count != v.count() || ma.GetHashCode() != v.GetHashCode())
                    return false;

                for ( int i=0; i<v.count(); i++ )
                {
                    if (!Util.equals(v.nth(i), ma[i]))
                        return false;
                }
                return true;
            }

            // Example in original code of Sequential/IPersistentVector conflation.

            //if(!(obj instanceof Sequential))
            //        return false;
            //    ISeq ms = ((IPersistentCollection) obj).seq();
            //    for(int i = 0; i < v.count(); i++, ms = ms.rest())
            //        {
            //        if(ms == null || !Util.equals(v.nth(i), ms.first()))
            //            return false;
            //        }
            //    if(ms != null)
            //        return false;
            //    }

            //return true;

            ISeq ms = obj as ISeq;
            if (ms == null)
            {
                IPersistentCollection mc = obj as IPersistentCollection;
                if (mc == null)
                    return false;
                ms = mc.seq();
            }

            // Once we have the ISeq, we're ready to go.

            for (int i = 0; i < v.count(); i++, ms = ms.rest())
            {
                if (ms == null || !Util.equals(v.nth(i), ms.first()))
                    return false;
            }
            if (ms != null)
                return false;

            return true;
        }
Beispiel #39
0
        internal static FnMethod Parse(FnExpr fn, ISeq form)
        {
            // ([args] body ... )

            IPersistentVector parms = (IPersistentVector)RT.first(form);
            ISeq body = RT.next(form);

            try
            {
                FnMethod method = new FnMethod(fn, (FnMethod)Compiler.METHODS.deref());
                // TODO: method.line = (Integer) LINE.deref();


                Var.pushThreadBindings(RT.map(
                                           Compiler.METHODS, method,
                                           Compiler.LOCAL_ENV, Compiler.LOCAL_ENV.deref(),
                                           Compiler.LOOP_LOCALS, null,
                                           Compiler.NEXT_LOCAL_NUM, 0));

                // register 'this' as local 0
                method._thisBinding = Compiler.RegisterLocal(Symbol.intern(fn.ThisName ?? "fn__" + RT.nextID()), null, null);

                ParamParseState   paramState = ParamParseState.Required;
                IPersistentVector argLocals  = PersistentVector.EMPTY;
                int parmsCount = parms.count();

                for (int i = 0; i < parmsCount; i++)
                {
                    if (!(parms.nth(i) is Symbol))
                    {
                        throw new ArgumentException("fn params must be Symbols");
                    }
                    Symbol p = (Symbol)parms.nth(i);
                    if (p.Namespace != null)
                    {
                        throw new Exception("Can't use qualified name as parameter: " + p);
                    }
                    if (p.Equals(Compiler._AMP_))
                    {
                        if (paramState == ParamParseState.Required)
                        {
                            paramState = ParamParseState.Rest;
                        }
                        else
                        {
                            throw new Exception("Invalid parameter list");
                        }
                    }
                    else
                    {
                        LocalBinding b = Compiler.RegisterLocal(p,
                                                                paramState == ParamParseState.Rest ? Compiler.ISEQ : Compiler.TagOf(p),
                                                                null); // asdf-tag

                        argLocals = argLocals.cons(b);
                        switch (paramState)
                        {
                        case ParamParseState.Required:
                            method._reqParms = method._reqParms.cons(b);
                            break;

                        case ParamParseState.Rest:
                            method._restParm = b;
                            paramState       = ParamParseState.Done;
                            break;

                        default:
                            throw new Exception("Unexpected parameter");
                        }
                    }
                }

                if (method.NumParams > Compiler.MAX_POSITIONAL_ARITY)
                {
                    throw new Exception(string.Format("Can't specify more than {0} parameters", Compiler.MAX_POSITIONAL_ARITY));
                }
                Compiler.LOOP_LOCALS.set(argLocals);
                method._argLocals = argLocals;
                method._body      = (new BodyExpr.Parser()).Parse(body);
                return(method);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
        private static Type[] SeqToTypeArray(IPersistentVector interfaces)
        {
            Type[] types = new Type[interfaces.count()];
            for (int i = 0; i < interfaces.count(); i++)
                types[i] = (Type)interfaces.nth(i);

            return types;
        }
Beispiel #41
0
 public static void EmitTypedArgs(ObjExpr objx, CljILGen ilg, ParameterInfo[] parms, IPersistentVector args)
 {
     for (int i = 0; i < parms.Length; i++)
         EmitTypedArg(objx, ilg, parms[i].ParameterType, (Expr)args.nth(i));
 }
        public void NthOutOfRangeHighFails()
        {
            IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3);

            Expect(v.nth(4), EqualTo(1));
        }
Beispiel #43
0
        internal static void EmitArgsAsArray(IPersistentVector args, ObjExpr objx, CljILGen ilg)
        {
            ilg.EmitInt(args.count());
            ilg.Emit(OpCodes.Newarr, typeof(Object));

            for (int i = 0; i < args.count(); i++)
            {
                ilg.Emit(OpCodes.Dup);
                ilg.EmitInt(i);
                ((Expr)args.nth(i)).Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Stelem_Ref);
            }
        }
Beispiel #44
0
 internal static Expression[] GenTypedArgs(ObjExpr objx, GenContext context, Type[] paramTypes, IPersistentVector args)
 {
     Expression[] exprs = new Expression[paramTypes.Length];
     for (int i = 0; i < paramTypes.Length; i++)
         exprs[i] = GenTypedArg(objx, context, paramTypes[i], (Expr)args.nth(i));
     return exprs;
 }
Beispiel #45
0
        public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context)
        {
            if (_compiledType != null)
                return _compiledType;

            string publicTypeName = IsDefType || (_isStatic && Compiler.IsCompiling) ? InternalName : InternalName + "__" + RT.nextID();

            _typeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true);
            context = context.WithNewDynInitHelper().WithTypeBuilder(_typeBuilder);

            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context));

            try
            {
                if (interfaces != null)
                {
                    for (int i = 0; i < interfaces.count(); i++)
                        _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i));
                }

                ObjExpr.MarkAsSerializable(_typeBuilder);
                GenInterface.SetCustomAttributes(_typeBuilder, _classMeta);

                try
                {
                    if (IsDefType)
                    {
                        Compiler.RegisterDuplicateType(_typeBuilder);

                        Var.pushThreadBindings(RT.map(
                            Compiler.CompileStubOrigClassVar, stubType
                            ));
                        //,
                        //Compiler.COMPILE_STUB_CLASS, _baseType));
                    }
                    EmitConstantFieldDefs(_typeBuilder);
                    EmitKeywordCallsiteDefs(_typeBuilder);

                    DefineStaticConstructor(_typeBuilder);

                    if (SupportsMeta)
                        _metaField = _typeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly);

                    // If this IsDefType, then it has already emitted the closed-over fields on the base class.
                    if ( ! IsDefType )
                        EmitClosedOverFields(_typeBuilder);
                    EmitProtocolCallsites(_typeBuilder);

                    _ctorInfo = EmitConstructor(_typeBuilder, superType);

                    if (_altCtorDrops > 0)
                        EmitFieldOnlyConstructor(_typeBuilder, superType);

                    if (SupportsMeta)
                    {
                        EmitNonMetaConstructor(_typeBuilder, superType);
                        EmitMetaFunctions(_typeBuilder);
                    }

                    EmitStatics(_typeBuilder);
                    EmitMethods(_typeBuilder);

                    //if (KeywordCallsites.count() > 0)
                    //    EmitSwapThunk(_typeBuilder);

                    _compiledType = _typeBuilder.CreateType();

                    if (context.DynInitHelper != null)
                        context.DynInitHelper.FinalizeType();

                    _ctorInfo = GetConstructorWithArgCount(_compiledType, CtorTypes().Length);

                    return _compiledType;
                }
                finally
                {
                    if (IsDefType)
                        Var.popThreadBindings();
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #46
0
        private static object[] GetCtorArgs(IPersistentVector v)
        {
            object[] args = new object[v.length()];
            for (int i = 0; i < v.length(); i++)
                args[i] = v.nth(i);

            return args;
        }
Beispiel #47
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (let  [var1 val1 var2 val2 ... ] body ... )
                //      or (loop [var1 val1 var2 val2 ... ] body ... )

                bool isLoop = RT.first(form).Equals(Compiler.LoopSym);

                if (!(RT.second(form) is IPersistentVector bindings))
                {
                    throw new ParseException("Bad binding form, expected vector");
                }

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

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

                if (pcon.Rhc == RHC.Eval ||
                    (pcon.Rhc == RHC.Expression && isLoop))
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "let__" + RT.nextID()));
                }

                ObjMethod      method                  = (ObjMethod)Compiler.MethodVar.deref();
                IPersistentMap backupMethodLocals      = method.Locals;
                IPersistentMap backupMethodIndexLocals = method.IndexLocals;

                IPersistentVector recurMismatches = PersistentVector.EMPTY;

                for (int i = 0; i < bindings.count() / 2; i++)
                {
                    recurMismatches = recurMismatches.cons(false);
                }

                // may repeat once for each binding with a mismatch, return breaks
                while (true)
                {
                    IPersistentMap dynamicBindings = RT.map(
                        Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                        Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref());
                    method.SetLocals(backupMethodLocals, backupMethodIndexLocals);

                    if (isLoop)
                    {
                        dynamicBindings = dynamicBindings.assoc(Compiler.LoopLocalsVar, 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 ParseException("Bad binding form, expected symbol, got " + bindings.nth(i));
                            }

                            Symbol sym = (Symbol)bindings.nth(i);
                            if (sym.Namespace != null)
                            {
                                throw new ParseException("Can't let qualified name: " + sym);
                            }

                            Expr init = Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), bindings.nth(i + 1), sym.Name);
                            if (isLoop)
                            {
                                if (recurMismatches != null && RT.booleanCast(recurMismatches.nth(i / 2)))
                                {
                                    HostArg        ha  = new HostArg(HostArg.ParameterType.Standard, init, null);
                                    List <HostArg> has = new List <HostArg>(1)
                                    {
                                        ha
                                    };
                                    init = new StaticMethodExpr("", PersistentArrayMap.EMPTY, null, typeof(RT), "box", null, has, false);
                                    if (RT.booleanCast(RT.WarnOnReflectionVar.deref()))
                                    {
                                        RT.errPrintWriter().WriteLine("Auto-boxing loop arg: " + sym);
                                    }
                                }
                                else if (Compiler.MaybePrimitiveType(init) == typeof(int))
                                {
                                    List <HostArg> args = new List <HostArg>
                                    {
                                        new HostArg(HostArg.ParameterType.Standard, init, null)
                                    };
                                    init = new StaticMethodExpr("", null, null, typeof(RT), "longCast", null, args, false);
                                }
                                else if (Compiler.MaybePrimitiveType(init) == typeof(float))
                                {
                                    List <HostArg> args = new List <HostArg>
                                    {
                                        new HostArg(HostArg.ParameterType.Standard, init, null)
                                    };
                                    init = new StaticMethodExpr("", null, null, typeof(RT), "doubleCast", null, args, false);
                                }
                            }

                            // Sequential enhancement of env (like Lisp let*)
                            LocalBinding b  = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), init, typeof(Object), false);
                            BindingInit  bi = new BindingInit(b, init);
                            bindingInits = bindingInits.cons(bi);

                            if (isLoop)
                            {
                                loopLocals = loopLocals.cons(b);
                            }
                        }
                        if (isLoop)
                        {
                            Compiler.LoopLocalsVar.set(loopLocals);
                        }

                        Expr bodyExpr;
                        bool moreMismatches = false;
                        try
                        {
                            if (isLoop)
                            {
                                object methodReturnContext = pcon.Rhc == RHC.Return ? Compiler.MethodReturnContextVar.deref() : null;
                                // stuff with clear paths,
                                Var.pushThreadBindings(RT.map(Compiler.NoRecurVar, null,
                                                              Compiler.MethodReturnContextVar, methodReturnContext));
                            }
                            bodyExpr = new BodyExpr.Parser().Parse(isLoop ? pcon.SetRhc(RHC.Return) : pcon, body);
                        }
                        finally
                        {
                            if (isLoop)
                            {
                                Var.popThreadBindings();

                                for (int i = 0; i < loopLocals.count(); i++)
                                {
                                    LocalBinding lb = (LocalBinding)loopLocals.nth(i);
                                    if (lb.RecurMismatch)
                                    {
                                        recurMismatches = (IPersistentVector)recurMismatches.assoc(i, true);
                                        moreMismatches  = true;
                                    }
                                }
                            }
                        }

                        if (!moreMismatches)
                        {
                            return(new LetExpr(bindingInits, bodyExpr, isLoop));
                        }
                    }
                    finally
                    {
                        Var.popThreadBindings();
                    }
                }
            }
Beispiel #48
0
        public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context)
        {
            if (_compiledType != null)
                return _compiledType;

            string publicTypeName = IsDefType || (_isStatic && Compiler.IsCompiling) ? InternalName : InternalName + "__" + RT.nextID();

            //Console.WriteLine("DefFn {0}, {1}", publicTypeName, context.AssemblyBuilder.GetName().Name);

            _typeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true);
            context = context.WithNewDynInitHelper().WithTypeBuilder(_typeBuilder);

            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context));

            try
            {
                if (interfaces != null)
                {
                    for (int i = 0; i < interfaces.count(); i++)
                        _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i));
                }

                ObjExpr.MarkAsSerializable(_typeBuilder);
                GenInterface.SetCustomAttributes(_typeBuilder, _classMeta);

                try
                {
                    if (IsDefType)
                    {
                        Compiler.RegisterDuplicateType(_typeBuilder);

                        Var.pushThreadBindings(RT.map(
                            Compiler.CompileStubOrigClassVar, stubType
                            ));
                        //,
                        //Compiler.COMPILE_STUB_CLASS, _baseType));
                    }
                    EmitConstantFieldDefs(_typeBuilder);
                    EmitKeywordCallsiteDefs(_typeBuilder);

                    DefineStaticConstructor(_typeBuilder);

                    if (SupportsMeta)
                        _metaField = _typeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly);

                    EmitClosedOverFields(_typeBuilder);
                    EmitProtocolCallsites(_typeBuilder);

                    _ctorInfo = EmitConstructor(_typeBuilder, superType);

                    if (_altCtorDrops > 0)
                        EmitFieldOnlyConstructor(_typeBuilder, superType);

                    if (SupportsMeta)
                    {
                        EmitNonMetaConstructor(_typeBuilder, superType);
                        EmitMetaFunctions(_typeBuilder);
                    }

                    EmitStatics(_typeBuilder);
                    EmitMethods(_typeBuilder);

                    //if (KeywordCallsites.count() > 0)
                    //    EmitSwapThunk(_typeBuilder);

                    _compiledType = _typeBuilder.CreateType();

                    if (context.DynInitHelper != null)
                        context.DynInitHelper.FinalizeType();

                    //  If we don't pick up the ctor after we finalize the type,
                    //    we sometimes get a ctor which is not a RuntimeConstructorInfo
                    //  This causes System.DynamicILGenerator.Emit(opcode,ContructorInfo) to blow up.
                    //    The error says the ConstructorInfo is null, but there is a second case in the code.
                    //  Thank heavens one can run Reflector on mscorlib.

                    ConstructorInfo[] cis = _compiledType.GetConstructors();
                    foreach (ConstructorInfo ci in cis)
                    {
                        if (ci.GetParameters().Length == CtorTypes().Length)
                        {
                            _ctorInfo = ci;
                            break;
                        }
                    }

                    return _compiledType;
                }
                finally
                {
                    if (IsDefType)
                        Var.popThreadBindings();
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #49
0
        private void GenerateFnClass(IPersistentVector interfaces, GenContext context)
        {
            string publicTypeName = IsDefType || (IsStatic && Compiler.IsCompiling) ? _internalName : _internalName + "__" + RT.nextID();

            //Console.WriteLine("DefFn {0}, {1}", publicTypeName, context.AssemblyBuilder.GetName().Name);

            _typeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, _baseType, true);
            for (int i = 0; i < interfaces.count(); i++)
                _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i));

            MarkAsSerializable(_typeBuilder);

            GenInterface.SetCustomAttributes(_typeBuilder, _classMeta);

            GenerateStaticConstructor(_typeBuilder, _baseType, context.IsDebuggable);
            _ctorInfo = GenerateConstructor(_typeBuilder, _baseType);

            if (_altCtorDrops > 0)
                GenerateFieldOnlyConstructor(_typeBuilder, _baseType);

            if (SupportsMeta)
            {
                _nonmetaCtorInfo = GenerateNonMetaConstructor(_typeBuilder, _baseType);
            }
            GenerateMetaFunctions(_typeBuilder);

            //GenerateReloadVarsMethod(_typeBuilder, context);

            // The incoming context holds info on the containing function.
            // That is the one that holds the closed-over variable values.

            //GenContext newContext = CreateContext(context, _typeBuilder, _baseType);
            //GenerateMethods(newContext);
            GenerateStatics(context);
            GenerateMethods(context);
        }
Beispiel #50
0
        internal static Expression[] GenTypedArgArray(GenContext context, ParameterInfo[] infos, IPersistentVector args)
        {
            Expression[] exprs = new Expression[args.count()];

            for (int i = 0; i < infos.Length; i++)
            {
                Expr e = (Expr)args.nth(i);
                // Java: this is in a try/catch, where the catch prints a stack trace
                if (MaybePrimitiveType(e) == infos[i].ParameterType)
                    exprs[i] = ((MaybePrimitiveExpr)e).GenDlrUnboxed(context);
                else
                    // Java follows this with: HostExpr.emitUnboxArg(fn, gen, parameterTypes[i]);
                    //exprs[i] = e.GenDlr(context);
                    exprs[i] = Expression.Convert(e.GenDlr(context), infos[i].ParameterType); ;
            }
            return exprs;
        }
Beispiel #51
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, Compiler.munge(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)
            {
                IPersistentVector args = (IPersistentVector)value;
                if (args.count() <= Tuple.MAX_SIZE)
                {
                    for (int i = 0; i < args.count(); i++)
                        EmitValue(args.nth(i), ilg);
                    ilg.Emit(OpCodes.Call, Compiler.Methods_CreateTuple[args.count()]);
                }
                else
                {
                    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);
                }
            }
        }
Beispiel #52
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));
            }
Beispiel #53
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form => (letfn*  [var1 (fn [args] body) ... ] body ... )

                if (!(RT.second(form) is IPersistentVector bindings))
                {
                    throw new ParseException("Bad binding form, expected vector");
                }

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

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

                if (pcon.Rhc == RHC.Eval)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "letfn__" + RT.nextID()));
                }

                IPersistentMap dynamicBindings = RT.map(
                    Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(),
                    Compiler.NextLocalNumVar, Compiler.NextLocalNumVar.deref());

                try
                {
                    Var.pushThreadBindings(dynamicBindings);

                    // pre-seed env (like Lisp labels)
                    IPersistentVector lbs = PersistentVector.EMPTY;
                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        if (!(bindings.nth(i) is Symbol))
                        {
                            throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i));
                        }

                        Symbol sym = (Symbol)bindings.nth(i);
                        if (sym.Namespace != null)
                        {
                            throw new ParseException("Can't let qualified name: " + sym);
                        }

                        LocalBinding b = Compiler.RegisterLocal(sym, Compiler.TagOf(sym), null, typeof(Object), false);
                        // b.CanBeCleared = false;
                        lbs = lbs.cons(b);
                    }

                    IPersistentVector bindingInits = PersistentVector.EMPTY;
                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        Symbol       sym  = (Symbol)bindings.nth(i);
                        Expr         init = Compiler.Analyze(pcon.SetRhc(RHC.Expression), bindings.nth(i + 1), sym.Name);
                        LocalBinding b    = (LocalBinding)lbs.nth(i / 2);
                        b.Init = init;
                        BindingInit bi = new BindingInit(b, init);
                        bindingInits = bindingInits.cons(bi);
                    }

                    return(new LetFnExpr(bindingInits, new BodyExpr.Parser().Parse(pcon, body)));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Beispiel #54
0
        public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context)
        {
            if (_compiledType != null)
            {
                return(_compiledType);
            }

            string publicTypeName = IsDefType || (_isStatic && Compiler.IsCompiling) ? InternalName : InternalName + "__" + RT.nextID();

            //Console.WriteLine("DefFn {0}, {1}", publicTypeName, context.AssemblyBuilder.GetName().Name);

            _typeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true);
            context      = context.WithNewDynInitHelper().WithTypeBuilder(_typeBuilder);

            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context));

            try
            {
                if (interfaces != null)
                {
                    for (int i = 0; i < interfaces.count(); i++)
                    {
                        _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i));
                    }
                }

                ObjExpr.MarkAsSerializable(_typeBuilder);
                GenInterface.SetCustomAttributes(_typeBuilder, _classMeta);

                try
                {
                    if (IsDefType)
                    {
                        Compiler.RegisterDuplicateType(_typeBuilder);

                        Var.pushThreadBindings(RT.map(
                                                   Compiler.CompileStubOrigClassVar, stubType
                                                   ));
                        //,
                        //Compiler.COMPILE_STUB_CLASS, _baseType));
                    }
                    EmitConstantFieldDefs(_typeBuilder);
                    EmitKeywordCallsiteDefs(_typeBuilder);

                    DefineStaticConstructor(_typeBuilder);

                    if (SupportsMeta)
                    {
                        _metaField = _typeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly);
                    }

                    EmitClosedOverFields(_typeBuilder);
                    EmitProtocolCallsites(_typeBuilder);

                    _ctorInfo = EmitConstructor(_typeBuilder, superType);

                    if (_altCtorDrops > 0)
                    {
                        EmitFieldOnlyConstructor(_typeBuilder, superType);
                    }

                    if (SupportsMeta)
                    {
                        EmitNonMetaConstructor(_typeBuilder, superType);
                        EmitMetaFunctions(_typeBuilder);
                    }

                    EmitStatics(_typeBuilder);
                    EmitMethods(_typeBuilder);

                    //if (KeywordCallsites.count() > 0)
                    //    EmitSwapThunk(_typeBuilder);

                    _compiledType = _typeBuilder.CreateType();

                    if (context.DynInitHelper != null)
                    {
                        context.DynInitHelper.FinalizeType();
                    }

                    //  If we don't pick up the ctor after we finalize the type,
                    //    we sometimes get a ctor which is not a RuntimeConstructorInfo
                    //  This causes System.DynamicILGenerator.Emit(opcode,ContructorInfo) to blow up.
                    //    The error says the ConstructorInfo is null, but there is a second case in the code.
                    //  Thank heavens one can run Reflector on mscorlib.

                    ConstructorInfo[] cis = _compiledType.GetConstructors();
                    foreach (ConstructorInfo ci in cis)
                    {
                        if (ci.GetParameters().Length == CtorTypes().Length)
                        {
                            _ctorInfo = ci;
                            break;
                        }
                    }

                    return(_compiledType);
                }
                finally
                {
                    if (IsDefType)
                    {
                        Var.popThreadBindings();
                    }
                }
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Beispiel #55
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            LabelTarget loopLabel = (LabelTarget)Compiler.LoopLabelVar.deref();

            if (loopLabel == null)
            {
                throw new InvalidOperationException("Recur not in proper context.");
            }

            int argCount = _args.count();

            List <ParameterExpression> tempVars     = new List <ParameterExpression>(argCount);
            List <Expression>          tempAssigns  = new List <Expression>(argCount);
            List <Expression>          finalAssigns = new List <Expression>(argCount);

            // Evaluate all the init forms into local variables.
            for (int i = 0; i < _loopLocals.count(); i++)
            {
                LocalBinding lb  = (LocalBinding)_loopLocals.nth(i);
                Expr         arg = (Expr)_args.nth(i);

                ParameterExpression tempVar;
                Expression          valExpr;

                Type primt = lb.PrimitiveType;
                if (primt != null)
                {
                    tempVar = Expression.Parameter(primt, "__local__" + i);

                    MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr;
                    Type pt = Compiler.MaybePrimitiveType(arg);
                    if (pt == primt)
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        // do nothing
                    }
                    else if (primt == typeof(long) && pt == typeof(int))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else if (primt == typeof(double) && pt == typeof(float))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else if (primt == typeof(int) && pt == typeof(long))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else if (primt == typeof(float) && pt == typeof(double))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else
                    {
                        //if (true) //RT.booleanCast(RT.WARN_ON_REFLECTION.deref()))
                        //RT.errPrintWriter().WriteLine
                        throw new ArgumentException(String.Format(
                                                        "{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, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name));
                        //valExpr = arg.GenCode(RHC.Expression, objx, context);
                        // valExpr = Expression.Convert(valExpr, primt);
                    }
                }
                else
                {
                    tempVar = Expression.Parameter(lb.ParamExpression.Type, "__local__" + i);
                    valExpr = arg.GenCode(RHC.Expression, objx, context);
                }


                //ParameterExpression tempVar = Expression.Parameter(lb.ParamExpression.Type, "__local__" + i);
                //Expression valExpr = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context);
                tempVars.Add(tempVar);

                //if (tempVar.Type == typeof(Object))
                //    tempAssigns.Add(Expression.Assign(tempVar, Compiler.MaybeBox(valExpr)));
                //else
                //    tempAssigns.Add(Expression.Assign(tempVar, Expression.Convert(valExpr, tempVar.Type)));
                if (valExpr.Type.IsPrimitive && !tempVar.Type.IsPrimitive)
                {
                    tempAssigns.Add(Expression.Assign(tempVar, Compiler.MaybeBox(valExpr)));
                }
                else if (!valExpr.Type.IsPrimitive && tempVar.Type.IsPrimitive)
                {
                    tempAssigns.Add(Expression.Assign(tempVar, HostExpr.GenUnboxArg(valExpr, tempVar.Type)));
                }
                else
                {
                    tempAssigns.Add(Expression.Assign(tempVar, valExpr));
                }

                finalAssigns.Add(Expression.Assign(lb.ParamExpression, tempVar));
            }

            List <Expression> exprs = tempAssigns;

            exprs.AddRange(finalAssigns);
            exprs.Add(Expression.Goto(loopLabel));
            // need to do this to get a return value in the type inferencing -- else can't use this in a then or else clause.
            exprs.Add(Expression.Constant(null));
            return(Expression.Block(tempVars, exprs));
        }