/// <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); } }
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)))); } }
/// <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)); }
/// <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)); }
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)); }
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); }
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))); } }
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); }
public static IPersistentMap create(IDictionary other) { IPersistentMap ret = EMPTY; foreach (DictionaryEntry e in other) { ret = ret.assoc(e.Key, e.Value); } return(ret); }
/// <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); }
/// <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); }
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 }
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); }
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); }
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")); }
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")); }
/// <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)); }
/// <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); }
/// <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); }
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); }
/// <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)); } }
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); }
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(); } }
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(); } } }
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); }
public void setMeta(IPersistentMap m) { // ensure these basis keys resetMeta(m.assoc(_nameKey, _sym).assoc(_nsKey, _ns)); }
public IRef addWatch(object key, IFn callback) { _watches = _watches.assoc(key, callback); return(this); }
/// <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(); } }
public void setMeta(IPersistentMap m) { // ensure these basis keys resetMeta(m.assoc(_nameKey, _sym).assoc(_nsKey, _ns)); }
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); }