Exemplo n.º 1
0
        /// <summary>
        /// Intern a symbol with a specified value.
        /// </summary>
        /// <param name="sym">The symbol to intern.</param>
        /// <param name="val">The value to associate with the symbol.</param>
        /// <returns>The value that is associated. (only guaranteed == to the value given).</returns>
        object reference(Symbol sym, object val)
        {
            if (sym.Namespace != null)
            {
                throw new ArgumentException("Can't intern a namespace-qualified symbol");
            }

            IPersistentMap map = Mappings;
            object         o;

            // race condition
            while ((o = map.valAt(sym)) == null)
            {
                IPersistentMap newMap = map.assoc(sym, val);
                _mappings.CompareAndSet(map, newMap);
                map = Mappings;
            }

            if (o == val)
            {
                return(o);
            }

            WarnOrFailOnReplace(sym, o, val);

            while (!_mappings.CompareAndSet(map, map.assoc(sym, val)))
            {
                map = Mappings;
            }

            return(val);
        }
        public ClojureRecordedMapModel(IEnumerable <KeyValuePair <TKeyType, TValueType> > keyValuePairs)
            : this()
        {
            Contract.Requires <ArgumentNullException>(keyValuePairs != null);

            foreach (var e in keyValuePairs)
            {
                Map = Map.assoc(e.Key, e.Value);
            }
        }
Exemplo n.º 3
0
    object DrawDynamicWidget(object key, object val)
    {
        if (val is IPersistentMap)
        {
            IPersistentMap map = val as IPersistentMap;

            EditorGUILayout.LabelField(key.ToString(), "{");
            EditorGUI.indentLevel++;
            foreach (var entry in map)
            {
                object oldKey = entry.key();
                GUILayout.BeginHorizontal();
                object newKey = LoadString(EditorGUILayout.TextField(PrStr(entry.key())));
                object newVal = LoadString(EditorGUILayout.TextField(PrStr(entry.val())));
                map = map.without(oldKey);

                if (!GUILayout.Button("X", EditorStyles.miniButton))
                {
                    map = map.assoc(newKey, newVal);
                }

                GUILayout.EndHorizontal();
            }
            if (GUILayout.Button("+", EditorStyles.miniButton))
            {
                map = map.assoc("", "");
            }

            EditorGUI.indentLevel--;
            return(map);
        }
        else if (val is IPersistentVector)
        {
            IPersistentVector vector = val as IPersistentVector;
            EditorGUILayout.LabelField(key.ToString(), "[");
            EditorGUI.indentLevel++;
            for (int i = 0; i < vector.count(); i++)
            {
                vector = vector.assocN(i, DrawDynamicWidget(i.ToString(), vector.nth(i)));
            }
            // EditorGUILayout.LabelField("", "]");
            EditorGUI.indentLevel--;
            return(vector);
        }
        else
        {
            return(RT.var("clojure.core", "read-string").invoke(EditorGUILayout.TextField(key.ToString(), (string)RT.var("clojure.core", "pr-str").invoke(val))));
        }
    }
