Ejemplo n.º 1
0
        public CaseExpr(IPersistentMap sourceSpan, LocalBindingExpr expr, int shift, int mask, int low, int high, Expr defaultExpr,
                        SortedDictionary <int, Expr> tests, Dictionary <int, Expr> thens, Keyword switchType, Keyword testType, IPersistentSet skipCheck)
        {
            _sourceSpan  = sourceSpan;
            _expr        = expr;
            _shift       = shift;
            _mask        = mask;
            _low         = low;
            _high        = high;
            _defaultExpr = defaultExpr;
            _tests       = tests;
            _thens       = thens;
            if (switchType != _compactKey && switchType != _sparseKey)
            {
                throw new ArgumentException("Unexpected switch type: " + switchType);
            }
            _switchType = switchType;
            if (testType != _intKey && testType != _hashEquivKey && testType != _hashIdentityKey)
            {
                throw new ArgumentException("Unexpected test type: " + testType);
            }
            _testType  = testType;
            _skipCheck = skipCheck;
            ICollection <Expr> returns = new List <Expr>(thens.Values);

            returns.Add(defaultExpr);
            _returnType = Compiler.MaybeClrType(returns);
            if (RT.count(skipCheck) > 0 && RT.booleanCast(RT.WarnOnReflectionVar.deref()))
            {
                RT.errPrintWriter().WriteLine("Performance warning, {0}:{1}:{2} - hash collision of some case test constants; if selected, those entries will be tested sequentially.",
                                              Compiler.SourcePathVar.deref(), Compiler.GetLineFromSpanMap(sourceSpan), Compiler.GetColumnFromSpanMap(sourceSpan));
            }
        }
Ejemplo n.º 2
0
        public static Expr Parse(Var v, ISeq args, object tag)
        {
            if (!v.isBound || v.get() == null)
            {
                //Console.WriteLine("Not bound: {0}", v);
                return(null);
            }

            Type target = v.get().GetType();

            MethodInfo[] allMethods = target.GetMethods();
            bool         variadic   = false;
            int          argcount   = RT.count(args);
            MethodInfo   method     = null;

            ParameterInfo[] pInfos = null;

            foreach (MethodInfo m in allMethods)
            {
                //Console.WriteLine("Method {0}", m.Name);
                if (m.IsStatic && m.Name.Equals("invokeStatic"))
                {
                    pInfos = m.GetParameters();
                    if (argcount == pInfos.Length)
                    {
                        method   = m;
                        variadic = argcount > 0 && pInfos[pInfos.Length - 1].ParameterType == typeof(ISeq);
                        break;
                    }
                    else if (argcount > pInfos.Length &&
                             pInfos.Length > 0 &&
                             pInfos[pInfos.Length - 1].ParameterType == typeof(ISeq))
                    {
                        method   = m;
                        variadic = true;
                        break;
                    }
                }
            }

            if (method == null)
            {
                return(null);
            }

            IPersistentVector argv = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(args); s != null; s = s.next())
            {
                argv = argv.cons(Compiler.Analyze(new ParserContext(RHC.Expression), s.first()));
            }

            return(new StaticInvokeExpr(target, method, variadic, argv, tag));
        }
Ejemplo n.º 3
0
            public Expr Parse(object form)
            {
                // (def x) or (def x initexpr)
                if (RT.count(form) > 3)
                {
                    throw new Exception("Too many arguments to def");
                }

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

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

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

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

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

                if (!v.Namespace.Equals(Compiler.CurrentNamespace))
                {
                    if (sym.Namespace == null)
                    {
                        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 Exception("Can't create defs outside of current namespace");
                    }
                }

                IPersistentMap mm = sym.meta();
                // TODO: add source and line info metadata.
                //Object source_path = SOURCE_PATH.get();
                //source_path = source_path == null ? "NO_SOURCE_FILE" : source_path;
                //mm = (IPersistentMap)RT.assoc(mm, RT.LINE_KEY, LINE.get()).assoc(RT.FILE_KEY, source_path);

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

                return(new DefExpr(v, init, meta, initProvided));
            }
