コード例 #1
0
 public override object invoke(Object obj)
 {
     return(RT.get(obj, this));
 }
コード例 #2
0
 public override object invoke(Object obj, Object notFound)
 {
     return(RT.get(obj, this, notFound));
 }
コード例 #3
0
        public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args, bool tailPosition)
        {
            _source       = source;
            _spanMap      = spanMap;
            _fexpr        = fexpr;
            _args         = args;
            _tailPosition = tailPosition;

            VarExpr varFexpr = fexpr as VarExpr;

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

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

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

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

            fn._src = form;

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

            fn.ComputeNames(form, name);

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

            //arglist might be preceded by symbol naming this fn
            Symbol nm = RT.second(form) as Symbol;

            if (nm != null)
            {
                fn._thisName = nm.Name;
                fn._isStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY));
                form         = RT.cons(Compiler.FnSym, RT.next(RT.next(form)));
            }

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

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

            GenContext newContext = null;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext;

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


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

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

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

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

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

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

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


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


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

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

                if (fn.SupportsMeta)
                {
                    return(new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta)));
                }
                else
                {
                    return(fn);
                }
            }
            finally
            {
                if (newContext != null)
                {
                    Var.popThreadBindings();
                }
            }
        }
コード例 #5
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            bool tailPosition = Compiler.InTailCall(pcon.Rhc);

            pcon = pcon.EvalOrExpr();

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

            if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar) && RT.count(form) == 3)
            {
                Expr         sexpr  = Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.second(form));
                ConstantExpr csexpr = sexpr as ConstantExpr;
                if (csexpr != null)
                {
                    Type tval = csexpr.Val as Type;
                    if (tval != null)
                    {
                        return(new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), tval, Compiler.Analyze(pcon, RT.third(form))));
                    }
                }
            }

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

            KeywordExpr kwFexpr = fexpr as KeywordExpr;

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

            IPersistentVector args = PersistentVector.EMPTY;

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

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

            return(new InvokeExpr((string)Compiler.SourceVar.deref(),
                                  (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form),
                                  Compiler.TagOf(form),
                                  fexpr,
                                  args,
                                  tailPosition));
        }
コード例 #6
0
 /// <summary>
 /// (:keyword arg default) => (get arg :keyword default)
 /// </summary>
 /// <param name="arg1">The object to access.</param>
 /// <param name="arg2">Default value if not found.</param>
 /// <returns></returns>
 public override object invoke(object arg1, object arg2)
 {
     return(RT.get(arg1, this, arg2));
 }
コード例 #7
0
ファイル: FnExpr.cs プロジェクト: ryrency/Misc
        public static Expr Parse(object frm, string name)
        {
            ISeq form = (ISeq)frm;

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

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


            fn.ComputeNames(form, name);

            try
            {
                Var.pushThreadBindings(RT.map(
                                           Compiler.CONSTANTS, PersistentVector.EMPTY,
                                           Compiler.KEYWORDS, PersistentHashMap.EMPTY,
                                           Compiler.VARS, PersistentHashMap.EMPTY));

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

                // Normalize body
                // If it is (fn [arg...] body ...), turn it into
                //          (fn ([arg...] body...))
                // so that we can treat uniformly as (fn ([arg...] body...) ([arg...] body...) ... )
                if (RT.second(form) is IPersistentVector)
                {
                    form = RT.list(Compiler.FN, RT.next(form));
                }


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

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

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

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

                fn._methods        = allMethods;
                fn._variadicMethod = variadicMethod;
                fn._keywords       = (IPersistentMap)Compiler.KEYWORDS.deref();
                fn._vars           = (IPersistentMap)Compiler.VARS.deref();
                fn._constants      = (PersistentVector)Compiler.CONSTANTS.deref();
                fn._constantsID    = RT.nextID();
            }
            finally
            {
                Var.popThreadBindings();
            }
            // JAVA: fn.compile();
            return(fn);
        }
