Skip to content

Commit 97a8568

Browse files
committed
[GR-12855] Implement or for frozenset.
1 parent dfe6086 commit 97a8568

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/set/FrozenSetBuiltins.java

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
package com.oracle.graal.python.builtins.objects.set;
2727

2828
import static com.oracle.graal.python.nodes.SpecialMethodNames.__AND__;
29+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__OR__;
2930
import static com.oracle.graal.python.nodes.SpecialMethodNames.__CONTAINS__;
3031
import static com.oracle.graal.python.nodes.SpecialMethodNames.__EQ__;
3132
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GE__;
@@ -73,6 +74,7 @@
7374
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
7475
import com.oracle.truffle.api.dsl.NodeFactory;
7576
import com.oracle.truffle.api.dsl.Specialization;
77+
import com.oracle.truffle.api.nodes.Node;
7678
import com.oracle.truffle.api.profiles.ConditionProfile;
7779
import com.oracle.truffle.api.profiles.ValueProfile;
7880

@@ -208,7 +210,67 @@ PBaseSet doPBaseSet(PFrozenSet left, PBaseSet right) {
208210

209211
@Fallback
210212
Object doAnd(Object self, Object other) {
211-
throw raise(PythonErrorType.TypeError, "unsupported operand type(s) for &=: '%p' and '%p'", self, other);
213+
throw raise(PythonErrorType.TypeError, "unsupported operand type(s) for &: '%p' and '%p'", self, other);
214+
}
215+
}
216+
217+
@Builtin(name = __OR__, fixedNumOfPositionalArgs = 2)
218+
@GenerateNodeFactory
219+
abstract static class OrNode extends PythonBinaryBuiltinNode {
220+
@Node.Child private HashingStorageNodes.UnionNode unionNode;
221+
@Node.Child private HashingStorageNodes.SetItemNode setItemNode;
222+
223+
private HashingStorageNodes.SetItemNode getSetItemNode() {
224+
if (setItemNode == null) {
225+
CompilerDirectives.transferToInterpreterAndInvalidate();
226+
setItemNode = insert(HashingStorageNodes.SetItemNode.create());
227+
}
228+
return setItemNode;
229+
}
230+
231+
@TruffleBoundary
232+
private HashingStorage getStringAsHashingStorage(String str) {
233+
HashingStorage storage = EconomicMapStorage.create(str.length(), true);
234+
for (int i = 0; i < str.length(); i++) {
235+
String key = String.valueOf(str.charAt(i));
236+
getSetItemNode().execute(storage, key, PNone.NO_VALUE);
237+
}
238+
return storage;
239+
}
240+
241+
@Specialization
242+
PBaseSet doPBaseSet(PSet left, String right) {
243+
return factory().createSet(getUnionNode().execute(left.getDictStorage(), getStringAsHashingStorage(right)));
244+
}
245+
246+
@Specialization
247+
PBaseSet doPBaseSet(PFrozenSet left, String right) {
248+
return factory().createFrozenSet(getUnionNode().execute(left.getDictStorage(), getStringAsHashingStorage(right)));
249+
}
250+
251+
private HashingStorageNodes.UnionNode getUnionNode() {
252+
if (unionNode == null) {
253+
CompilerDirectives.transferToInterpreterAndInvalidate();
254+
unionNode = insert(HashingStorageNodes.UnionNode.create());
255+
}
256+
return unionNode;
257+
}
258+
259+
@Specialization
260+
PBaseSet doPBaseSet(PSet left, PBaseSet right) {
261+
HashingStorage intersectedStorage = getUnionNode().execute(left.getDictStorage(), right.getDictStorage());
262+
return factory().createSet(intersectedStorage);
263+
}
264+
265+
@Specialization
266+
PBaseSet doPBaseSet(PFrozenSet left, PBaseSet right) {
267+
HashingStorage intersectedStorage = getUnionNode().execute(left.getDictStorage(), right.getDictStorage());
268+
return factory().createFrozenSet(intersectedStorage);
269+
}
270+
271+
@Fallback
272+
Object doAnd(Object self, Object other) {
273+
throw raise(PythonErrorType.TypeError, "unsupported operand type(s) for |: '%p' and '%p'", self, other);
212274
}
213275
}
214276

0 commit comments

Comments
 (0)