Ejemplo n.º 4
0
            public Expr Parse(ParserContext pcon, object form)
            {
                int argCount = RT.count(form) - 1;

                if (argCount != 1)
                {
                    IPersistentMap exData = new PersistentArrayMap(new Object[] { FormKey, form });
                    throw new ExceptionInfo("Wrong number of args (" +
                                            argCount +
                                            ") passed to quote",
                                            exData);
                }

                object v = RT.second(form);

                if (v == null)
                {
                    return(Compiler.NilExprInstance);
                }
                else if (v is Boolean)
                {
                    if ((bool)v)
                    {
                        return(Compiler.TrueExprInstance);
                    }
                    else
                    {
                        return(Compiler.FalseExprInstance);
                    }
                }
                else if (Util.IsNumeric(v))
                {
                    return(NumberExpr.Parse(v));
                }
                else if (v is string)
                {
                    return(new StringExpr((String)v));
                }
                else if (v is IPersistentCollection && ((IPersistentCollection)v).count() == 0)
                {
                    return(new EmptyExpr(v));
                }
                else
                {
                    return(new ConstantExpr(v));
                }
            }
Ejemplo n.º 5
0
        public static Def createSlotMap(ISeq keys)
        {
            if (keys == null)
            {
                throw new ArgumentException("Must supply keys");
            }
            int c = RT.count(keys);

            object[] v = new object[2 * c];
            int      i = 0;

            for (ISeq s = keys; s != null; s = s.next(), i++)
            {
                v[2 * i]     = s.first();
                v[2 * i + 1] = i;
            }
            return(new Def(keys, RT.map(v)));
        }
Ejemplo n.º 6
0
            public Expr Parse(ParserContext pcon, object form)
            {
                if (pcon.Rhc == RHC.Eval)
                {
                    return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "throw__" + RT.nextID()));
                }

                if (RT.Length((ISeq)form) == 1)
                {
                    return(new ThrowExpr());
                }

                if (RT.count(form) > 2)
                {
                    throw new InvalidOperationException("Too many arguments to throw, throw expects a single Exception instance");
                }

                return(new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form))));
            }
Ejemplo n.º 7
0
            //(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));
            }
Ejemplo n.º 8
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvalOrExpr();

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

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

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

            KeywordExpr kwFexpr = fexpr as KeywordExpr;

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

            IPersistentVector args = PersistentVector.EMPTY;

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

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

            return(new InvokeExpr((string)Compiler.SourceVar.deref(),
                                  (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form),
                                  Compiler.TagOf(form),
                                  fexpr,
                                  args));
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Gets the number of items in the collection.
 /// </summary>
 /// <returns>The number of items in the collection.</returns>
 public override int count()
 {
     return(_vals.Length + RT.count(_ext));
 }
Ejemplo n.º 10
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

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

            fn._src = form;

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

            fn.ComputeNames(form, name);

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

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

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

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

            GenContext newContext = null;

            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();
                }
            }
        }
Ejemplo n.º 11
0
            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);
                        Compiler.RegisterVar(v);
                    }

                    //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 > 2)
                {
                    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.ColumnKey, Compiler.ColumnVar.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);
                }

                //  Following comment in JVM version
                //mm = mm.without(RT.DOC_KEY)
                //            .without(Keyword.intern(null, "arglists"))
                //            .without(RT.FILE_KEY)
                //            .without(RT.LINE_KEY)
                //            .without(RT.COLUMN_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(),
                           Compiler.LineVarDeref(),
                           Compiler.ColumnVarDeref(),
                           v, init, meta, initProvided, isDynamic));
            }
Ejemplo n.º 12
0
 /// <summary>
 /// Gets the number of items in the collection.
 /// </summary>
 /// <returns>The number of items in the collection.</returns>
 public int count()
 {
     return(RT.count(_f) + RT.count(_r));
 }
Ejemplo n.º 13
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));
                if (sexpr is ConstantExpr csexpr)
                {
                    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 (RT.booleanCast(Compiler.GetCompilerOption(Compiler.DirectLinkingKeyword)) &&
                varFexpr != null &&
                pcon.Rhc != RHC.Eval)
            {
                Var v = varFexpr.Var;
                if (!v.isDynamic() && !RT.booleanCast(RT.get(v.meta(), Compiler.RedefKeyword, false)) && !RT.booleanCast(RT.get(v.meta(), RT.DeclaredKey, false)))
                {
                    Symbol formTag = Compiler.TagOf(form);
                    //object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword);
                    int    arity  = RT.count(form.next());
                    object sigtag = SigTag(arity, v);
                    object vtag   = RT.get(RT.meta(v), RT.TagKey);
                    if (StaticInvokeExpr.Parse(v, RT.next(form), formTag ?? sigtag ?? vtag) is StaticInvokeExpr ret && !((Compiler.IsCompiling || Compiler.IsCompilingDefType) && GenContext.IsInternalAssembly(ret.Method.DeclaringType.Assembly)))
                    {
                        //Console.WriteLine("invoke direct: {0}", v);
                        return(ret);
                    }
                    //Console.WriteLine("NOT direct: {0}", v);
                }
            }

            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;
                    }
                }
            }

            if (fexpr is KeywordExpr kwFexpr && 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));
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Gets the number of items in the collection.
 /// </summary>
 /// <returns>The number of items in the collection.</returns>
 public override int count()
 {
     return(1 + RT.count(_more));
 }