Exemplo n.º 4
0
        /// <summary>
        /// Intern a <see cref="Symbol">Symbol</see> in the namespace, with a (new) <see cref="Var">Var</see> as its value.
        /// </summary>
        /// <param name="sym">The symbol to intern.</param>
        /// <returns>The <see cref="Var">Var</see> associated with the symbol.</returns>
        /// <remarks>
        /// <para>It is an error to intern a symbol with a namespace.</para>
        /// <para>This has to deal with other threads also interning.</para>
        /// </remarks>
        public Var intern(Symbol sym)
        {
            if (sym.Namespace != null)
            {
                throw new ArgumentException("Can't intern a namespace-qualified symbol");
            }

            IPersistentMap map = Mappings;
            object         o;
            Var            v = null;

            // race condition
            while ((o = map.valAt(sym)) == null)
            {
                if (v == null)
                {
                    v = new Var(this, sym);
                }
                IPersistentMap newMap = map.assoc(sym, v);
                _mappings.CompareAndSet(map, newMap);
                map = Mappings;
            }
            if ((o is Var) && ((Var)o).Namespace == this)
            {
                return((Var)o);
            }

            // race condition
            throw new InvalidOperationException(String.Format("{0} already refers to: {1} in namespace: {2}", sym, o, _name));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Intern a symbol with a specified value.
        /// </summary>
        /// <param name="sym">The symbol to intern.</param>
        /// <param name="val">The value to associate with the symbol.</param>
        /// <returns>The value that is associated. (only guaranteed == to the value given).</returns>
        object reference(Symbol sym, object val)
        {
            if (sym.Namespace != null)
            {
                throw new ArgumentException("Can't intern a namespace-qualified symbol");
            }

            IPersistentMap map = Mappings;
            object         o;

            // race condition
            while ((o = map.valAt(sym)) == null)
            {
                IPersistentMap newMap = map.assoc(sym, val);
                _mappings.CompareAndSet(map, newMap);
                map = Mappings;
            }

            if (o == val)
            {
                return(o);
            }

            throw new InvalidOperationException(String.Format("{0} already refers to: {1} in namespace: {2}", sym, o, _name));
        }
Exemplo n.º 6
0
        public static PersistentStructMap create(Def def, ISeq keyvals)
        {
            object[]       vals = new object[def.Keyslots.count()];
            IPersistentMap ext  = PersistentHashMap.EMPTY;

            for (; keyvals != null; keyvals = keyvals.next().next())
            {
                if (keyvals.next() == null)
                {
                    throw new ArgumentException(String.Format("No value supplied for key: {0}", keyvals.first()));
                }
                object    k  = keyvals.first();
                object    v  = RT.second(keyvals);
                IMapEntry me = def.Keyslots.entryAt(k);
                if (me != null)
                {
                    vals[Util.ConvertToInt(me.val())] = v;
                }
                else
                {
                    ext = ext.assoc(k, v);
                }
            }
            return(new PersistentStructMap(null, def, vals, ext));
        }
Exemplo n.º 7
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                // frm is: (deftype* tagname classname [fields] :implements [interfaces] :tag tagname methods*)

                ISeq rform = (ISeq)frm;

                rform = RT.next(rform);

                string tagname = ((Symbol)rform.first()).ToString();

                rform = rform.next();
                Symbol classname = (Symbol)rform.first();

                rform = rform.next();
                IPersistentVector fields = (IPersistentVector)rform.first();

                rform = rform.next();
                IPersistentMap opts = PersistentHashMap.EMPTY;

                while (rform != null && rform.first() is Keyword)
                {
                    opts  = opts.assoc(rform.first(), RT.second(rform));
                    rform = rform.next().next();
                }

                ObjExpr ret = Build((IPersistentVector)RT.get(opts, Compiler.ImplementsKeyword, PersistentVector.EMPTY), fields, null, tagname, classname,
                                    (Symbol)RT.get(opts, RT.TagKey), rform, frm);

                return(ret);
            }
Exemplo n.º 8
0
        public void addAlias(Symbol alias, Namespace ns)
        {
            if (alias == null)
            {
                throw new ArgumentNullException("alias", "Expecting Symbol + Namespace");
            }
            if (ns == null)
            {
                throw new ArgumentNullException("ns", "Expecting Symbol + Namespace");
            }

            IPersistentMap map = Aliases;

            // race condition
            while (!map.containsKey(alias))
            {
                IPersistentMap newMap = map.assoc(alias, ns);
                _aliases.CompareAndSet(map, newMap);
                map = Aliases;
            }
            // you can rebind an alias, but only to the initially-aliased namespace
            if (!map.valAt(alias).Equals(ns))
            {
                throw new InvalidOperationException(String.Format("Alias {0} already exists in namespace {1}, aliasing {2}",
                                                                  alias, _name, map.valAt(alias)));
            }
        }
