Пример #1
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;
        }
Пример #2
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keyvals = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr k = Compiler.Analyze(pconToUse, e.key());
                Expr v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (!(k is LiteralExpr && v is LiteralExpr))
                    constant = false;
            }
            Expr ret = new MapExpr(keyvals);

            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                // This 'optimzation' works, mostly, unless you have nested map values.
                // The nested map values do not participate in the constants map, so you end up with the code to create the keys.
                // Result: huge duplication of keyword creation.  3X increase in init time to the REPL.
                //IPersistentMap m = PersistentHashMap.EMPTY;
                //for (int i = 0; i < keyvals.length(); i += 2)
                //    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                //return new ConstantExpr(m);
                return ret;
            }
            else
                return ret;
        }
Пример #3
0
        public static Expr Parse(ParserContext pcon, IPersistentSet form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keys = PersistentVector.EMPTY;
            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                object e = s.first();
                Expr expr = Compiler.Analyze(pconToUse, e);
                keys = (IPersistentVector)keys.cons(expr);
                if (!(expr is LiteralExpr))
                    constant = false;
            }
            Expr ret = new SetExpr(keys);
            if (form is IObj && ((IObj)form).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;
        }
Пример #4
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keyvals = PersistentVector.EMPTY;
            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr k = Compiler.Analyze(pconToUse, e.key());
                Expr v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (!(k is LiteralExpr && v is LiteralExpr))
                    constant = false;
            }
            Expr ret = new MapExpr(keyvals);
            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                IPersistentMap m = PersistentHashMap.EMPTY;
                for (int i = 0; i < keyvals.length(); i += 2)
                    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                return new ConstantExpr(m);
            }
            else
                return ret;
        }
Пример #5
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

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

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

            fn.ComputeNames(form, name);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            if (fn.SupportsMeta)
                return new MetaExpr(fn, MapExpr.Parse(pcon.EvEx(),fmeta));
            else
                return fn;
        }
