From: Finn B. <bc...@us...> - 2001-01-31 13:39:22
|
Update of /cvsroot/jython/jython/org/python/core In directory usw-pr-cvs1:/tmp/cvs-serv15073 Modified Files: PyInstance.java PyObject.java PySequence.java PyString.java Log Message: Support for Rich Comparisons (pep-0207). Index: PyInstance.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyInstance.java,v retrieving revision 2.14 retrieving revision 2.15 diff -C2 -r2.14 -r2.15 *** PyInstance.java 2001/01/31 13:34:35 2.14 --- PyInstance.java 2001/01/31 13:39:20 2.15 *************** *** 431,434 **** --- 431,458 ---- } + public PyObject __lt__(PyObject o) { + return invoke_ex("__lt__", o); + } + + public PyObject __le__(PyObject o) { + return invoke_ex("__le__", o); + } + + public PyObject __gt__(PyObject o) { + return invoke_ex("__gt__", o); + } + + public PyObject __ge__(PyObject o) { + return invoke_ex("__ge__", o); + } + + public PyObject __eq__(PyObject o) { + return invoke_ex("__eq__", o); + } + + public PyObject __ne__(PyObject o) { + return invoke_ex("__ne__", o); + } + public boolean __nonzero__() { PyObject ret = invoke_ex("__nonzero__"); Index: PyObject.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyObject.java,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -r2.17 -r2.18 *** PyObject.java 2001/01/31 13:34:35 2.17 --- PyObject.java 2001/01/31 13:39:20 2.18 *************** *** 175,179 **** public boolean equals(Object ob_other) { return (ob_other instanceof PyObject) && ! _cmp((PyObject)ob_other) == 0; } --- 175,179 ---- public boolean equals(Object ob_other) { return (ob_other instanceof PyObject) && ! _eq((PyObject)ob_other).__nonzero__(); } *************** *** 825,828 **** --- 825,841 ---- + public PyObject __eq__(PyObject other) { return null; } + + public PyObject __ne__(PyObject other) { return null; } + + public PyObject __le__(PyObject other) { return null; } + + public PyObject __lt__(PyObject other) { return null; } + + public PyObject __ge__(PyObject other) { return null; } + + public PyObject __gt__(PyObject other) { return null; } + + /** Implements cmp(this, other) *************** *** 920,940 **** } public final PyObject _eq(PyObject o) { ! return _cmp(o) == 0 ? Py.One : Py.Zero; } public final PyObject _ne(PyObject o) { ! return _cmp(o) != 0 ? Py.One : Py.Zero; } public final PyObject _le(PyObject o) { ! return _cmp(o) <= 0 ? Py.One : Py.Zero; } public final PyObject _lt(PyObject o) { ! return _cmp(o) < 0 ? Py.One : Py.Zero; } public final PyObject _ge(PyObject o) { ! return _cmp(o) >= 0 ? Py.One : Py.Zero; } public final PyObject _gt(PyObject o) { ! return _cmp(o) > 0 ? Py.One : Py.Zero; } --- 933,1090 ---- } + + private final static PyObject check_recursion(ThreadState ts, PyObject o1, PyObject o2) { + PyDictionary stateDict = ts.getCompareStateDict(); + + PyObject pair = o1.make_pair(o2); + + if (stateDict.__finditem__(pair) != null) + return null; + + stateDict.__setitem__(pair, pair); + return pair; + } + + private final static void delete_token(ThreadState ts, PyObject token) { + if (token == null) + return; + PyDictionary stateDict = ts.getCompareStateDict(); + + stateDict.__delitem__(token); + } + + public final PyObject _eq(PyObject o) { ! PyObject token = null; ! ! ThreadState ts = Py.getThreadState(); ! try { ! if (++ts.compareStateNesting > 10) { ! if ((token = check_recursion(ts, this, o)) == null) ! return Py.One; ! } ! PyObject res = __eq__(o); ! if (res != null) ! return res; ! res = o.__eq__(this); ! if (res != null) ! return res; ! return _cmp_unsafe(o) == 0 ? Py.One : Py.Zero; ! } finally { ! delete_token(ts, token); ! ts.compareStateNesting--; ! } } + + public final PyObject _ne(PyObject o) { ! PyObject token = null; ! ! ThreadState ts = Py.getThreadState(); ! try { ! if (++ts.compareStateNesting > 10) { ! if ((token = check_recursion(ts, this, o)) == null) ! return Py.Zero; ! } ! PyObject res = __ne__(o); ! if (res != null) ! return res; ! res = o.__ne__(this); ! if (res != null) ! return res; ! return _cmp_unsafe(o) != 0 ? Py.One : Py.Zero; ! } finally { ! delete_token(ts, token); ! ts.compareStateNesting--; ! } } + public final PyObject _le(PyObject o) { ! PyObject token = null; ! ! ThreadState ts = Py.getThreadState(); ! try { ! if (++ts.compareStateNesting > 10) { ! if ((token = check_recursion(ts, this, o)) == null) ! throw Py.ValueError("can't order recursive values"); ! } ! PyObject res = __le__(o); ! if (res != null) ! return res; ! res = o.__ge__(this); ! if (res != null) ! return res; ! return _cmp_unsafe(o) <= 0 ? Py.One : Py.Zero; ! } finally { ! delete_token(ts, token); ! ts.compareStateNesting--; ! } } + public final PyObject _lt(PyObject o) { ! PyObject token = null; ! ! ThreadState ts = Py.getThreadState(); ! try { ! if (++ts.compareStateNesting > 10) { ! if ((token = check_recursion(ts, this, o)) == null) ! throw Py.ValueError("can't order recursive values"); ! } ! PyObject res = __lt__(o); ! if (res != null) ! return res; ! res = o.__gt__(this); ! if (res != null) ! return res; ! return _cmp_unsafe(o) < 0 ? Py.One : Py.Zero; ! } finally { ! delete_token(ts, token); ! ts.compareStateNesting--; ! } } + public final PyObject _ge(PyObject o) { ! PyObject token = null; ! ! ThreadState ts = Py.getThreadState(); ! try { ! if (++ts.compareStateNesting > 10) { ! if ((token = check_recursion(ts, this, o)) == null) ! throw Py.ValueError("can't order recursive values"); ! } ! PyObject res = __ge__(o); ! if (res != null) ! return res; ! res = o.__le__(this); ! if (res != null) ! return res; ! return _cmp_unsafe(o) >= 0 ? Py.One : Py.Zero; ! } finally { ! delete_token(ts, token); ! ts.compareStateNesting--; ! } } + public final PyObject _gt(PyObject o) { ! PyObject token = null; ! ! ThreadState ts = Py.getThreadState(); ! try { ! if (++ts.compareStateNesting > 10) { ! if ((token = check_recursion(ts, this, o)) == null) ! throw Py.ValueError("can't order recursive values"); ! } ! PyObject res = __gt__(o); ! if (res != null) ! return res; ! res = o.__lt__(this); ! if (res != null) ! return res; ! return _cmp_unsafe(o) > 0 ? Py.One : Py.Zero; ! } finally { ! delete_token(ts, token); ! ts.compareStateNesting--; ! } ! } *************** *** 942,945 **** --- 1092,1096 ---- return this == o ? Py.One : Py.Zero; } + public PyObject _isnot(PyObject o) { return this != o ? Py.One : Py.Zero; Index: PySequence.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PySequence.java,v retrieving revision 2.13 retrieving revision 2.14 diff -C2 -r2.13 -r2.14 *** PySequence.java 2001/01/31 13:34:35 2.13 --- PySequence.java 2001/01/31 13:39:20 2.14 *************** *** 185,204 **** } ! public synchronized int __cmp__(PyObject ob_other) { ! if (ob_other.__class__ != __class__) ! return -2; ! ! PySequence other = (PySequence)ob_other; ! int s1 = __len__(); ! int s2 = other.__len__(); ! int len = (s1 > s2) ? s2 : s1; ! ! for (int i=0; i<len; i++) { ! int c = get(i)._cmp(other.get(i)); ! if (c != 0) ! return c; } ! return s1 < s2 ? -1 : (s1 > s2 ? 1: 0); } // Return a copy of a sequence where the __len__() method is --- 185,265 ---- } ! public synchronized PyObject __eq__(PyObject o) { ! if (o.__class__ != __class__) ! return null; ! int tl = __len__(); ! int ol = o.__len__(); ! if (tl != ol) ! return Py.Zero; ! int i = cmp(this, tl, o, ol); ! return (i < 0) ? Py.One : Py.Zero; ! } ! ! public synchronized PyObject __ne__(PyObject o) { ! if (o.__class__ != __class__) ! return null; ! int tl = __len__(); ! int ol = o.__len__(); ! if (tl != ol) ! return Py.One; ! int i = cmp(this, tl, o, ol); ! return (i < 0) ? Py.Zero : Py.One; ! } ! ! public synchronized PyObject __lt__(PyObject o) { ! if (o.__class__ != __class__) ! return null; ! int i = cmp(this, -1, o, -1); ! if (i < 0) ! return (i == -1) ? Py.One : Py.Zero; ! return __finditem__(i)._lt(o.__finditem__(i)); ! } ! ! public synchronized PyObject __le__(PyObject o) { ! if (o.__class__ != __class__) ! return null; ! int i = cmp(this, -1, o, -1); ! if (i < 0) ! return (i == -1 || i == -2) ? Py.One : Py.Zero; ! return __finditem__(i)._le(o.__finditem__(i)); ! } ! ! public synchronized PyObject __gt__(PyObject o) { ! if (o.__class__ != __class__) ! return null; ! int i = cmp(this, -1, o, -1); ! if (i < 0) ! return (i == -3) ? Py.One : Py.Zero; ! return __finditem__(i)._gt(o.__finditem__(i)); ! } ! ! public synchronized PyObject __ge__(PyObject o) { ! if (o.__class__ != __class__) ! return null; ! int i = cmp(this, -1, o, -1); ! if (i < 0) ! return (i == -3 || i == -2) ? Py.One : Py.Zero; ! return __finditem__(i)._ge(o.__finditem__(i)); ! } ! ! // Return value >= 0 is the index where the sequences differs. ! // -1: reached the end of o1 without a difference ! // -2: reached the end of both seqeunces without a difference ! // -3: reached the end of o2 without a difference ! private static int cmp(PyObject o1, int ol1, PyObject o2, int ol2) { ! if (ol1 < 0) ! ol1 = o1.__len__(); ! if (ol2 < 0) ! ol2 = o2.__len__(); ! int i = 0; ! for ( ; i < ol1 && i < ol2; i++) { ! if (!o1.__getitem__(i)._eq(o2.__getitem__(i)).__nonzero__()) ! return i; } ! if (ol1 == ol2) ! return -2; ! return (ol1 < ol2) ? -1 : -3; } + // Return a copy of a sequence where the __len__() method is Index: PyString.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyString.java,v retrieving revision 2.34 retrieving revision 2.35 diff -C2 -r2.34 -r2.35 *** PyString.java 2001/01/21 16:21:36 2.34 --- PyString.java 2001/01/31 13:39:20 2.35 *************** *** 558,561 **** --- 558,609 ---- } + public PyObject __eq__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.equals(s) ? Py.One : Py.Zero; + } + + public PyObject __ne__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.equals(s) ? Py.Zero : Py.One; + } + + public PyObject __lt__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) < 0 ? Py.One : Py.Zero; + } + + public PyObject __le__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) <= 0 ? Py.One : Py.Zero; + } + + public PyObject __gt__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) > 0 ? Py.One : Py.Zero; + } + + public PyObject __ge__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) >= 0 ? Py.One : Py.Zero; + } + + private static String coerce(PyObject o) { + if (o instanceof PyString) + return o.toString(); + return null; + } + public int hashCode() { if (cached_hashcode == 0) |