Skip to content

Commit b07c135

Browse files
committed
[GR-9687] Reimplement list.remove node.
PullRequest: graalpython-open/33
2 parents 192c4d1 + dd598bc commit b07c135

File tree

3 files changed

+91
-10
lines changed

3 files changed

+91
-10
lines changed

graalpython/com.oracle.graal.python.test/src/tests/list_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def test_pop(self):
316316
# self.assertRaises(IndexError, a.pop)
317317
self.assertRaises(TypeError, a.pop, 42, 42)
318318
a = self.type2test([0, 10, 20, 30, 40])
319-
'''
319+
320320
def test_remove(self):
321321
a = self.type2test([0, 0, 1])
322322
a.remove(1)
@@ -361,7 +361,7 @@ def __eq__(self, other):
361361
for x, y in zip(d, e):
362362
# verify that original order and values are retained.
363363
self.assertIs(x, y)
364-
364+
'''
365365
def test_count(self):
366366
a = self.type2test([0, 1, 2])*3
367367
self.assertEqual(a.count(0), 3)

graalpython/com.oracle.graal.python.test/src/tests/test_list.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,29 @@ def test_set_slice_generalize_storage(self):
280280
a[1:5] = [1.1, 2.2, 3.3]
281281
self.assertEqual([1,1.1, 2.2, 3.3], a)
282282

283+
def test_remove_spec(self):
284+
a = [1,2]
285+
a.remove(2);
286+
self.assertEqual([1], a)
287+
a.remove(1)
288+
self.assertEqual([], a)
289+
290+
a = [0,1,0,1,2]
291+
a.remove(True)
292+
self.assertEqual([0,0,1,2], a)
293+
a.remove(False)
294+
self.assertEqual([0,1,2], a)
295+
296+
a = list([LONG_NUMBER, LONG_NUMBER + 1])
297+
a.remove(LONG_NUMBER + 1)
298+
self.assertEqual([LONG_NUMBER], a)
299+
300+
class MyInt(int):
301+
pass
302+
303+
a = [1,2,3]
304+
a.remove(MyInt(2))
305+
self.assertEqual([1,3], a)
283306
def test_insert_spec(self):
284307
a = [1,2]
285308
self.assertRaises(TypeError, a.insert, [1,2,3], 1)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -613,15 +613,73 @@ protected ListInsertNode createListInsertNode() {
613613
@GenerateNodeFactory
614614
public abstract static class ListRemoveNode extends PythonBuiltinNode {
615615

616-
@Specialization
617-
public PList remove(PList list, Object arg) {
618-
int index = list.index(arg);
619-
if (index >= 0) {
620-
list.delItem(index);
621-
return list;
622-
} else {
623-
throw raise(PythonErrorType.ValueError, "list.remove(x): x not in list");
616+
private static String NOT_IN_LIST_MESSAGE = "list.index(x): x not in list";
617+
618+
@Specialization(guards = "isIntStorage(list)")
619+
public PNone removeInt(PList list, int value) {
620+
IntSequenceStorage store = (IntSequenceStorage) list.getSequenceStorage();
621+
for (int index = 0; index < store.length(); index++) {
622+
if (value == store.getIntItemNormalized(index)) {
623+
store.delItemInBound(index);
624+
return PNone.NONE;
625+
}
626+
}
627+
throw raise(PythonErrorType.ValueError, NOT_IN_LIST_MESSAGE);
628+
}
629+
630+
@Specialization(guards = "isLongStorage(list)")
631+
public PNone removeLong(PList list, int value) {
632+
LongSequenceStorage store = (LongSequenceStorage) list.getSequenceStorage();
633+
for (int index = 0; index < store.length(); index++) {
634+
if (value == store.getLongItemNormalized(index)) {
635+
store.delItemInBound(index);
636+
return PNone.NONE;
637+
}
638+
}
639+
throw raise(PythonErrorType.ValueError, NOT_IN_LIST_MESSAGE);
640+
}
641+
642+
@Specialization(guards = "isLongStorage(list)")
643+
public PNone removeLong(PList list, long value) {
644+
LongSequenceStorage store = (LongSequenceStorage) list.getSequenceStorage();
645+
for (int index = 0; index < store.length(); index++) {
646+
if (value == store.getLongItemNormalized(index)) {
647+
store.delItemInBound(index);
648+
return PNone.NONE;
649+
}
624650
}
651+
throw raise(PythonErrorType.ValueError, NOT_IN_LIST_MESSAGE);
652+
}
653+
654+
@Specialization(guards = "isDoubleStorage(list)")
655+
public PNone removeDouble(PList list, double value) {
656+
DoubleSequenceStorage store = (DoubleSequenceStorage) list.getSequenceStorage();
657+
for (int index = 0; index < store.length(); index++) {
658+
if (value == store.getDoubleItemNormalized(index)) {
659+
store.delItemInBound(index);
660+
return PNone.NONE;
661+
}
662+
}
663+
throw raise(PythonErrorType.ValueError, NOT_IN_LIST_MESSAGE);
664+
}
665+
666+
@Specialization(guards = "isNotSpecialCase(list, value)")
667+
public PNone remove(PList list, Object value,
668+
@Cached("create(__EQ__, __EQ__, __EQ__)") BinaryComparisonNode eqNode) {
669+
int len = list.len();
670+
for (int i = 0; i < len; i++) {
671+
Object object = list.getItem(i);
672+
if (eqNode.executeBool(object, value)) {
673+
list.delItem(i);
674+
return PNone.NONE;
675+
}
676+
}
677+
throw raise(PythonErrorType.ValueError, NOT_IN_LIST_MESSAGE);
678+
}
679+
680+
protected boolean isNotSpecialCase(PList list, Object value) {
681+
return !((PGuards.isIntStorage(list) && value instanceof Integer) || (PGuards.isLongStorage(list) && (value instanceof Integer || value instanceof Long)) ||
682+
PGuards.isDoubleStorage(list) && value instanceof Double);
625683
}
626684
}
627685

0 commit comments

Comments
 (0)