Skip to content

Commit c9cb09d

Browse files
committed
implement iterator/iterable messages
1 parent a488d69 commit c9cb09d

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

graalpython/com.oracle.graal.python.tck/src/com/oracle/graal/python/tck/PythonProvider.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public class PythonProvider implements LanguageProvider {
9292
private static final TypeDescriptor BYTES = intersection(OBJECT, ITERABLE, array(INT));
9393
private static final TypeDescriptor BYTEARRAY = intersection(OBJECT, ITERABLE, array(INT));
9494
private static final TypeDescriptor DICT = dict(ANY, ANY);
95+
private static final TypeDescriptor SET = set(ANY);
9596
private static final TypeDescriptor LIST = list(ANY);
9697
private static final TypeDescriptor TUPLE = tuple(ANY);
9798
private static final TypeDescriptor DATETIME_DATE = intersection(OBJECT, DATE);
@@ -117,6 +118,10 @@ private static final TypeDescriptor dict(TypeDescriptor keyType, @SuppressWarnin
117118
return intersection(OBJECT, iterable(keyType));
118119
}
119120

121+
private static final TypeDescriptor set(TypeDescriptor componentType) {
122+
return intersection(OBJECT, iterable(componentType));
123+
}
124+
120125
private static final TypeDescriptor iter(TypeDescriptor componentType) {
121126
return intersection(OBJECT, iterable(componentType), iterator(componentType));
122127
}
@@ -179,6 +184,7 @@ public Collection<? extends Snippet> createValueConstructors(Context context) {
179184
"dict", DICT, "{object(): 'q'}",
180185
"dict:int-str", dict(INT, STR), "{1: 'q'}",
181186
"dict:str-int", dict(STR, INT), "{'q': 1}",
187+
"set", SET, "{object(), 'q', 12}",
182188
"datetime", DATETIME_DATETIME, "import datetime; datetime.datetime.now()",
183189
"date", DATETIME_DATE, "import datetime; datetime.date.today()",
184190
"time", DATETIME_TIME, "import datetime; datetime.datetime.now().time()",

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INT__;
6363
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ITER__;
6464
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
65+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEXT__;
6566
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETITEM__;
6667
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SET__;
6768
import static com.oracle.graal.python.nodes.SpecialMethodNames.__STR__;
@@ -159,6 +160,7 @@
159160
import com.oracle.truffle.api.interop.ArityException;
160161
import com.oracle.truffle.api.interop.InteropLibrary;
161162
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
163+
import com.oracle.truffle.api.interop.StopIterationException;
162164
import com.oracle.truffle.api.interop.TruffleObject;
163165
import com.oracle.truffle.api.interop.UnknownIdentifierException;
164166
import com.oracle.truffle.api.interop.UnsupportedMessageException;
@@ -170,6 +172,8 @@
170172
import com.oracle.truffle.api.nodes.ExplodeLoop;
171173
import com.oracle.truffle.api.nodes.Node;
172174
import com.oracle.truffle.api.object.DynamicObject;
175+
import com.oracle.truffle.api.object.DynamicObjectLibrary;
176+
import com.oracle.truffle.api.object.HiddenKey;
173177
import com.oracle.truffle.api.object.Shape;
174178
import com.oracle.truffle.api.profiles.BranchProfile;
175179
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -2092,4 +2096,64 @@ public static Object getIteratorWithState(PythonAbstractObject self, ThreadState
20922096
throw raise.raise(PythonErrorType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, self);
20932097
}
20942098
}
2099+
2100+
@ExportMessage
2101+
public boolean hasIterator(
2102+
@CachedLibrary("this") PythonObjectLibrary lib) {
2103+
return lib.isIterable(this);
2104+
}
2105+
2106+
@ExportMessage
2107+
public Object getIterator(
2108+
@CachedLibrary("this") PythonObjectLibrary lib) throws UnsupportedMessageException {
2109+
if (lib.isIterable(this)) {
2110+
return lib.getIterator(this);
2111+
} else {
2112+
throw UnsupportedMessageException.create();
2113+
}
2114+
}
2115+
2116+
@ExportMessage
2117+
public boolean isIterator(
2118+
@CachedLibrary("this") PythonObjectLibrary lib) {
2119+
return lib.lookupAttributeOnType(this, __NEXT__) != PNone.NO_VALUE;
2120+
}
2121+
2122+
private static final HiddenKey NEXT_ELEMENT = new HiddenKey("next_element");
2123+
2124+
@ExportMessage
2125+
public boolean hasIteratorNextElement(
2126+
@CachedLibrary("this") InteropLibrary ilib,
2127+
@CachedLibrary("this") PythonObjectLibrary plib,
2128+
@CachedLibrary("this") DynamicObjectLibrary dylib,
2129+
@Exclusive @Cached IsBuiltinClassProfile exceptionProfile) throws UnsupportedMessageException {
2130+
if (ilib.isIterator(this)) {
2131+
Object nextElement = dylib.getOrDefault(this, NEXT_ELEMENT, null);
2132+
if (nextElement != null) {
2133+
return true;
2134+
}
2135+
try {
2136+
nextElement = plib.lookupAndCallSpecialMethod(this, null, __NEXT__);
2137+
dylib.put(this, NEXT_ELEMENT, nextElement);
2138+
return true;
2139+
} catch (PException e) {
2140+
e.expect(PythonBuiltinClassType.StopIteration, exceptionProfile);
2141+
return false;
2142+
}
2143+
}
2144+
throw UnsupportedMessageException.create();
2145+
}
2146+
2147+
@ExportMessage
2148+
public Object getIteratorNextElement(
2149+
@CachedLibrary("this") InteropLibrary ilib,
2150+
@CachedLibrary("this") DynamicObjectLibrary dylib) throws StopIterationException, UnsupportedMessageException {
2151+
if (ilib.hasIteratorNextElement(this)) {
2152+
Object nextElement = dylib.getOrDefault(this, NEXT_ELEMENT, null);
2153+
dylib.put(this, NEXT_ELEMENT, null);
2154+
return nextElement;
2155+
} else {
2156+
throw StopIterationException.create();
2157+
}
2158+
}
20952159
}

0 commit comments

Comments
 (0)