コード例 #8
0
ファイル: DefExpr.cs プロジェクト: terkhorn/clojure-clr
            public Expr Parse(ParserContext pcon, object form)
            {
                // (def x) or (def x initexpr) or (def x "docstring" initexpr)
                string docstring = null;

                if (RT.count(form) == 4 && (RT.third(form) is String))
                {
                    docstring = (String)RT.third(form);
                    form      = RT.list(RT.first(form), RT.second(form), RT.fourth(form));
                }

                if (RT.count(form) > 3)
                {
                    throw new ParseException("Too many arguments to def");
                }

                if (RT.count(form) < 2)
                {
                    throw new ParseException("Too few arguments to def");
                }

                Symbol sym = RT.second(form) as Symbol;

                if (sym == null)
                {
                    throw new ParseException("First argument to def must be a Symbol.");
                }

                //Console.WriteLine("Def {0}", sym.Name);

                Var v = Compiler.LookupVar(sym, true);

                if (v == null)
                {
                    throw new ParseException("Can't refer to qualified var that doesn't exist");
                }

                if (!v.Namespace.Equals(Compiler.CurrentNamespace))
                {
                    if (sym.Namespace == null)
                    {
                        v = Compiler.CurrentNamespace.intern(sym);
                    }

                    //throw new Exception(string.Format("Name conflict, can't def {0} because namespace: {1} refers to: {2}",
                    //            sym, Compiler.CurrentNamespace.Name, v));
                    else
                    {
                        throw new ParseException("Can't create defs outside of current namespace");
                    }
                }

                IPersistentMap mm        = sym.meta();
                bool           isDynamic = RT.booleanCast(RT.get(mm, Compiler.DynamicKeyword));

                if (isDynamic)
                {
                    v.setDynamic();
                }
                if (!isDynamic && sym.Name.StartsWith("*") && sym.Name.EndsWith("*") && sym.Name.Length > 1)
                {
                    RT.errPrintWriter().WriteLine("Warning: {0} not declared dynamic and thus is not dynamically rebindable, "
                                                  + "but its name suggests otherwise. Please either indicate ^:dynamic {0} or change the name. ({1}:{2}\n",
                                                  sym, Compiler.SourcePathVar.get(), Compiler.LineVar.get());
                }

                if (RT.booleanCast(RT.get(mm, Compiler.ArglistsKeyword)))
                {
                    IPersistentMap vm = v.meta();
                    //vm = (IPersistentMap)RT.assoc(vm, Compiler.STATIC_KEY, true);
                    // drop quote
                    vm = (IPersistentMap)RT.assoc(vm, Compiler.ArglistsKeyword, RT.second(mm.valAt(Compiler.ArglistsKeyword)));
                    v.setMeta(vm);
                }

                Object source_path = Compiler.SourcePathVar.get();

                source_path = source_path ?? "NO_SOURCE_FILE";
                mm          = (IPersistentMap)RT.assoc(mm, RT.LineKey, Compiler.LineVar.get())
                              .assoc(RT.FileKey, source_path);
                //.assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref());
                if (docstring != null)
                {
                    mm = (IPersistentMap)RT.assoc(mm, RT.DocKey, docstring);
                }

                //mm = mm.without(RT.DOC_KEY)
                //            .without(Keyword.intern(null, "arglists"))
                //            .without(RT.FILE_KEY)
                //            .without(RT.LINE_KEY)
                //            .without(Keyword.intern(null, "ns"))
                //            .without(Keyword.intern(null, "name"))
                //            .without(Keyword.intern(null, "added"))
                //            .without(Keyword.intern(null, "static"));

                mm = (IPersistentMap)Compiler.ElideMeta(mm);

                Expr meta         = mm == null || mm.count() == 0 ? null : Compiler.Analyze(pcon.EvalOrExpr(), mm);
                Expr init         = Compiler.Analyze(pcon.EvalOrExpr(), RT.third(form), v.Symbol.Name);
                bool initProvided = RT.count(form) == 3;

                return(new DefExpr(
                           (string)Compiler.SourceVar.deref(),
                           (int)Compiler.LineVar.deref(),
                           v, init, meta, initProvided, isDynamic));
            }
コード例 #9
0
 internal bool IsVolatile(LocalBinding lb)
 {
     return(RT.booleanCast(RT.contains(_fields, lb.Symbol)) &&
            RT.booleanCast(RT.get(lb.Symbol.meta(), Keyword.intern("volatile-mutable"))));
 }