Exemplo n.º 9
0
        public Var intern(Symbol sym)
        {
            if (sym.Namespace != null)
            {
                throw new ArgumentException("Can't intern a namespace-qualified symbol");
            }

            IPersistentMap map = Mappings;
            object         o;
            Var            v = null;

            // race condition
            while ((o = map.valAt(sym)) == null)
            {
                if (v == null)
                {
                    v = new Var(this, sym);
                }
                IPersistentMap newMap = map.assoc(sym, v);
                _mappings.CompareAndSet(map, newMap);
                map = Mappings;
            }

            Var ovar = o as Var;

            if (ovar != null && ovar.Namespace == this)
            {
                return(ovar);
            }

            if (v == null)
            {
                v = new Var(this, sym);
            }

            WarnOrFailOnReplace(sym, o, v);

            while (!_mappings.CompareAndSet(map, map.assoc(sym, v)))
            {
                map = Mappings;
            }

            return(v);
        }
Exemplo n.º 10
0
        public static IPersistentMap create(IDictionary other)
        {
            IPersistentMap ret = EMPTY;

            foreach (DictionaryEntry e in other)
            {
                ret = ret.assoc(e.Key, e.Value);
            }
            return(ret);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Create a <see cref="PersistentHashMap">PersistentHashMap</see> initialized from an array of alternating keys and values.
        /// </summary>
        /// <param name="init">An array of alternating keys and values.</param>
        /// <returns>A <see cref="PersistentHashMap">PersistentHashMap</see>.</returns>
        public static PersistentHashMap create(params object[] init)
        {
            IPersistentMap ret = EMPTY;

            for (int i = 0; i < init.Length; i += 2)
            {
                ret = ret.assoc(init[i], init[i + 1]);
            }
            return((PersistentHashMap)ret);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Create a <see cref="PersistentHashMap">PersistentHashMap</see> with given metadata initialized from an array of alternating keys and values.
        /// </summary>
        /// <param name="meta">The metadata to attach.</param>
        /// <param name="init">An array of alternating keys and values.</param>
        /// <returns>A <see cref="PersistentHashMap">PersistentHashMap</see>.</returns>
        public static PersistentHashMap create(IPersistentMap meta, params object[] init)
        {
            IPersistentMap ret = (IPersistentMap)EMPTY.withMeta(meta);

            for (int i = 0; i < init.Length; i += 2)
            {
                ret = ret.assoc(init[i], init[i + 1]);
            }
            return((PersistentHashMap)ret);
        }
Exemplo n.º 13
0
        private static Type RegisterBaseClass(Type superType, Type baseType)
        {
            IPersistentMap map = _baseClassMapRef.Get();

            while (!map.containsKey(superType))
            {
                IPersistentMap newMap = map.assoc(superType, baseType);
                _baseClassMapRef.CompareAndSet(map, newMap);
                map = _baseClassMapRef.Get();
            }

            return(LookupBaseClass(superType));  // may not be the one we defined -- race condition
        }
Exemplo n.º 14
0
        public static PersistentTreeMap create(ISeq items)
        {
            IPersistentMap ret = EMPTY;

            for (; items != null; items = items.next().next())
            {
                if (items.next() == null)
                {
                    throw new ArgumentException(string.Format("No value supplied for key: {0}", items.first()));
                }
                ret = ret.assoc(items.first(), items.next().first());
            }
            return((PersistentTreeMap)ret);
        }
Exemplo n.º 15
0
        public static Associative getThreadBindings()
        {
            Frame          f   = CurrentFrame;
            IPersistentMap ret = PersistentHashMap.EMPTY;

            for (ISeq bs = f.Bindings.seq(); bs != null; bs = bs.next())
            {
                IMapEntry e = (IMapEntry)bs.first();
                Var       v = (Var)e.key();
                TBox      b = (TBox)e.val();
                ret = ret.assoc(v, b.Val);
            }
            return(ret);
        }
Exemplo n.º 16
0
        public void AssocAddsOnNewKey()
        {
            Dictionary <int, string> d = new Dictionary <int, string>();

            d[1] = "a";
            d[2] = "b";

            IPersistentMap m1 = PersistentArrayMap.create(d);
            IPersistentMap m2 = m1.assoc(3, "c");

            Expect(m1.count(), EqualTo(2));
            Expect(m1.containsKey(3), False);
            Expect(m2.count(), EqualTo(3));
            Expect(m2.valAt(3), EqualTo("c"));
        }
Exemplo n.º 17
0
        public void AssocModifiesOnExistingKey()
        {
            Dictionary <int, string> d = new Dictionary <int, string>();

            d[1] = "a";
            d[2] = "b";

            IPersistentMap m1 = PersistentArrayMap.create(d);
            IPersistentMap m2 = m1.assoc(2, "c");

            Expect(m1.count(), EqualTo(2));
            Expect(m1.valAt(2), EqualTo("b"));
            Expect(m2.count(), EqualTo(2));
            Expect(m2.valAt(2), EqualTo("c"));
        }
Exemplo n.º 18
0
        /// <summary>
        /// Creates a struct definition.
        /// </summary>
        /// <param name="keys">The set of fixed keys.</param>
        /// <returns>A struct definition.</returns>
        public static Def createSlotMap(ISeq keys)
        {
            if (keys == null)
            {
                throw new ArgumentException("Must supply keys");
            }
            IPersistentMap map = PersistentHashMap.EMPTY;
            int            i   = 0;

            for (ISeq s = keys; s != null; s = s.next(), i++)
            {
                map = map.assoc(s.first(), i);
            }
            return(new Def(keys, map));
        }
Exemplo n.º 19
0
        /// <summary>
        /// Create a <see cref="PersistentHashMap">PersistentHashMap</see> initialized from an IList of alternating keys and values.
        /// </summary>
        /// <param name="init">An IList of alternating keys and values.</param>
        /// <returns>A <see cref="PersistentHashMap">PersistentHashMap</see>.</returns>
        public static PersistentHashMap create1(IList init)
        {
            IPersistentMap ret = EMPTY;

            for (IEnumerator i = init.GetEnumerator(); i.MoveNext();)
            {
                object key = i.Current;
                if (!i.MoveNext())
                {
                    throw new ArgumentException(String.Format("No value supplied for key: {0}", key));
                }
                object val = i.Current;
                ret = ret.assoc(key, val);
            }
            return((PersistentHashMap)ret);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Add a new key/value pair.
        /// </summary>
        /// <param name="o">The key/value pair to add.</param>
        /// <returns>A new map with key+value pair added.</returns>
        public IPersistentMap cons(object o)
        {
            IMapEntry e = o as IMapEntry;

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

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

            if (o != null)
            {
                Type t = o.GetType();
                if (t.IsGenericType && t.Name == "KeyValuePair`2")
                {
                    object key = t.InvokeMember("Key", BindingFlags.GetProperty, null, o, null);
                    object val = t.InvokeMember("Value", BindingFlags.GetProperty, null, o, null);
                    return(assoc(key, val));
                }
            }

            IPersistentVector v = o as IPersistentVector;

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

            IPersistentMap ret = this;

            for (ISeq s = RT.seq(o); s != null; s = s.next())
            {
                IMapEntry me = (IMapEntry)s.first();
                ret = ret.assoc(me.key(), me.val());
            }
            return(ret);
        }
Exemplo n.º 21
0
        Type ReferenceClass(Symbol sym, Type val)
        {
            if (sym.Namespace != null)
            {
                throw new ArgumentException("Can't intern namespace-qualified symbol");
            }
            IPersistentMap map = getMappings();
            Type           c   = (Type)map.valAt(sym);

            while ((c == null) || (AreDifferentInstancesOfSameClassName(c, val)))
            {
                IPersistentMap newMap = map.assoc(sym, val);
                _mappings.CompareAndSet(map, newMap);
                map = getMappings();
                c   = (Type)map.valAt(sym);
            }
            if (c == val)
            {
                return(c);
            }

            throw new InvalidOperationException(sym + " already refers to: " + c + " in namespace: " + Name);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Get the method for a dispatch value and cache it.
        /// </summary>
        /// <param name="dispatchVal">The disaptch value.</param>
        /// <returns>The mest method.</returns>
        private IFn FindAndCacheBestMethod(object dispatchVal)
        {
            IMapEntry bestEntry = null;

            foreach (IMapEntry me in MethodTable)
            {
                if (IsA(dispatchVal, me.key()))
                {
                    if (bestEntry == null || Dominates(me.key(), bestEntry.key()))
                    {
                        bestEntry = me;
                    }
                    if (!Dominates(bestEntry.key(), me.key()))
                    {
                        throw new ArgumentException(String.Format("Multiple methods in multimethod {0} match dispatch value: {1} -> {2} and {3}, and neither is preferred",
                                                                  _name, dispatchVal, me.key(), bestEntry.key()));
                    }
                }
            }
            if (bestEntry == null)
            {
                return(null);
            }

            // ensure basis has stayed stable throughout, else redo
            if (_cachedHierarchy == _hierarchy.deref())
            {
                // place in cache
                _methodCache = _methodCache.assoc(dispatchVal, bestEntry.val());
                return((IFn)bestEntry.val());
            }
            else
            {
                ResetCache();
                return(FindAndCacheBestMethod(dispatchVal));
            }
        }
Exemplo n.º 23
0
        internal static ObjExpr Build(
            IPersistentVector interfaceSyms,
            IPersistentVector fieldSyms,
            Symbol thisSym,
            string tagName,
            Symbol className,
            Symbol typeTag,
            ISeq methodForms,
            Object frm)
        {
            NewInstanceExpr ret = new NewInstanceExpr(null);

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

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

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

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

            IPersistentVector interfaces = PersistentVector.EMPTY;

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

            Dictionary <IPersistentVector, List <MethodInfo> > overrideables;

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

            ret._methodMap = overrideables;

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

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

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

            //genC.FnCompileMode = FnMode.Full;

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

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

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

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

            return(ret);
        }
Exemplo n.º 24
0
            public Expr Parse(object frm)
            {
                ISeq form = (ISeq)frm;

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

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

                IPersistentVector bindings = RT.second(form) as IPersistentVector;

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

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

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

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

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

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

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

                try
                {
                    Var.pushThreadBindings(dynamicBindings);

                    IPersistentVector bindingInits = PersistentVector.EMPTY;
                    IPersistentVector loopLocals   = PersistentVector.EMPTY;

                    for (int i = 0; i < bindings.count(); i += 2)
                    {
                        if (!(bindings.nth(i) is Symbol))
                        {
                            throw new ArgumentException("Bad binding form, expected symbol, got " + bindings.nth(i));
                        }

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

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

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

                    return(new LetExpr(bindingInits,
                                       new BodyExpr.Parser().Parse(body),
                                       isLoop));
                }
                finally
                {
                    Var.popThreadBindings();
                }
            }
Exemplo n.º 25
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                ISeq form = (ISeq)frm;

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

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

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

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

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

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

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

                IPersistentVector recurMismatches = PersistentVector.EMPTY;

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

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

                    if (isLoop)
                    {
                        dynamicBindings = dynamicBindings.assoc(Compiler.LoopLocalsVar, null);
                    }

                    try
                    {
                        Var.pushThreadBindings(dynamicBindings);

                        IPersistentVector bindingInits = PersistentVector.EMPTY;
                        IPersistentVector loopLocals   = PersistentVector.EMPTY;

                        for (int i = 0; i < bindings.count(); i += 2)
                        {
                            if (!(bindings.nth(i) is Symbol))
                            {
                                throw new ParseException("Bad binding form, expected symbol, got " + bindings.nth(i));
                            }

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

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

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

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

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

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

                        if (!moreMismatches)
                        {
                            return(new LetExpr(bindingInits, bodyExpr, isLoop));
                        }
                    }
                    finally
                    {
                        Var.popThreadBindings();
                    }
                }
            }
Exemplo n.º 26
0
            static object syntaxQuote(object form)
            {
                object ret;

                if (Compiler.isSpecial(form))
                {
                    ret = RT.list(Compiler.QUOTE, form);
                }
                else if (form is Symbol)
                {
                    Symbol sym = (Symbol)form;
                    if (sym.Namespace == null && sym.Name.EndsWith("#"))
                    {
                        IPersistentMap gmap = (IPersistentMap)GENSYM_ENV.deref();
                        if (gmap == null)
                        {
                            throw new InvalidDataException("Gensym literal not in syntax-quote");
                        }
                        Symbol gs = (Symbol)gmap.valAt(sym);
                        if (gs == null)
                        {
                            GENSYM_ENV.set(gmap.assoc(sym, gs = Symbol.intern(null,
                                                                              sym.Name.Substring(0, sym.Name.Length - 1)
                                                                              + "__" + RT.nextID() + "__auto__")));
                        }
                        sym = gs;
                    }
                    else if (sym.Namespace == null && sym.Name.EndsWith("."))
                    {
                        Symbol csym = Symbol.intern(null, sym.Name.Substring(0, sym.Name.Length - 1));
                        csym = Compiler.resolveSymbol(csym);
                        sym  = Symbol.intern(null, csym.Name + ".");
                    }
                    else if (sym.Namespace == null && sym.Name.StartsWith("."))
                    {
                        // simply quote method names
                    }
                    else
                    {
                        sym = Compiler.resolveSymbol(sym);
                    }
                    ret = RT.list(Compiler.QUOTE, sym);
                }
                //else if (form is Unquote)
                //    return ((Unquote)form).Obj;
                // Rev 1184
                else if (isUnquote(form))
                {
                    return(RT.second(form));
                }
                else if (isUnquoteSplicing(form))
                {
                    throw new ArgumentException("splice not in list");
                }
                else if (form is IPersistentCollection)
                {
                    if (form is IPersistentMap)
                    {
                        IPersistentVector keyvals = flattenMap(form);
                        ret = RT.list(APPLY, HASHMAP, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(keyvals.seq()))));
                    }
                    else if (form is IPersistentVector)
                    {
                        ret = RT.list(APPLY, VECTOR, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(((IPersistentVector)form).seq()))));
                    }
                    else if (form is IPersistentSet)
                    {
                        ret = RT.list(APPLY, HASHSET, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(((IPersistentSet)form).seq()))));
                    }
                    else if (form is ISeq || form is IPersistentList)
                    {
                        ISeq seq = RT.seq(form);
                        if (seq == null)
                        {
                            ret = RT.cons(LIST, null);
                        }
                        else
                        {
                            ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Unknown Collection type");
                    }
                }
                else if (form is Keyword ||
                         Util.IsNumeric(form) ||
                         form is Char ||
                         form is String)
                {
                    ret = form;
                }
                else
                {
                    ret = RT.list(Compiler.QUOTE, form);
                }

                if (form is IObj && RT.meta(form) != null)
                {
                    //filter line numbers
                    IPersistentMap newMeta = ((IObj)form).meta().without(RT.LINE_KEY);
                    if (newMeta.count() > 0)
                    {
                        return(RT.list(WITH_META, ret, syntaxQuote(((IObj)form).meta())));
                    }
                }
                return(ret);
            }
