def test_proper_cons(self): a = cons(2, nil) b = cons(1, a) c = cons(0, b) self.assertTrue(a.is_proper()) self.assertTrue(b.is_proper()) self.assertTrue(c.is_proper()) self.assertFalse(a.is_recursive()) self.assertFalse(b.is_recursive()) self.assertFalse(c.is_recursive()) self.assertEqual(car(b), 1) self.assertEqual(car(cdr(b)), 2) self.assertEqual(car(c), 0) self.assertEqual(car(cdr(c)), 1) self.assertEqual(car(cdr(cdr(c))), 2) x, (y, (z, n)) = c self.assertEqual(x, 0) self.assertEqual(y, 1) self.assertEqual(z, 2) self.assertEqual(n, nil) x, y, z = c.unpack() self.assertEqual(x, 0) self.assertEqual(y, 1) self.assertEqual(z, 2) self.assertEqual(c.count(), 3) self.assertSequenceEqual(list(c.unpack()), [0, 1, 2]) self.assertSequenceEqual(tuple(c.unpack()), (0, 1, 2)) self.assertEqual(str(c), "(0 1 2)") self.assertEqual(repr(c), "cons(0, cons(1, cons(2, niltype())))") self.assertEqual(car(a), 2) self.assertEqual(cdr(a), nil) self.assertEqual(car(b), 1) self.assertEqual(cdr(b), a) w = cons(0, cons(1, cons(2, nil))) self.assertEqual(c, w) self.assertEqual(w, c) u = cons(99, c) v = cons(99, w) self.assertEqual(u, v) self.assertEqual(v, u) self.assertNotEqual(cons(99, nil), u) self.assertNotEqual(u, cons(99, nil))
def simplify(self, positions): c = None for member in self.members[::-1]: s = member.simplify(positions) if c is None: c = cons(s, nil) if self.proper else s else: c = cons(s, c) positions[id(c)] = member.position if c is None: c = nil return c
def bup(*items): if not items: return nil coll = list() colle = coll.extend for item in items: if item is nil: pass elif is_pair(item): colle(item.unpack()) else: colle(item) if not coll: return nil elif not is_pair(item): coll.append(nil) elif is_proper(item): coll.append(nil) return cons(*coll)
def test_nil(self): # singleton nil check self.assertEqual(id(nil), id(niltype())) self.assertEqual(id(niltype()), id(niltype())) self.assertTrue(nil is niltype()) # behavior self.assertIsInstance(nil, cons) self.assertFalse(nil) self.assertEqual(str(nil), "()") self.assertEqual(repr(nil), "niltype()") self.assertEqual(nil, nil) self.assertNotEqual(nil, cons(1, nil)) self.assertNotEqual(cons(1, nil), nil) with self.assertRaises(TypeError): car(nil) with self.assertRaises(TypeError): cdr(nil) self.assertEqual(list(nil), list()) self.assertEqual(tuple(nil), tuple())
def test_recursive_cons(self): a = cons(1, cons(2, cons(3, nil))) setcdr(cdr(cdr(a)), a) self.assertTrue(a.is_proper()) self.assertTrue(a.is_recursive()) self.assertEqual(car(a), car(cdr(cdr(cdr(a))))) self.assertEqual(str(a), "(1 2 3 ...)") self.assertEqual(repr(a), "cons(1, cons(2, cons(3, ...)))") b = cons(0, a) c = cons(0, a) self.assertEqual(b, c) self.assertNotEqual(a, b) self.assertNotEqual(a, c) z = cons(1, cons(2, cons(3, nil))) setcdr(cdr(cdr(z)), z) self.assertEqual(a, z) self.assertEqual(z, a)
def test_dot(self): src = "(1.4)" col = simplify(src) self.assertEqual(col, cons(1.4, nil)) src = "(1. 4)" col = simplify(src) self.assertEqual(col, cons(1.0, cons(4, nil))) src = "(1 .4)" col = simplify(src) self.assertEqual(col, cons(1, cons(0.4, nil))) src = "(1 . 4)" col = simplify(src) self.assertEqual(col, cons(1, 4))
return nil elif not is_pair(item): coll.append(nil) elif is_proper(item): coll.append(nil) return cons(*coll) # in essence, bup combines lists and pairs into a new pair list. If # the last item is proper, then the result is also proper. If the # whole thing is empty, then it's nil assert bup([1, 2, 3]) == cons(1, 2, 3, nil) assert bup([1, 2, 3], []) == cons(1, 2, 3, nil) assert bup([1, 2, 3], [4]) == cons(1, 2, 3, 4, nil) assert bup([1, 2, 3], [], [4]) == cons(1, 2, 3, 4, nil) assert bup([1, 2, 3], [], [1, 2]) == cons(1, 2, 3, 1, 2, nil) assert bup(cons(1, nil), nil, [1, 2]) == cons(1, 1, 2, nil) assert bup([1, 2, 3], nil) == cons(1, 2, 3, nil) assert bup([1, 2, 3], [nil]) == cons(1, 2, 3, nil, nil) assert bup([1, 2, 3], [], nil) == cons(1, 2, 3, nil) assert bup([1, 2, 3], [nil], nil) == cons(1, 2, 3, nil, nil) assert bup([1, 2, 3], [], cons(4, nil)) == cons(1, 2, 3, 4, nil) assert bup([1]) == cons(1, nil) # only way to get an improper result is if the last argument is an # improper cons list. Non-pair sequences are considered proper. assert bup([1, 2, 3], [], cons(1, 2)) == cons(1, 2, 3, 1, 2)
def test_improper_cons(self): z = cons(1, 2) self.assertFalse(z.is_proper()) self.assertEqual(car(z), 1) self.assertEqual(cdr(z), 2) self.assertEqual(str(z), "(1 . 2)")