131
131
name = PythonLanguage .NAME , //
132
132
implementationName = PythonLanguage .IMPLEMENTATION_NAME , //
133
133
version = PythonLanguage .VERSION , //
134
- characterMimeTypes = {PythonLanguage .MIME_TYPE ,
135
- PythonLanguage .MIME_TYPE_COMPILE0 , PythonLanguage .MIME_TYPE_COMPILE1 , PythonLanguage .MIME_TYPE_COMPILE2 ,
136
- PythonLanguage .MIME_TYPE_EVAL0 , PythonLanguage .MIME_TYPE_EVAL1 , PythonLanguage .MIME_TYPE_EVAL2 }, //
134
+ characterMimeTypes = {PythonLanguage .MIME_TYPE , "text/x-python-eval-0-0" , "text/x-python-eval-0-1" , "text/x-python-eval-1-0" , "text/x-python-eval-1-1" , "text/x-python-eval-2-0" ,
135
+ "text/x-python-eval-2-1" , "text/x-python-compile-0-0" , "text/x-python-compile-0-1" , "text/x-python-compile-1-0" , "text/x-python-compile-1-1" ,
136
+ "text/x-python-compile-2-0" ,
137
+ "text/x-python-compile-2-1" }, //
137
138
byteMimeTypes = {PythonLanguage .MIME_TYPE_BYTECODE }, //
138
139
defaultMimeType = PythonLanguage .MIME_TYPE , //
139
140
dependentLanguages = {"nfi" , "llvm" }, //
@@ -206,14 +207,20 @@ public final class PythonLanguage extends TruffleLanguage<PythonContext> {
206
207
public static final int API_VERSION = 1013 ;
207
208
208
209
public static final String MIME_TYPE = "text/x-python" ;
209
- static final String MIME_TYPE_COMPILE0 = "text/x-python-compile0" ;
210
- static final String MIME_TYPE_COMPILE1 = "text/x-python-compile1" ;
211
- static final String MIME_TYPE_COMPILE2 = "text/x-python-compile2" ;
212
- static final String [] MIME_TYPE_COMPILE = {PythonLanguage .MIME_TYPE_COMPILE0 , PythonLanguage .MIME_TYPE_COMPILE1 , PythonLanguage .MIME_TYPE_COMPILE2 };
213
- static final String [] MIME_TYPE_EVAL = {PythonLanguage .MIME_TYPE_EVAL0 , PythonLanguage .MIME_TYPE_EVAL1 , PythonLanguage .MIME_TYPE_EVAL2 };
214
- static final String MIME_TYPE_EVAL0 = "text/x-python-eval0" ;
215
- static final String MIME_TYPE_EVAL1 = "text/x-python-eval1" ;
216
- static final String MIME_TYPE_EVAL2 = "text/x-python-eval2" ;
210
+
211
+ // the syntax for mime types is as follows
212
+ // <mime> ::= "text/x-python-" <kind> "-" <optlevel> "-" <future_annotations>
213
+ // <kind> ::= "compile" | "eval"
214
+ // <optlevel> ::= "0" | "1" | "2"
215
+ // <future_annotations> ::= "0" | "1"
216
+ static final String MIME_PREFIX = MIME_TYPE + "-" ;
217
+ static final String MIME_KIND_COMPILE = "compile" ;
218
+ static final String MIME_KIND_EVAL = "eval" ;
219
+ static final int MIME_KIND_IDX = 0 ;
220
+ static final int MIME_OPTLEVEL_IDX = 1 ;
221
+ static final int MIME_FUTURE_ANNOTATIONS_IDX = 2 ;
222
+ static final int MIME_FIELD_COUNT = 3 ;
223
+
217
224
public static final String MIME_TYPE_BYTECODE = "application/x-python-bytecode" ;
218
225
219
226
public static final TruffleString [] T_DEFAULT_PYTHON_EXTENSIONS = new TruffleString []{T_PY_EXTENSION , tsLiteral (".pyc" )};
@@ -388,23 +395,28 @@ protected void initializeContext(PythonContext context) {
388
395
context .initialize ();
389
396
}
390
397
391
- public static String getCompileMimeType (int optimize ) {
398
+ public static String getCompileMimeType (int optimize , boolean futureAnnotations ) {
399
+ String futureAnnField = futureAnnotations ? "1" : "0" ;
400
+ String compile = MIME_PREFIX + "compile-" ;
392
401
if (optimize <= 0 ) {
393
- return MIME_TYPE_COMPILE0 ;
402
+ return compile + "0-" + futureAnnField ;
394
403
} else if (optimize == 1 ) {
395
- return MIME_TYPE_COMPILE1 ;
404
+ return compile + "1-" + futureAnnField ;
396
405
} else {
397
- return MIME_TYPE_COMPILE2 ;
406
+ return compile + "2-" + futureAnnField ;
398
407
}
399
408
}
400
409
401
- public static String getEvalMimeType (int optimize ) {
410
+ // TODO inherit other implemented
411
+ public static String getEvalMimeType (int optimize , boolean futureAnnotations ) {
412
+ String futureAnnField = futureAnnotations ? "1" : "0" ;
413
+ String eval = MIME_PREFIX + "eval-" ;
402
414
if (optimize <= 0 ) {
403
- return MIME_TYPE_EVAL0 ;
415
+ return eval + "0-" + futureAnnField ;
404
416
} else if (optimize == 1 ) {
405
- return MIME_TYPE_EVAL1 ;
417
+ return eval + "1-" + futureAnnField ;
406
418
} else {
407
- return MIME_TYPE_EVAL2 ;
419
+ return eval + "2-" + futureAnnField ;
408
420
}
409
421
}
410
422
@@ -417,7 +429,7 @@ protected CallTarget parse(ParsingRequest request) {
417
429
throw new IllegalStateException ("parse with arguments not allowed for interactive sources" );
418
430
}
419
431
InputType inputType = source .isInteractive () ? InputType .SINGLE : InputType .FILE ;
420
- return parse (context , source , inputType , true , 0 , source .isInteractive (), request .getArgumentNames ());
432
+ return parse (context , source , inputType , true , 0 , source .isInteractive (), request .getArgumentNames (), false );
421
433
}
422
434
if (!request .getArgumentNames ().isEmpty ()) {
423
435
throw new IllegalStateException ("parse with arguments is only allowed for " + MIME_TYPE + " mime type" );
@@ -452,19 +464,38 @@ protected CallTarget parse(ParsingRequest request) {
452
464
PBytecodeRootNode rootNode = PBytecodeRootNode .create (this , code , source );
453
465
return PythonUtils .getOrCreateCallTarget (rootNode );
454
466
}
455
- for ( int optimize = 0 ; optimize < MIME_TYPE_EVAL . length ; optimize ++) {
456
- if ( MIME_TYPE_EVAL [ optimize ]. equals ( source .getMimeType ())) {
457
- assert ! source . isInteractive ( );
458
- return parse ( context , source , InputType . EVAL , false , optimize , false , null );
459
- }
467
+
468
+ String mime = source .getMimeType ();
469
+ String prefix = mime . substring ( 0 , MIME_PREFIX . length () );
470
+ if (! prefix . equals ( MIME_PREFIX )) {
471
+ throw CompilerDirectives . shouldNotReachHere ( "unknown mime type: " + source . getMimeType ());
460
472
}
461
- for (int optimize = 0 ; optimize < MIME_TYPE_COMPILE .length ; optimize ++) {
462
- if (MIME_TYPE_COMPILE [optimize ].equals (source .getMimeType ())) {
463
- assert !source .isInteractive ();
464
- return parse (context , source , InputType .FILE , false , optimize , false , null );
465
- }
473
+ String [] fields = mime .substring (MIME_PREFIX .length ()).split ("-" );
474
+ if (fields .length != MIME_FIELD_COUNT ) {
475
+ throw CompilerDirectives .shouldNotReachHere ("unknown mime type: " + source .getMimeType ());
476
+ }
477
+ String kind = fields [MIME_KIND_IDX ];
478
+ InputType type ;
479
+ if (kind .equals (MIME_KIND_COMPILE )) {
480
+ type = InputType .FILE ;
481
+ } else if (kind .equals (MIME_KIND_EVAL )) {
482
+ type = InputType .EVAL ;
483
+ } else {
484
+ throw CompilerDirectives .shouldNotReachHere ("unknown mime type: " + source .getMimeType ());
485
+ }
486
+ int optimize ;
487
+ int futureAnnotations ;
488
+ try {
489
+ optimize = Integer .parseInt (fields [MIME_OPTLEVEL_IDX ]);
490
+ futureAnnotations = Integer .parseInt (fields [MIME_FUTURE_ANNOTATIONS_IDX ]);
491
+ } catch (NumberFormatException e ) {
492
+ throw CompilerDirectives .shouldNotReachHere ("unknown mime type: " + source .getMimeType ());
493
+ }
494
+ if (0 > optimize || optimize > 2 || 0 > futureAnnotations || futureAnnotations > 2 ) {
495
+ throw CompilerDirectives .shouldNotReachHere ("unknown mime type: " + source .getMimeType ());
466
496
}
467
- throw CompilerDirectives .shouldNotReachHere ("unknown mime type: " + source .getMimeType ());
497
+ assert !source .isInteractive ();
498
+ return parse (context , source , type , false , optimize , false , null , futureAnnotations == 1 );
468
499
}
469
500
470
501
private static Source tryLoadSource (PythonContext context , CodeUnit code , boolean internal , String path ) {
@@ -475,13 +506,14 @@ private static Source tryLoadSource(PythonContext context, CodeUnit code, boolea
475
506
}
476
507
}
477
508
478
- public RootCallTarget parse (PythonContext context , Source source , InputType type , boolean topLevel , int optimize , boolean interactiveTerminal , List <String > argumentNames ) {
509
+ public RootCallTarget parse (PythonContext context , Source source , InputType type , boolean topLevel , int optimize , boolean interactiveTerminal , List <String > argumentNames ,
510
+ boolean futureAnnotations ) {
479
511
RaisePythonExceptionErrorCallback errorCb = new RaisePythonExceptionErrorCallback (source , PythonOptions .isPExceptionWithJavaStacktrace (this ));
480
512
try {
481
513
Parser parser = Compiler .createParser (source .getCharacters ().toString (), errorCb , type , interactiveTerminal );
482
514
ModTy mod = (ModTy ) parser .parse ();
483
515
assert mod != null ;
484
- return compileForBytecodeInterpreter (context , mod , source , topLevel , optimize , argumentNames , errorCb );
516
+ return compileForBytecodeInterpreter (context , mod , source , topLevel , optimize , argumentNames , errorCb , futureAnnotations );
485
517
} catch (PException e ) {
486
518
if (topLevel ) {
487
519
PythonUtils .getOrCreateCallTarget (new TopLevelExceptionHandler (this , e )).call ();
@@ -492,7 +524,7 @@ public RootCallTarget parse(PythonContext context, Source source, InputType type
492
524
493
525
@ TruffleBoundary
494
526
public RootCallTarget compileForBytecodeInterpreter (PythonContext context , ModTy mod , Source source , boolean topLevel , int optimize , List <String > argumentNames ,
495
- RaisePythonExceptionErrorCallback errorCallback ) {
527
+ RaisePythonExceptionErrorCallback errorCallback , boolean futureAnnotations ) {
496
528
RaisePythonExceptionErrorCallback errorCb = errorCallback ;
497
529
if (errorCb == null ) {
498
530
errorCb = new RaisePythonExceptionErrorCallback (source , PythonOptions .isPExceptionWithJavaStacktrace (this ));
@@ -503,7 +535,7 @@ public RootCallTarget compileForBytecodeInterpreter(PythonContext context, ModTy
503
535
if (hasArguments ) {
504
536
mod = transformASTForExecutionWithArguments (argumentNames , mod );
505
537
}
506
- CompilationUnit cu = compiler .compile (mod , EnumSet .noneOf (Compiler .Flags .class ), optimize );
538
+ CompilationUnit cu = compiler .compile (mod , EnumSet .noneOf (Compiler .Flags .class ), optimize , futureAnnotations );
507
539
CodeUnit co = cu .assemble ();
508
540
RootNode rootNode = PBytecodeRootNode .create (this , co , source , errorCb );
509
541
if (topLevel ) {
@@ -588,7 +620,7 @@ public String getName() {
588
620
@ Override
589
621
public ExecutableNode parse (InlineParsingRequest request ) {
590
622
PythonContext context = PythonContext .get (null );
591
- RootCallTarget callTarget = parse (context , request .getSource (), InputType .EVAL , false , 0 , false , null );
623
+ RootCallTarget callTarget = parse (context , request .getSource (), InputType .EVAL , false , 0 , false , null , false );
592
624
return new ExecutableNode (this ) {
593
625
@ Child private GilNode gilNode = GilNode .create ();
594
626
@ Child private GenericInvokeNode invokeNode = GenericInvokeNode .create ();
0 commit comments