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):
self.node = node
self.nodes = get_scope(node)
for i, n in enumerate(self.nodes):
n.scope_index = i
def __getitem__(self, key):
return self.nodes[key]
......@@ -576,17 +579,22 @@ class Scope(object):
return '<Scope of "%s">' % repr(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:
i = self.nodes.index(node)
i = node.scope_index
if 'replacement' in kwargs:
self[i] = kwargs['replacement']
if replacement:
self[i] = replacement
replacement.scope_index = i
else:
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".'
% (node, self.node))
......
......@@ -34,24 +34,25 @@ class TestRulesFactors(RulesTestCase):
P(root, expand_single, (Scope(root), ab, e))])
def test_expand_single(self):
a, b, c, d = tree('a,b,c,d')
bc = b + c
root = a * bc
root, expect = tree('a(b + c), ab + ac')
a, bc = root
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)),
a * (b * d + c * d))
expect)
def test_expand_double(self):
(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)),
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)),
a * (a * c + a * d + b * c + b * d) * b * c)
expect)
......@@ -21,21 +21,17 @@ class TestRulesNumerics(RulesTestCase):
[P(root, add_numerics, (Scope(root), l1, l2))])
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
self.assertEqual(add_numerics(root, (Scope(root), l0, l1)), 3)
root = l0 + a + l1
self.assertEqual(add_numerics(root, (Scope(root), l0, l1)), L(3) + a)
(l1, a), l2 = root = tree('1 + a + 2')
self.assertEqual(add_numerics(root, (Scope(root), l1, l2)), L(3) + a)
def test_add_numerics_negations(self):
l1, a, l2 = tree('1,a,2')
ml1, ml2 = -l1, -l2
r = ml1 + l2
self.assertEqual(add_numerics(r, (Scope(r), ml1, l2)), 1)
r = l1 + ml2
self.assertEqual(add_numerics(r, (Scope(r), l1, ml2)), -1)
ml1, l2 = root = tree('-1 + 2')
self.assertEqual(add_numerics(root, (Scope(root), ml1, l2)), 1)
l1, ml2 = root = tree('1 - 2')
self.assertEqual(add_numerics(root, (Scope(root), l1, ml2)), -1)
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')
......@@ -127,16 +123,16 @@ class TestRulesNumerics(RulesTestCase):
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')
root = i3 * i2
i3, i2 = root = tree('3 * 2')
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)
root = i3 * f2
i3, f2 = root = tree('3 * 2.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)
root = a * i3 * i2 * b
((a, i3), i2), b = root = tree('a * 3 * 2 * b')
self.assertEqualNodes(multiply_numerics(root,
(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