Ejemplo n.º 15
0
        private Expression GenerateValue(object value)
        {
            bool       partial = true;
            Expression ret;

            if (value is String)
            {
                ret = Expression.Constant((String)value);
            }
            else if (Util.IsPrimitive(value.GetType())) // or just IsNumeric?
            {
                ret = Expression.Constant(value);
            }
            else if (value is Type)
            {
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_classForName,
                    Expression.Constant(((Type)value).FullName));
            }
            else if (value is Symbol)
            {
                Symbol sym = (Symbol)value;
                ret = Expression.Call(
                    null,
                    Compiler.Method_Symbol_create2,
                    Expression.Convert(Expression.Constant(sym.Namespace), typeof(string)), // can be null
                    Expression.Constant(sym.Name));
            }
            else if (value is Keyword)
            {
                ret = Expression.Call(
                    null,
                    Compiler.Method_Keyword_intern,
                    GenerateValue(((Keyword)value).Symbol));
            }
            else if (value is Var)
            {
                Var var = (Var)value;
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_var2,
                    Expression.Constant(var.Namespace.Name.ToString()),
                    Expression.Constant(var.Symbol.Name.ToString()));
            }
            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());
                }
                Expression expr = GenerateListAsObjectArray(entries);
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_map,
                    expr);
            }
            else if (value is IPersistentVector)
            {
                Expression expr = GenerateListAsObjectArray(value);
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_vector,
                    expr);
            }
            else if (value is ISeq || value is IPersistentList)
            {
                Expression expr = GenerateListAsObjectArray(value);
                ret = Expression.Call(
                    null,
                    Compiler.Method_PersistentList_create,
                    expr);
            }
            else
            {
                string cs = null;
                try
                {
                    cs = RT.printString(value);
                }
                catch (Exception)
                {
                    throw new Exception(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value));
                }
                if (cs.Length == 0)
                {
                    throw new Exception(String.Format("Can't embed unreadable object in code: " + value));
                }
                if (cs.StartsWith("#<"))
                {
                    throw new Exception(String.Format("Can't embed unreadable object in code: " + cs));
                }

                ret     = Expression.Call(Compiler.Method_RT_readString, Expression.Constant(cs));
                partial = false;
            }

            if (partial)
            {
                if (value is Obj && RT.count(((Obj)value).meta()) > 0)
                {
                    Expression objExpr  = Expression.Convert(ret, typeof(Obj));
                    Expression metaExpr = Expression.Convert(GenerateValue(((Obj)value).meta()), typeof(IPersistentMap));
                    ret = Expression.Call(
                        objExpr,
                        Compiler.Method_IObj_withMeta,
                        metaExpr);
                }
            }
            return(ret);
        }
