Fix for equal? bug #312

This commit is contained in:
Doug Currie 2015-12-27 21:27:26 -05:00
parent 75246336e8
commit b585d89056
1 changed files with 25 additions and 10 deletions

View File

@ -10,8 +10,10 @@ KHASH_DEFINE2(m, void *, int, 0, kh_ptr_hash_func, kh_ptr_hash_equal)
static bool static bool
internal_equal_p(pic_state *pic, pic_value x, pic_value y, int depth, khash_t(m) *h) internal_equal_p(pic_state *pic, pic_value x, pic_value y, int depth, khash_t(m) *h)
{ {
pic_value local = pic_nil_value(); pic_value localx = pic_nil_value();
int c = 0; pic_value localy = pic_nil_value();
int cx = 0;
int cy = 0;
if (depth > 10) { if (depth > 10) {
if (depth > 200) { if (depth > 200) {
@ -68,17 +70,30 @@ internal_equal_p(pic_state *pic, pic_value x, pic_value y, int depth, khash_t(m)
return false; return false;
/* Floyd's cycle-finding algorithm */ /* Floyd's cycle-finding algorithm */
if (pic_nil_p(local)) { if (pic_nil_p(localx)) {
local = x; localx = x;
} }
x = pic_cdr(pic, x); x = pic_cdr(pic, x);
cx++;
if (pic_nil_p(localy)) {
localy = y;
}
y = pic_cdr(pic, y); y = pic_cdr(pic, y);
c++; cy++;
if (c == 2) { if (cx == 2) {
c = 0; cx = 0;
local = pic_cdr(pic, local); localx = pic_cdr(pic, localx);
if (pic_eq_p(local, x)) { if (pic_eq_p(localx, x)) {
return true; if (cy < 0 ) return true; /* both lists circular */
cx = INT_MIN; /* found a cycle on x */
}
}
if (cy == 2) {
cy = 0;
localy = pic_cdr(pic, localy);
if (pic_eq_p(localy, y)) {
if (cx < 0 ) return true; /* both lists circular */
cy = INT_MIN; /* found a cycle on y */
} }
} }
goto LOOP; /* tail-call optimization */ goto LOOP; /* tail-call optimization */