Пример #6
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // form is one of:
                //  (. x fieldname-sym)
                //  (. x 0-ary-method)
                //  (. x propertyname-sym)
                //  (. x methodname-sym args)+
                //  (. x (methodname-sym args?))
                //  (. x (generic-m

                if (RT.Length(form) < 3)
                    throw new ArgumentException("Malformed member expression, expecting (. target member ... )");

                string source = (string)Compiler.SOURCE.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SOURCE_SPAN.deref();  // Compiler.GetSourceSpanMap(form);

                Symbol tag = Compiler.TagOf(form);

                // determine static or instance
                // static target must be symbol, either fully.qualified.Typename or Typename that has been imported

                Type t = HostExpr.MaybeType(RT.second(form), false);
                // at this point, t will be non-null if static

                Expr instance = null;
                if (t == null)
                    instance = Compiler.Analyze(pcon.EvEx(),RT.second(form));

                bool isZeroArityCall = RT.Length(form) == 3 && (RT.third(form) is Symbol || RT.third(form) is Keyword);

                if (isZeroArityCall)
                {
                    PropertyInfo pinfo = null;
                    FieldInfo finfo = null;
                    MethodInfo minfo = null;

                    Symbol sym = (RT.third(form) is Keyword) ? ((Keyword)RT.third(form)).Symbol : (Symbol)RT.third(form);
                    string fieldName = Compiler.munge(sym.Name);
                    // The JVM version does not have to worry about Properties.  It captures 0-arity methods under fields.
                    // We have to put in special checks here for this.
                    // Also, when reflection is required, we have to capture 0-arity methods under the calls that
                    //   are generated by StaticFieldExpr and InstanceFieldExpr.
                    if (t != null)
                    {
                        if ((finfo = Reflector.GetField(t, fieldName, true)) != null)
                            return new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo);
                        if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null)
                            return new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo);
                        if ((minfo = Reflector.GetArityZeroMethod(t, fieldName, true)) != null)
                            return new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List<HostArg>());
                        throw new MissingMemberException(t.Name, fieldName);
                    }
                    else if (instance != null && instance.HasClrType && instance.ClrType != null)
                    {
                        Type instanceType = instance.ClrType;
                        if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null)
                            return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo);
                        if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null)
                            return new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo);
                        if ((minfo = Reflector.GetArityZeroMethod(instanceType, fieldName, false)) != null)
                            return new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List<HostArg>());
                        if (pcon.IsAssignContext)
                            return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        else
                            return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);
                    }
                    else
                    {
                        //  t is null, so we know this is not a static call
                        //  If instance is null, we are screwed anyway.
                        //  If instance is not null, then we don't have a type.
                        //  So we must be in an instance call to a property, field, or 0-arity method.
                        //  The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo
                        //     will generate code to do a runtime call to a Reflector method that will check all three.
                        //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);
                        if (pcon.IsAssignContext)
                            return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null
                        else
                            return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName);

                    }
                }

                //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                ISeq call;
                List<Type> typeArgs = null;

                   //object third = RT.third(form);

                //if (third is ISeq && RT.first(third) is Symbol && ((Symbol)RT.first(third)).Equals(GENERIC))
                //{
                //    // We have a generic method call
                //    // (. thing (generic methodname type1 ...) args...)
                //    typeArgs = ParseGenericMethodTypeArgs(RT.next(RT.next(third)));
                //    call = RT.listStar(RT.second(third), RT.next(RT.next(RT.next(form))));
                //}
                //else
                //    call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                object fourth = RT.fourth(form);
                if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TYPE_ARGS))
                 {
                    // We have a type args supplied for a generic method call
                    // (. thing methodname (type-args type1 ... ) args ...)
                    typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth));
                    call = RT.listStar(RT.third(form), RT.next(RT.next(RT.next(RT.next(form)))));
                }
                else
                    call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form));

                if (!(RT.first(call) is Symbol))
                    throw new ArgumentException("Malformed member exception");

                string methodName = Compiler.munge(((Symbol)RT.first(call)).Name);

                List<HostArg> args = ParseArgs(pcon, RT.next(call));

                return t != null
                    ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args))
                    : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args));
            }
Пример #7
0
        internal static List<HostArg> ParseArgs(ParserContext pcon, ISeq argSeq)
        {
            List<HostArg> args = new List<HostArg>();

            for (ISeq s = argSeq; s != null; s = s.next())
            {
                object arg = s.first();

                HostArg.ParameterType paramType = HostArg.ParameterType.Standard;
                LocalBinding lb = null;

                if (arg is ISeq)
                {
                    Symbol op = RT.first(arg) as Symbol;
                    if (op != null && op.Equals(BY_REF))
                    {
                        if (RT.Length((ISeq)arg) != 2)
                            throw new ArgumentException("Wrong number of arguments to {0}", ((Symbol)op).Name);

                        object localArg = RT.second(arg);
                        if (!(localArg is Symbol) || (lb = Compiler.ReferenceLocal((Symbol)localArg)) == null)
                            throw new ArgumentException("Argument to {0} must be a local variable.", ((Symbol)op).Name);

                        paramType = HostArg.ParameterType.ByRef;

                        arg = localArg;
                    }
                }

                Expr expr = Compiler.Analyze(pcon.EvEx(),arg);

                args.Add(new HostArg(paramType, expr, lb));
            }

            return args;
        }
            public Expr Parse(ParserContext pcon, object frm)
            {
                // frm is:  (reify this-name? [interfaces] (method-name [args] body)* )
                ISeq form = (ISeq)frm;
                ObjMethod enclosingMethod = (ObjMethod)Compiler.METHOD.deref();
                string baseName = enclosingMethod != null
                    ? (ObjExpr.TrimGenID(enclosingMethod.Objx.Name) + "$")
                    : (Compiler.munge(Compiler.CurrentNamespace.Name.Name) + "$");
                string simpleName = "reify__" + RT.nextID();
                string className = baseName + simpleName;

                ISeq rform = RT.next(form);

                IPersistentVector interfaces = ((IPersistentVector)RT.first(rform)).cons(Symbol.intern("clojure.lang.IObj"));

                rform = RT.next(rform);

                ObjExpr ret = Build(interfaces, null, null, className, Symbol.intern(className), null, rform,frm);
                if (frm is IObj && ((IObj)frm).meta() != null)
                    return new MetaExpr(ret, (MapExpr)MapExpr.Parse(pcon.EvEx(),((IObj)frm).meta()));
                else
                    return ret;
            }