Exemplo n.º 27
0
 public void setMeta(IPersistentMap m)
 {
     // ensure these basis keys
     resetMeta(m.assoc(_nameKey, _sym).assoc(_nsKey, _ns));
 }
Exemplo n.º 28
0
 public IRef addWatch(object key, IFn callback)
 {
     _watches = _watches.assoc(key, callback);
     return(this);
 }
Exemplo n.º 29
0
        /// <summary>
        /// Get the method for a dispatch value and cache it.
        /// </summary>
        /// <param name="dispatchVal">The disaptch value.</param>
        /// <returns>The mest method.</returns>
        private IFn FindAndCacheBestMethod(object dispatchVal)
        {
            _rw.EnterWriteLock();
            object         bestValue;
            IPersistentMap mt = _methodTable;
            IPersistentMap pt = _preferTable;
            object         ch = _cachedHierarchy;

            try
            {
                IMapEntry bestEntry = null;

                foreach (IMapEntry me in MethodTable)
                {
                    if (IsA(dispatchVal, me.key()))
                    {
                        if (bestEntry == null || Dominates(me.key(), bestEntry.key()))
                        {
                            bestEntry = me;
                        }
                        if (!Dominates(bestEntry.key(), me.key()))
                        {
                            throw new ArgumentException(String.Format("Multiple methods in multimethod {0} match dispatch value: {1} -> {2} and {3}, and neither is preferred",
                                                                      _name, dispatchVal, me.key(), bestEntry.key()));
                        }
                    }
                }
                if (bestEntry == null)
                {
                    bestValue = _methodTable.valAt(_defaultDispatchVal);
                    if (bestValue == null)
                    {
                        return(null);
                    }
                }
                else
                {
                    bestValue = bestEntry.val();
                }
            }
            finally
            {
                _rw.ExitWriteLock();
            }

            // ensure basis has stayed stable throughout, else redo
            _rw.EnterWriteLock();
            try
            {
                if (mt == _methodTable &&
                    pt == _preferTable &&
                    ch == _cachedHierarchy &&
                    _cachedHierarchy == _hierarchy.deref())
                {
                    // place in cache
                    _methodCache = _methodCache.assoc(dispatchVal, bestValue);
                    return((IFn)bestValue);
                }
                else
                {
                    ResetCache();
                    return(FindAndCacheBestMethod(dispatchVal));
                }
            }
            finally
            {
                _rw.ExitWriteLock();
            }
        }
