Skip to content

Commit 2ecb3ef

Browse files
committed
[GR-28565] [GR-32546] Implement must_advance for findall searches and add support for fullmatch.
PullRequest: graalpython/2106
2 parents 720b1ea + 792e2d3 commit 2ecb3ef

File tree

2 files changed

+81
-67
lines changed

2 files changed

+81
-67
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.oracle.graal.python.nodes.PNodeWithRaiseAndIndirectCall;
5858
import com.oracle.graal.python.nodes.call.CallNode;
5959
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
60+
import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode;
6061
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
6162
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
6263
import com.oracle.graal.python.nodes.util.CannotCastException;
@@ -65,6 +66,7 @@
6566
import com.oracle.graal.python.runtime.PythonContext;
6667
import com.oracle.graal.python.runtime.PythonOptions;
6768
import com.oracle.graal.python.runtime.exception.PException;
69+
import com.oracle.graal.python.util.PythonUtils;
6870
import com.oracle.truffle.api.CompilerDirectives;
6971
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
7072
import com.oracle.truffle.api.dsl.Cached;
@@ -80,6 +82,7 @@
8082
import com.oracle.truffle.api.interop.UnsupportedTypeException;
8183
import com.oracle.truffle.api.library.CachedLibrary;
8284
import com.oracle.truffle.api.profiles.BranchProfile;
85+
import com.oracle.truffle.api.profiles.ConditionProfile;
8386
import com.oracle.truffle.api.source.Source;
8487
import com.oracle.truffle.api.source.SourceSection;
8588

@@ -98,7 +101,7 @@ public void initialize(Python3Core core) {
98101

99102
abstract static class ToRegexSourceNode extends PNodeWithRaiseAndIndirectCall {
100103

101-
public abstract Source execute(VirtualFrame frame, Object pattern, String flags);
104+
public abstract Source execute(VirtualFrame frame, Object pattern, String flags, String options);
102105

103106
@TruffleBoundary
104107
private static String decodeLatin1(byte[] bytes, int length) {
@@ -117,18 +120,24 @@ private static Source constructRegexSource(String options, String pattern, Strin
117120
}
118121

119122
@Specialization
120-
protected Source doString(String pattern, String flags) {
121-
String options = "Flavor=PythonStr,Encoding=UTF-16";
122-
return constructRegexSource(options, pattern, flags);
123+
protected Source doString(String pattern, String flags, String options,
124+
@Cached ConditionProfile nonEmptyOptionsProfile) {
125+
StringBuilder allOptions = PythonUtils.newStringBuilder("Flavor=PythonStr,Encoding=UTF-16");
126+
if (nonEmptyOptionsProfile.profile(!options.isEmpty())) {
127+
PythonUtils.append(allOptions, ',');
128+
PythonUtils.append(allOptions, options);
129+
}
130+
return constructRegexSource(PythonUtils.sbToString(allOptions), pattern, flags);
123131
}
124132

125133
@Specialization(limit = "3")
126-
protected Source doGeneric(VirtualFrame frame, Object pattern, String flags,
134+
protected Source doGeneric(VirtualFrame frame, Object pattern, String flags, String options,
135+
@Cached ConditionProfile nonEmptyOptionsProfile,
127136
@Cached CastToJavaStringNode cast,
128137
@CachedLibrary("pattern") PythonBufferAcquireLibrary bufferAcquireLib,
129138
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) {
130139
try {
131-
return doString(cast.execute(pattern), flags);
140+
return doString(cast.execute(pattern), flags, options, nonEmptyOptionsProfile);
132141
} catch (CannotCastException ce) {
133142
Object buffer;
134143
try {
@@ -137,36 +146,42 @@ protected Source doGeneric(VirtualFrame frame, Object pattern, String flags,
137146
throw raise(TypeError, "expected string or bytes-like object");
138147
}
139148
try {
140-
String options = "Flavor=PythonBytes,Encoding=BYTES";
149+
StringBuilder allOptions = PythonUtils.newStringBuilder("Flavor=PythonBytes,Encoding=BYTES");
150+
if (nonEmptyOptionsProfile.profile(!options.isEmpty())) {
151+
PythonUtils.append(allOptions, ',');
152+
PythonUtils.append(allOptions, options);
153+
}
141154
byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
142155
int bytesLen = bufferLib.getBufferLength(buffer);
143156
String patternStr = decodeLatin1(bytes, bytesLen);
144-
return constructRegexSource(options, patternStr, flags);
157+
return constructRegexSource(PythonUtils.sbToString(allOptions), patternStr, flags);
145158
} finally {
146159
bufferLib.release(buffer, frame, this);
147160
}
148161
}
149162
}
150163
}
151164

152-
@Builtin(name = "tregex_compile_internal", minNumOfPositionalArgs = 3)
165+
@Builtin(name = "tregex_compile_internal", minNumOfPositionalArgs = 4)
153166
@TypeSystemReference(PythonArithmeticTypes.class)
154167
@GenerateNodeFactory
155-
abstract static class TRegexCallCompile extends PythonTernaryBuiltinNode {
168+
abstract static class TRegexCallCompile extends PythonQuaternaryBuiltinNode {
156169

157170
@Specialization
158-
Object call(VirtualFrame frame, Object pattern, Object flags, PFunction fallbackCompiler,
171+
Object call(VirtualFrame frame, Object pattern, Object flags, Object options, PFunction fallbackCompiler,
159172
@Cached BranchProfile potentialSyntaxError,
160173
@Cached BranchProfile syntaxError,
161174
@Cached BranchProfile unsupportedRegexError,
162-
@Cached CastToJavaStringNode toStringNode,
175+
@Cached CastToJavaStringNode flagsToStringNode,
176+
@Cached CastToJavaStringNode optionsToStringNode,
163177
@Cached ToRegexSourceNode toRegexSourceNode,
164178
@Cached CallNode callFallbackCompilerNode,
165179
@CachedLibrary(limit = "2") InteropLibrary exceptionLib,
166180
@CachedLibrary(limit = "2") InteropLibrary compiledRegexLib) {
167181
try {
168-
String flagsStr = toStringNode.execute(flags);
169-
Source regexSource = toRegexSourceNode.execute(frame, pattern, flagsStr);
182+
String flagsStr = flagsToStringNode.execute(flags);
183+
String optionsStr = optionsToStringNode.execute(options);
184+
Source regexSource = toRegexSourceNode.execute(frame, pattern, flagsStr, optionsStr);
170185
Object compiledRegex = getContext().getEnv().parseInternal(regexSource).call();
171186
if (compiledRegexLib.isNull(compiledRegex)) {
172187
unsupportedRegexError.enter();

0 commit comments

Comments
 (0)