Пример #9
0
            public Expr Parse(ParserContext pcon, 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("First 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)
                        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 Exception("Can't create defs outside of current namespace");
                }

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

                Object source_path = Compiler.SOURCE_PATH.deref();
                source_path = source_path ?? "NO_SOURCE_FILE";
                mm = (IPersistentMap)RT.assoc(mm,RT.LINE_KEY, Compiler.LINE.deref())
                    .assoc(RT.FILE_KEY, source_path)
                    .assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref());

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

                return new DefExpr(v, init, meta, initProvided);
            }
Пример #10
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvEx();

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

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

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

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

            IPersistentVector args = PersistentVector.EMPTY;
            for ( ISeq s = RT.seq(form.next()); s != null; s = s.next())
                args = args.cons(Compiler.Analyze(pcon,s.first()));
            return new InvokeExpr((string)Compiler.SOURCE.deref(),
                (IPersistentMap)Compiler.SOURCE_SPAN.deref(), //Compiler.GetSourceSpanMap(form),
                Compiler.TagOf(form),
                fexpr,
                args);
        }
Пример #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 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("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 Exception("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 Exception("Can't create defs outside of current namespace");
                }

                IPersistentMap mm = sym.meta();
                bool isDynamic = RT.booleanCast(RT.get(mm, Compiler.DYNAMIC_KEY));
                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.\n",
                                           sym);
                }

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

                Object source_path = Compiler.SOURCE_PATH.get();
                source_path = source_path ?? "NO_SOURCE_FILE";
                mm = (IPersistentMap)RT.assoc(mm,RT.LINE_KEY, Compiler.LINE.get())
                    .assoc(RT.FILE_KEY, source_path);
                    //.assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref());
                if (docstring != null)
                    mm = (IPersistentMap)RT.assoc(mm, RT.DOC_KEY, 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"));

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

                return new DefExpr(
                    (string)Compiler.SOURCE.deref(),
                    (int) Compiler.LINE.deref(),
                    v, init, meta, initProvided,isDynamic);
            }
Пример #12
0
        public static Expr Parse(ParserContext pcon, ISeq form)
        {
            pcon = pcon.EvEx();

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

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

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

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

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

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

            return new InvokeExpr((string)Compiler.SOURCE.deref(),
                (IPersistentMap)Compiler.SOURCE_SPAN.deref(), //Compiler.GetSourceSpanMap(form),
                Compiler.TagOf(form),
                fexpr,
                args);
        }
Пример #13
0
        internal static Expr OptionallyGenerateMetaInit(ParserContext pcon, object form, Expr expr)
        {
            Expr ret = expr;

            if ( RT.meta(form) != null )
                ret = new MetaExpr(ret, (MapExpr)MapExpr.Parse(pcon.EvEx(),((IObj)form).meta()));

            return ret;
        }
Пример #14
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

                // (if test then) or (if test then else)

                if (form.count() > 4)
                    throw new Exception("Too many arguments to if");

                if (form.count() < 3)
                    throw new Exception("Too few arguments to if");

                Expr testExpr = Compiler.Analyze(pcon.EvEx().SetAssign(false),RT.second(form));
                Expr thenExpr = Compiler.Analyze(pcon.SetAssign(false), RT.third(form));
                Expr elseExpr = Compiler.Analyze(pcon.SetAssign(false), RT.fourth(form));

                return new IfExpr((IPersistentMap)Compiler.SOURCE_SPAN.deref(), testExpr, thenExpr, elseExpr);
            }