Ejemplo n.º 16
0
        protected Expression GenerateValue(object value)
        {
            bool       partial = true;
            Expression ret;

            if (value == null)
            {
                ret = Expression.Constant(null);
            }

            else if (value is String)
            {
                ret = Expression.Constant((String)value);
            }
            else if (value is Boolean)
            {
                ret = Expression.Constant((Boolean)value);
            }
            else if (Util.IsPrimitive(value.GetType()))  // or just IsNumeric?
            {
                ret = Expression.Constant(value);
            }
            else if (value is Type)
            {
                Type t = (Type)value;
                if (t.IsValueType)
                {
                    ret = Expression.Constant(t, typeof(Type));
                }
                else
                {
                    ret = Expression.Call(
                        null,
                        Compiler.Method_RT_classForName,
                        Expression.Constant(Compiler.DestubClassName(((Type)value).FullName)));
                }
            }
            else if (value is Symbol)
            {
                Symbol sym = (Symbol)value;
                ret = Expression.Call(
                    null,
                    Compiler.Method_Symbol_intern2,
                    Expression.Convert(Expression.Constant(sym.Namespace), typeof(string)),  // can be null
                    Expression.Constant(sym.Name));
            }
            else if (value is Keyword)
            {
                Keyword keyword = (Keyword)value;
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_keyword,
                    Expression.Convert(Expression.Constant(keyword.Namespace), typeof(string)),  // can be null
                    Expression.Constant(keyword.Name));
            }
            else if (value is Var)
            {
                Var var = (Var)value;
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_var2,
                    Expression.Constant(var.Namespace.Name.ToString()),
                    Expression.Constant(var.Symbol.Name.ToString()));
            }
            else if (value is IType)
            {
                IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes);
                List <Expression> args   = new List <Expression>();

                for (ISeq s = RT.seq(fields); s != null; s = s.next())
                {
                    Symbol     field = (Symbol)s.first();
                    Type       k     = Compiler.TagType(Compiler.TagOf(field));
                    object     val   = Reflector.GetInstanceFieldOrProperty(value, field.Name);
                    Expression expr  = GenerateValue(val);
                    if (k.IsPrimitive)
                    {
                        expr = Expression.Convert(expr, k);
                    }
                    else
                    {
                        expr = Compiler.MaybeBox(expr);
                    }
                    args.Add(expr);
                }

                ConstructorInfo cinfo = value.GetType().GetConstructors()[0];
                ret = Expression.New(cinfo, args);
            }
            else if (value is IRecord)
            {
                //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public);
                ret = Expression.Call(
                    value.GetType(),
                    "create",
                    Type.EmptyTypes,
                    //new Type[] { typeof(IPersistentMap) },
                    GenerateValue(PersistentArrayMap.create((IDictionary)value)));
            }
            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());
                }
                Expression expr = GenerateListAsObjectArray(entries);
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_map,
                    expr);
            }
            else if (value is IPersistentVector)
            {
                Expression expr = GenerateListAsObjectArray(value);
                ret = Expression.Call(
                    null,
                    Compiler.Method_RT_vector,
                    expr);
            }
            else if (value is PersistentHashSet)
            {
                ISeq vs = RT.seq(value);
                if (vs == null)
                {
                    ret = Expression.Field(null, Compiler.Method_PersistentHashSet_EMPTY);
                }
                else
                {
                    Expression expr = GenerateListAsObjectArray(vs);
                    ret = Expression.Call(
                        null,
                        Compiler.Method_PersistentHashSet_create,
                        expr);
                }
            }
            else if (value is ISeq || value is IPersistentList)
            {
                Expression expr = GenerateListAsObjectArray(value);
                ret = Expression.Call(
                    null,
                    Compiler.Method_PersistentList_create,
                    expr);
            }
            else if (value is Regex)
            {
                ret = Expression.New(
                    Compiler.Ctor_Regex_1,
                    Expression.Constant(((Regex)value).ToString()));
            }
            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));
                }

                ret     = Expression.Call(Compiler.Method_RT_readString, Expression.Constant(cs));
                partial = false;
            }

            if (partial)
            {
                if (value is IObj && RT.count(((IObj)value).meta()) > 0)
                {
                    Expression objExpr  = Expression.Convert(ret, typeof(IObj));
                    Expression metaExpr = Expression.Convert(GenerateValue(((IObj)value).meta()), typeof(IPersistentMap));
                    ret = Expression.Call(
                        objExpr,
                        Compiler.Method_IObj_withMeta,
                        metaExpr);
                }
            }
            return(ret);
        }
Ejemplo n.º 17
0
        protected void EmitValue(object value, CljILGen ilg)
        {
            bool partial = true;

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

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

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

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

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

            if (partial)
            {
                if (value is IObj && RT.count(((IObj)value).meta()) > 0)
                {
                    ilg.Emit(OpCodes.Castclass, typeof(IObj));
                    Object m = ((IObj)value).meta();
                    EmitValue(Compiler.ElideMeta(m), ilg);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                    ilg.Emit(OpCodes.Callvirt, Compiler.Method_IObj_withMeta);
                }
            }
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Gets the number of items in the collection.
 /// </summary>
 /// <returns>The number of items in the collection.</returns>
 public override int count()
 {
     return(RT.count(_f) + RT.count(_rseq));
 }