Commit 91a26452 authored by Taddeus Kroes's avatar Taddeus Kroes

Scope removing/replacing is now done using numeric indices instead of node references.

parent 712dbdbc
...@@ -556,6 +556,9 @@ class Scope(object): ...@@ -556,6 +556,9 @@ class Scope(object):
self.node = node self.node = node
self.nodes = get_scope(node) self.nodes = get_scope(node)
for i, n in enumerate(self.nodes):
n.scope_index = i
def __getitem__(self, key): def __getitem__(self, key):
return self.nodes[key] return self.nodes[key]
...@@ -576,17 +579,22 @@ class Scope(object): ...@@ -576,17 +579,22 @@ class Scope(object):
return '<Scope of "%s">' % repr(self.node) return '<Scope of "%s">' % repr(self.node)
def index(self, node): def index(self, node):
return self.nodes.index(node) return node.scope_index
def remove(self, node, **kwargs): def remove(self, node, replacement=None):
try: try:
i = self.nodes.index(node) i = node.scope_index
if 'replacement' in kwargs: if replacement:
self[i] = kwargs['replacement'] self[i] = replacement
replacement.scope_index = i
else: else:
del self.nodes[i] del self.nodes[i]
except ValueError:
# Update remaining scope indices
for n in self[max(i, 1):]:
n.scope_index -= 1
except AttributeError:
raise ValueError('Node "%s" is not in the scope of "%s".' raise ValueError('Node "%s" is not in the scope of "%s".'
% (node, self.node)) % (node, self.node))
......
...@@ -34,24 +34,25 @@ class TestRulesFactors(RulesTestCase): ...@@ -34,24 +34,25 @@ class TestRulesFactors(RulesTestCase):
P(root, expand_single, (Scope(root), ab, e))]) P(root, expand_single, (Scope(root), ab, e))])
def test_expand_single(self): def test_expand_single(self):
a, b, c, d = tree('a,b,c,d') root, expect = tree('a(b + c), ab + ac')
bc = b + c a, bc = root
root = a * bc
self.assertEqualNodes(expand_single(root, (Scope(root), a, bc)), self.assertEqualNodes(expand_single(root, (Scope(root), a, bc)),
a * b + a * c) expect)
root = a * bc * d root, expect = tree('a(b+c)d, a(bd + cd)')
(a, bc), d = root
self.assertEqualNodes(expand_single(root, (Scope(root), bc, d)), self.assertEqualNodes(expand_single(root, (Scope(root), bc, d)),
a * (b * d + c * d)) expect)
def test_expand_double(self): def test_expand_double(self):
(a, b), (c, d) = ab, cd = tree('a + b,c + d') (a, b), (c, d) = ab, cd = tree('a + b,c + d')
root = ab * cd root, expect = tree('(a + b)(c + d), ac + ad + bc + bd')
ab, cd = root
self.assertEqualNodes(expand_double(root, (Scope(root), ab, cd)), self.assertEqualNodes(expand_double(root, (Scope(root), ab, cd)),
a * c + a * d + b * c + b * d) expect)
root = a * ab * b * cd * c root, expect = tree('a(a + b)b(c + d)c, a(ac + ad + bc + bd)bc')
(((a, ab), b), cd), c = root
self.assertEqualNodes(expand_double(root, (Scope(root), ab, cd)), self.assertEqualNodes(expand_double(root, (Scope(root), ab, cd)),
a * (a * c + a * d + b * c + b * d) * b * c) expect)
...@@ -21,21 +21,17 @@ class TestRulesNumerics(RulesTestCase): ...@@ -21,21 +21,17 @@ class TestRulesNumerics(RulesTestCase):
[P(root, add_numerics, (Scope(root), l1, l2))]) [P(root, add_numerics, (Scope(root), l1, l2))])
def test_add_numerics(self): def test_add_numerics(self):
l0, a, l1 = tree('1,a,2') l1, l2 = root = tree('1 + 2')
self.assertEqual(add_numerics(root, (Scope(root), l1, l2)), 3)
root = l0 + l1 (l1, a), l2 = root = tree('1 + a + 2')
self.assertEqual(add_numerics(root, (Scope(root), l0, l1)), 3) self.assertEqual(add_numerics(root, (Scope(root), l1, l2)), L(3) + a)
root = l0 + a + l1
self.assertEqual(add_numerics(root, (Scope(root), l0, l1)), L(3) + a)
def test_add_numerics_negations(self): def test_add_numerics_negations(self):
l1, a, l2 = tree('1,a,2') ml1, l2 = root = tree('-1 + 2')
ml1, ml2 = -l1, -l2 self.assertEqual(add_numerics(root, (Scope(root), ml1, l2)), 1)
l1, ml2 = root = tree('1 - 2')
r = ml1 + l2 self.assertEqual(add_numerics(root, (Scope(root), l1, ml2)), -1)
self.assertEqual(add_numerics(r, (Scope(r), ml1, l2)), 1)
r = l1 + ml2
self.assertEqual(add_numerics(r, (Scope(r), l1, ml2)), -1)
def test_match_divide_numerics(self): def test_match_divide_numerics(self):
a, b, i2, i3, i4, i6, f1, f2, f3 = tree('a,b,2,3,4,6,1.0,2.0,3.0') a, b, i2, i3, i4, i6, f1, f2, f3 = tree('a,b,2,3,4,6,1.0,2.0,3.0')
...@@ -127,16 +123,16 @@ class TestRulesNumerics(RulesTestCase): ...@@ -127,16 +123,16 @@ class TestRulesNumerics(RulesTestCase):
def test_multiply_numerics(self): def test_multiply_numerics(self):
a, b, i2, i3, i6, f2, f3, f6 = tree('a,b,2,3,6,2.0,3.0,6.0') a, b, i2, i3, i6, f2, f3, f6 = tree('a,b,2,3,6,2.0,3.0,6.0')
root = i3 * i2 i3, i2 = root = tree('3 * 2')
self.assertEqual(multiply_numerics(root, (Scope(root), i3, i2)), 6) self.assertEqual(multiply_numerics(root, (Scope(root), i3, i2)), 6)
root = f3 * i2 f3, i2 = root = tree('3.0 * 2')
self.assertEqual(multiply_numerics(root, (Scope(root), f3, i2)), 6.0) self.assertEqual(multiply_numerics(root, (Scope(root), f3, i2)), 6.0)
root = i3 * f2 i3, f2 = root = tree('3 * 2.0')
self.assertEqual(multiply_numerics(root, (Scope(root), i3, f2)), 6.0) self.assertEqual(multiply_numerics(root, (Scope(root), i3, f2)), 6.0)
root = f3 * f2 f3, f2 = root = tree('3.0 * 2.0')
self.assertEqual(multiply_numerics(root, (Scope(root), f3, f2)), 6.0) self.assertEqual(multiply_numerics(root, (Scope(root), f3, f2)), 6.0)
root = a * i3 * i2 * b ((a, i3), i2), b = root = tree('a * 3 * 2 * b')
self.assertEqualNodes(multiply_numerics(root, self.assertEqualNodes(multiply_numerics(root,
(Scope(root), i3, i2)), a * 6 * b) (Scope(root), i3, i2)), a * 6 * b)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment