/// <summary> /// Return a new vector with the i-th value set to <c>val</c>. /// </summary> /// <param name="i">The index of the item to set.</param> /// <param name="val">The new value</param> /// <returns>A new (immutable) vector v with v[i] == val.</returns> public override IPersistentVector assocN(int i, object val) { if (_start + i > _end) { throw new ArgumentOutOfRangeException("i"); } else if (_start + i == _end) { return(cons(val)); } else { return(new SubVector(_meta, _v.assocN(_start + i, val), _start, _end)); } }
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)))); } }
public void AssocnInRangeModifies() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); IPersistentVector v2 = v.assocN(1, 4); Expect(v.count(), EqualTo(3)); Expect(v.nth(0), EqualTo(1)); Expect(v.nth(1), EqualTo(2)); Expect(v.nth(2), EqualTo(3)); Expect(v2.count(), EqualTo(3)); Expect(v2.nth(0), EqualTo(1)); Expect(v2.nth(1), EqualTo(4)); Expect(v2.nth(2), EqualTo(3)); }
public void AssocnAtEndModifies() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); IPersistentVector v2 = v.assocN(3, 4); Expect(v.count()).To.Equal(3); Expect(v.nth(0)).To.Equal(1); Expect(v.nth(1)).To.Equal(2); Expect(v.nth(2)).To.Equal(3); Expect(v2.count()).To.Equal(4); Expect(v2.nth(0)).To.Equal(1); Expect(v2.nth(1)).To.Equal(2); Expect(v2.nth(2)).To.Equal(3); Expect(v2.nth(3)).To.Equal(4); }
public void AssocNChangesForBig() { Range r = new Range(2, 100000); PersistentVector v1 = PersistentVector.create((ISeq)r); IPersistentVector v2 = v1; for (int i = 0; i < 110000; i++) { v2 = v2.assocN(i, i + 20); } for (int i = 0; i < v1.count(); ++i) { Expect(v1.nth(i), EqualTo(i + 2)); } for (int i = 0; i < v2.count(); ++i) { Expect(v2.nth(i), EqualTo(i + 20)); } }
public void AssocNChangesForBig() { ISeq r = LongRange.create(2, 100000); PersistentVector v1 = PersistentVector.create(r); IPersistentVector v2 = v1; for (int i = 0; i < 110000; i++) { v2 = v2.assocN(i, i + 20L); } for (int i = 0; i < v1.count(); ++i) { Expect((long)v1.nth(i)).To.Equal(i + 2L); } for (int i = 0; i < v2.count(); ++i) { object o = v2.nth(i); Expect(o).To.Be.An.Instance.Of <long>(); Expect((long)o).To.Equal(i + 20L); } }
public void AssocNOutOfRangeHighFails() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); IPersistentVector v2 = v.assocN(4, 4); }
public void AssocNOutOfRangeLowFails() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); v.assocN(-4, 4); }
public static NewInstanceMethod Parse(ObjExpr objx, ISeq form, Symbol thisTag, Dictionary <IPersistentVector, IList <MethodInfo> > overrideables, Dictionary <IPersistentVector, IList <MethodInfo> > explicits) { // (methodname [this-name args*] body...) // this-name might be nil NewInstanceMethod method = new NewInstanceMethod(objx, (ObjMethod)Compiler.MethodVar.deref()); Symbol dotName = (Symbol)RT.first(form); Symbol name; string methodName; int idx = dotName.Name.LastIndexOf("."); if (idx >= 0) { // we have an explicit interface implementation string dotNameStr = dotName.Name; string interfaceName = dotNameStr.Substring(0, idx); method.ExplicitInterface = RT.classForName(interfaceName); if (method.ExplicitInterface == null) { throw new ParseException(String.Format("Unable to find interface {0} for explicit method implemntation: {1}", interfaceName, dotNameStr)); } methodName = dotNameStr.Substring(idx + 1); name = (Symbol)Symbol.intern(null, Compiler.munge(dotName.Name)).withMeta(RT.meta(dotName)); } else { name = (Symbol)Symbol.intern(null, Compiler.munge(dotName.Name)).withMeta(RT.meta(dotName)); methodName = name.Name; } IPersistentVector parms = (IPersistentVector)RT.second(form); if (parms.count() == 0 || !(parms.nth(0) is Symbol)) { throw new ParseException("Must supply at least one argument for 'this' in: " + dotName); } Symbol thisName = (Symbol)parms.nth(0); parms = RT.subvec(parms, 1, parms.count()); ISeq body = RT.next(RT.next(form)); try { method.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); // register as the current method and set up a new env frame // PathNode pnade = new PathNode(PATHTYPE.PATH, (PathNode) CLEAR_PATH.get()); Var.pushThreadBindings( RT.mapUniqueKeys( Compiler.MethodVar, method, Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(), Compiler.LoopLocalsVar, null, Compiler.NextLocalNumVar, 0 // CLEAR_PATH, pnode, // CLEAR_ROOT, pnode, // CLEAR_SITES, PersistentHashMap.EMPTY )); // register 'this' as local 0 //method._thisBinding = Compiler.RegisterLocalThis(((thisName == null) ? dummyThis : thisName), thisTag, null); Compiler.RegisterLocalThis(((thisName == null) ? dummyThis : thisName), thisTag, null); IPersistentVector argLocals = PersistentVector.EMPTY; method._retType = Compiler.TagType(Compiler.TagOf(name)); method._argTypes = new Type[parms.count()]; bool hinted = Compiler.TagOf(name) != null; Type[] pTypes = new Type[parms.count()]; Symbol[] pSyms = new Symbol[parms.count()]; bool[] pRefs = new bool[parms.count()]; for (int i = 0; i < parms.count(); i++) { // Param should be symbol or (by-ref symbol) Symbol p; bool isByRef = false; object pobj = parms.nth(i); if (pobj is Symbol) { p = (Symbol)pobj; } else if (pobj is ISeq) { ISeq pseq = (ISeq)pobj; object first = RT.first(pseq); object second = RT.second(pseq); if (!(first is Symbol && ((Symbol)first).Equals(HostExpr.ByRefSym))) { throw new ParseException("First element in parameter pair must be by-ref"); } if (!(second is Symbol)) { throw new ParseException("Params must be Symbols"); } isByRef = true; p = (Symbol)second; hinted = true; } else { throw new ParseException("Params must be Symbols or of the form (by-ref Symbol)"); } object tag = Compiler.TagOf(p); if (tag != null) { hinted = true; } if (p.Namespace != null) { p = Symbol.intern(p.Name); } Type pType = Compiler.TagType(tag); if (isByRef) { pType = pType.MakeByRefType(); } pTypes[i] = pType; pSyms[i] = p; pRefs[i] = isByRef; } Dictionary <IPersistentVector, IList <MethodInfo> > matches = method.IsExplicit ? FindMethodsWithNameAndArity(method.ExplicitInterface, methodName, parms.count(), overrideables, explicits) : FindMethodsWithNameAndArity(methodName, parms.count(), overrideables); IPersistentVector mk = MSig(methodName, pTypes, method._retType); IList <MethodInfo> ms = null; if (matches.Count > 0) { // multiple matches if (matches.Count > 1) { // must be hinted and match one method if (!hinted) { throw new ParseException("Must hint overloaded method: " + name.Name); } if (!matches.TryGetValue(mk, out ms)) { throw new ParseException("Can't find matching overloaded method: " + name.Name); } method._minfos = ms; } else // one match { // if hinted, validate match, if (hinted) { if (!matches.TryGetValue(mk, out ms)) { throw new ParseException("Can't find matching method: " + name.Name + ", leave off hints for auto match."); } method._minfos = ms; //if (m.ReturnType != method._retType) // throw new ArgumentException(String.Format("Mismatched return type: {0}, expected {1}, had: {2}", // name.Name, m.ReturnType.Name, method._retType.Name)); } else // adopt found method sig { using (var e = matches.GetEnumerator()) { e.MoveNext(); mk = e.Current.Key; ms = e.Current.Value; } MethodInfo m = ms[0]; method._retType = m.ReturnType; pTypes = Compiler.GetTypes(m.GetParameters()); method._minfos = ms; } } } else { throw new ParseException("Can't define method not in interfaces: " + name.Name); } if (method.IsExplicit) { method.ExplicitMethodInfo = ms[0]; } // validate unique name + arity among additional methods for (int i = 0; i < parms.count(); i++) { LocalBinding lb = Compiler.RegisterLocal(pSyms[i], null, new MethodParamExpr(pTypes[i]), true, pRefs[i]); argLocals = argLocals.assocN(i, lb); method._argTypes[i] = pTypes[i]; } Compiler.LoopLocalsVar.set(argLocals); method._name = name.Name; method.MethodMeta = GenInterface.ExtractAttributes(RT.meta(name)); method.Parms = parms; method.ArgLocals = argLocals; method.Body = (new BodyExpr.Parser()).Parse(new ParserContext(RHC.Return), body); return(method); } finally { Var.popThreadBindings(); } }
object DrawStaticWidget(object key, object val) { if (val is string) { return(EditorGUILayout.TextField(key.ToString(), (string)val)); } else if (val is bool) { return(EditorGUILayout.Toggle(key.ToString(), (bool)val)); } else if (val is int) { return(EditorGUILayout.IntField(key.ToString(), (int)val)); } else if (val is long) { return(EditorGUILayout.IntField(key.ToString(), (int)(long)val)); } else if (val is Vector2) { return(EditorGUILayout.Vector2Field(key.ToString(), (Vector2)val)); } else if (val is Vector3) { return(EditorGUILayout.Vector3Field(key.ToString(), (Vector3)val)); } else if (val is Vector4) { return(EditorGUILayout.Vector4Field(key.ToString(), (Vector4)val)); } else if (val is float) { return(EditorGUILayout.FloatField(key.ToString(), (float)val)); } else if (val is double) { return(EditorGUILayout.FloatField(key.ToString(), (float)(double)val)); } else if (val is Symbol) { return(Symbol.intern(EditorGUILayout.TextField(key.ToString(), val.ToString()))); } else if (val is Keyword) { return(Keyword.intern(EditorGUILayout.TextField(key.ToString(), ((Keyword)val).ToString().Substring(1)))); } else if (val is IPersistentMap) { IPersistentMap map = val as IPersistentMap; EditorGUILayout.LabelField(key.ToString(), "{"); EditorGUI.indentLevel++; foreach (var entry in map) { map = map.assoc(entry.key(), DrawStaticWidget(entry.key(), entry.val())); } // EditorGUILayout.LabelField("", "}"); 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, DrawStaticWidget(i.ToString(), vector.nth(i))); } // EditorGUILayout.LabelField("", "]"); EditorGUI.indentLevel--; return(vector); } else { EditorGUILayout.LabelField(key.ToString(), "val.GetType().ToString()"); return(val); } }