Exemplo n.º 30
0
 public void setMeta(IPersistentMap m)
 {
     // ensure these basis keys
     resetMeta(m.assoc(_nameKey, _sym).assoc(_nsKey, _ns));
 }
Exemplo n.º 31
0
            public override object invoke(object reader, object colon, object opts)
            {
                PushbackTextReader r = reader as PushbackTextReader;

                // Read ns symbol
                object osym = read(r, true, null, false, opts);
                Symbol sym  = osym as Symbol;

                if (sym == null || sym.Namespace != null)
                {
                    throw new Exception("Namespaced map must specify a valid namespace: " + osym);
                }
                string ns = sym.Name;

                // Read map
                int nextChar = r.Read();

                while (isWhitespace(nextChar))
                {
                    nextChar = r.Read();
                }
                if ('{' != nextChar)
                {
                    throw new Exception("Namespaced map must specify a map");
                }
                List <object> kvs = ReadDelimitedList('}', r, true, opts);

                if ((kvs.Count & 1) == 1)
                {
                    throw new Exception("Namespaced map literal must contain an even number of forms");
                }

                // Construct output map
                IPersistentMap m = RT.map();

                using (var iterator = kvs.GetEnumerator())
                {
                    while (iterator.MoveNext())
                    {
                        var key = iterator.Current;
                        iterator.MoveNext();
                        var val = iterator.Current;

                        Keyword kw = key as Keyword;
                        if (kw != null)
                        {
                            if (kw.Namespace == null)
                            {
                                m = m.assoc(Keyword.intern(ns, kw.Name), val);
                            }
                            else if (kw.Namespace.Equals("_"))
                            {
                                m = m.assoc(Keyword.intern(null, kw.Name), val);
                            }
                            else
                            {
                                m = m.assoc(kw, val);
                            }
                        }
                        else
                        {
                            Symbol s = key as Symbol;
                            if (s != null)
                            {
                                if (s.Namespace == null)
                                {
                                    m = m.assoc(Symbol.intern(ns, s.Name), val);
                                }
                                else if (s.Namespace.Equals("_"))
                                {
                                    m = m.assoc(Symbol.intern(null, s.Name), val);
                                }
                                else
                                {
                                    m = m.assoc(s, val);
                                }
                            }
                            else
                            {
                                m = m.assoc(key, val);
                            }
                        }
                    }
                }
                return(m);
            }