42
42
43
43
import static com .oracle .graal .python .runtime .exception .PythonErrorType .RuntimeError ;
44
44
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
45
+ import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
45
46
46
47
import java .io .UnsupportedEncodingException ;
47
48
import java .util .List ;
48
- import java .util .regex .Matcher ;
49
49
import java .util .regex .Pattern ;
50
50
51
51
import com .oracle .graal .python .builtins .Builtin ;
52
52
import com .oracle .graal .python .builtins .CoreFunctions ;
53
53
import com .oracle .graal .python .builtins .PythonBuiltins ;
54
+ import com .oracle .graal .python .builtins .objects .bytes .BytesNodes ;
54
55
import com .oracle .graal .python .builtins .objects .bytes .BytesUtils ;
55
56
import com .oracle .graal .python .builtins .objects .bytes .PIBytesLike ;
56
57
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
58
+ import com .oracle .graal .python .builtins .objects .memoryview .PMemoryView ;
57
59
import com .oracle .graal .python .builtins .objects .str .PString ;
58
60
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
59
61
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
78
80
import com .oracle .truffle .api .interop .UnsupportedTypeException ;
79
81
import com .oracle .truffle .api .nodes .Node ;
80
82
import com .oracle .truffle .api .profiles .BranchProfile ;
83
+ import com .oracle .truffle .regex .RegexSyntaxException ;
81
84
82
85
@ CoreFunctions (defineModule = "_sre" )
83
86
public class SREModuleBuiltins extends PythonBuiltins {
@@ -86,106 +89,6 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
86
89
return SREModuleBuiltinsFactory .getFactories ();
87
90
}
88
91
89
- @ Builtin (name = "tregex_preprocess_for_verbose" , fixedNumOfPositionalArgs = 1 )
90
- @ GenerateNodeFactory
91
- abstract static class TRegexPreprocessVerboseNode extends PythonUnaryBuiltinNode {
92
-
93
- @ Specialization
94
- Object run (PString str ) {
95
- return run (str .getValue ());
96
- }
97
-
98
- @ Specialization
99
- Object run (String str ) {
100
- return replaceAll (str );
101
- }
102
-
103
- /**
104
- * removes comments and whitespaces if they are not in a character class
105
- */
106
- @ TruffleBoundary (transferToInterpreterOnException = false , allowInlining = true )
107
- private static String replaceAll (String r ) {
108
- StringBuffer sb = new StringBuffer (r );
109
- int charclassNestingLevel = 0 ;
110
- boolean inComment = false ;
111
- for (int i = 0 ; i < sb .length ();) {
112
- char c = sb .charAt (i );
113
- if (c == '[' && !inComment ) {
114
- charclassNestingLevel ++;
115
- } else if (c == ']' && !inComment ) {
116
- charclassNestingLevel --;
117
- } else if (c == '#' && charclassNestingLevel == 0 ) {
118
- inComment = true ;
119
- } else if (c == '\n' && inComment ) {
120
- inComment = false ;
121
- }
122
- if (inComment || (Character .isWhitespace (c ) && charclassNestingLevel == 0 )) {
123
- sb .deleteCharAt (i );
124
- } else {
125
- i ++;
126
- }
127
- }
128
-
129
- for (int idx = sb .indexOf ("\\ Z" ); idx != -1 ; idx = sb .indexOf ("\\ Z" , idx + 2 )) {
130
- sb .replace (idx , idx + 2 , "$" );
131
- }
132
-
133
- return sb .toString ();
134
- }
135
-
136
- @ Fallback
137
- Object run (Object o ) {
138
- throw raise (PythonErrorType .TypeError , "expected string, not %p" , o );
139
- }
140
-
141
- }
142
-
143
- @ Builtin (name = "tregex_preprocess_default" , fixedNumOfPositionalArgs = 1 )
144
- @ GenerateNodeFactory
145
- abstract static class TRegexPreprocessDefaultNode extends PythonUnaryBuiltinNode {
146
- @ CompilationFinal private Pattern namedCaptGroupPattern ;
147
-
148
- @ Specialization
149
- Object run (PString str ) {
150
- return run (str .getValue ());
151
- }
152
-
153
- @ Specialization
154
- Object run (String str ) {
155
- if (namedCaptGroupPattern == null ) {
156
- CompilerDirectives .transferToInterpreterAndInvalidate ();
157
- namedCaptGroupPattern = Pattern .compile ("\\ ?P\\ <(?<GRPNAME>\\ w*)\\ >" );
158
- }
159
- return replaceAll (str );
160
- }
161
-
162
- /**
163
- * replaces named capturing groups {@code ?P<name>} by {@code ?<name>} and replaces
164
- * end-of-string {@code \Z} by {@code $}.
165
- */
166
- @ TruffleBoundary (transferToInterpreterOnException = false , allowInlining = true )
167
- private String replaceAll (String r ) {
168
- Matcher matcher0 = namedCaptGroupPattern .matcher (r );
169
- StringBuffer sb = new StringBuffer ();
170
- while (matcher0 .find ()) {
171
- matcher0 .appendReplacement (sb , "?<" + matcher0 .group ("GRPNAME" ) + ">" );
172
- }
173
- matcher0 .appendTail (sb );
174
-
175
- for (int idx = sb .indexOf ("\\ Z" ); idx != -1 ; idx = sb .indexOf ("\\ Z" , idx + 2 )) {
176
- sb .replace (idx , idx + 2 , "$" );
177
- }
178
-
179
- return sb .toString ();
180
- }
181
-
182
- @ Fallback
183
- Object run (Object o ) {
184
- throw raise (PythonErrorType .TypeError , "expected string, not %p" , o );
185
- }
186
-
187
- }
188
-
189
92
/**
190
93
* Replaces any <it>quoted</it> escape sequence like {@code "\\n"} (two characters; backslash +
191
94
* 'n') by its single character like {@code "\n"} (one character; newline).
@@ -195,6 +98,7 @@ Object run(Object o) {
195
98
abstract static class ProcessEscapeSequences extends PythonUnaryBuiltinNode {
196
99
197
100
@ Child private SequenceStorageNodes .ToByteArrayNode toByteArrayNode ;
101
+ @ Child private BytesNodes .ToBytesNode toBytesNode ;
198
102
199
103
@ CompilationFinal private Pattern namedCaptGroupPattern ;
200
104
@@ -222,6 +126,15 @@ Object run(PIBytesLike str) {
222
126
return str ;
223
127
}
224
128
129
+ @ Specialization
130
+ Object run (PMemoryView memoryView ) {
131
+ byte [] bytes = doBytes (getToBytesNode ().execute (memoryView ));
132
+ if (bytes != null ) {
133
+ return factory ().createByteArray (bytes );
134
+ }
135
+ return memoryView ;
136
+ }
137
+
225
138
@ TruffleBoundary (transferToInterpreterOnException = false , allowInlining = true )
226
139
private byte [] doBytes (byte [] str ) {
227
140
try {
@@ -255,47 +168,72 @@ private SequenceStorageNodes.ToByteArrayNode getToByteArrayNode() {
255
168
return toByteArrayNode ;
256
169
}
257
170
171
+ private BytesNodes .ToBytesNode getToBytesNode () {
172
+ if (toBytesNode == null ) {
173
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
174
+ toBytesNode = insert (BytesNodes .ToBytesNode .create ());
175
+ }
176
+ return toBytesNode ;
177
+ }
258
178
}
259
179
260
- @ Builtin (name = "tregex_call_safe " , fixedNumOfPositionalArgs = 3 )
180
+ @ Builtin (name = "tregex_call_compile " , fixedNumOfPositionalArgs = 3 )
261
181
@ TypeSystemReference (PythonArithmeticTypes .class )
262
182
@ GenerateNodeFactory
263
- abstract static class TRegexCallSafe extends PythonBuiltinNode {
183
+ abstract static class TRegexCallCompile extends PythonBuiltinNode {
264
184
265
- private Object doIt (TruffleObject callable , String arg1 , Object arg2 ,
266
- BranchProfile runtimeError ,
267
- BranchProfile typeError , Node invokeNode ) {
185
+ @ Specialization (guards = "isForeignObject(callable)" )
186
+ Object call (TruffleObject callable , Object arg1 , Object arg2 ,
187
+ @ Cached ("create()" ) BranchProfile syntaxError ,
188
+ @ Cached ("create()" ) BranchProfile typeError ,
189
+ @ Cached ("createExecute()" ) Node invokeNode ) {
268
190
try {
269
191
return ForeignAccess .sendExecute (invokeNode , callable , new Object []{arg1 , arg2 });
270
192
} catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e ) {
271
193
typeError .enter ();
272
194
throw raise (TypeError , "%s" , e );
273
- } catch (RuntimeException e ) {
274
- runtimeError .enter ();
275
- throw raise (RuntimeError , "%s" , e );
195
+ } catch (RegexSyntaxException e ) {
196
+ syntaxError .enter ();
197
+ if (e .getPosition () == -1 ) {
198
+ throw raise (ValueError , "%s" , e .getReason ());
199
+ } else {
200
+ throw raise (ValueError , "%s at position %d" , e .getReason (), e .getPosition ());
201
+ }
276
202
}
277
203
}
278
204
279
- @ Specialization (guards = "isForeignObject(callable)" )
280
- Object call (TruffleObject callable , String arg1 , String arg2 ,
281
- @ Cached ("create()" ) BranchProfile runtimeError ,
282
- @ Cached ("create()" ) BranchProfile typeError ,
283
- @ Cached ("createExecute()" ) Node invokeNode ) {
284
- return doIt (callable , arg1 , arg2 , runtimeError , typeError , invokeNode );
205
+ @ SuppressWarnings ("unused" )
206
+ @ Fallback
207
+ Object call (Object callable , Object arg1 , Object arg2 ) {
208
+ throw raise (RuntimeError , "invalid arguments passed to tregex_call_compile" );
209
+ }
210
+
211
+ protected static Node createExecute () {
212
+ return Message .EXECUTE .createNode ();
285
213
}
214
+ }
215
+
216
+ @ Builtin (name = "tregex_call_exec" , fixedNumOfPositionalArgs = 3 )
217
+ @ TypeSystemReference (PythonArithmeticTypes .class )
218
+ @ GenerateNodeFactory
219
+ abstract static class TRegexCallExec extends PythonBuiltinNode {
286
220
287
221
@ Specialization (guards = "isForeignObject(callable)" )
288
- Object call (TruffleObject callable , String arg1 , int arg2 ,
289
- @ Cached ("create()" ) BranchProfile runtimeError ,
222
+ Object call (TruffleObject callable , Object arg1 , Number arg2 ,
290
223
@ Cached ("create()" ) BranchProfile typeError ,
291
224
@ Cached ("createExecute()" ) Node invokeNode ) {
292
- return doIt (callable , arg1 , arg2 , runtimeError , typeError , invokeNode );
225
+ try {
226
+ return ForeignAccess .sendExecute (invokeNode , callable , new Object []{arg1 , arg2 });
227
+ } catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e ) {
228
+ typeError .enter ();
229
+ throw raise (TypeError , "%s" , e );
230
+ }
293
231
}
294
232
295
233
@ SuppressWarnings ("unused" )
296
234
@ Fallback
297
235
Object call (Object callable , Object arg1 , Object arg2 ) {
298
- throw raise (RuntimeError );
236
+ throw raise (RuntimeError , "invalid arguments passed to tregex_call_exec" );
299
237
}
300
238
301
239
protected static Node createExecute () {
0 commit comments