@@ -965,17 +965,43 @@ _PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
965965 return 0 ;
966966}
967967
968- expr_ty
969- _PyPegen_check_fstring_conversion (Parser * p , Token * symbol , expr_ty conv ) {
970- if (symbol -> lineno != conv -> lineno || symbol -> end_col_offset != conv -> col_offset ) {
968+ static ResultTokenWithMetadata *
969+ result_token_with_metadata (Parser * p , void * result , PyObject * metadata )
970+ {
971+ ResultTokenWithMetadata * res = _PyArena_Malloc (p -> arena , sizeof (ResultTokenWithMetadata ));
972+ if (res == NULL ) {
973+ return NULL ;
974+ }
975+ res -> metadata = metadata ;
976+ res -> result = result ;
977+ return res ;
978+ }
979+
980+ ResultTokenWithMetadata *
981+ _PyPegen_check_fstring_conversion (Parser * p , Token * conv_token , expr_ty conv )
982+ {
983+ if (conv_token -> lineno != conv -> lineno || conv_token -> end_col_offset != conv -> col_offset ) {
971984 return RAISE_SYNTAX_ERROR_KNOWN_RANGE (
972- symbol , conv ,
985+ conv_token , conv ,
973986 "f-string: conversion type must come right after the exclamanation mark"
974987 );
975988 }
976- return conv ;
989+ return result_token_with_metadata ( p , conv , conv_token -> metadata ) ;
977990}
978991
992+ ResultTokenWithMetadata *
993+ _PyPegen_setup_full_format_spec (Parser * p , Token * colon , asdl_expr_seq * spec , int lineno , int col_offset ,
994+ int end_lineno , int end_col_offset , PyArena * arena )
995+ {
996+ if (!spec ) {
997+ return NULL ;
998+ }
999+ expr_ty res = _PyAST_JoinedStr (spec , lineno , col_offset , end_lineno , end_col_offset , p -> arena );
1000+ if (!res ) {
1001+ return NULL ;
1002+ }
1003+ return result_token_with_metadata (p , res , colon -> metadata );
1004+ }
9791005
9801006const char *
9811007_PyPegen_get_expr_name (expr_ty e )
@@ -1197,27 +1223,6 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq
11971223
11981224// Fstring stuff
11991225
1200- static expr_ty
1201- decode_fstring_buffer (Parser * p , int lineno , int col_offset , int end_lineno ,
1202- int end_col_offset )
1203- {
1204- tokenizer_mode * tok_mode = & (p -> tok -> tok_mode_stack [p -> tok -> tok_mode_stack_index ]);
1205- assert (tok_mode -> last_expr_buffer != NULL );
1206- assert (tok_mode -> last_expr_size >= 0 && tok_mode -> last_expr_end >= 0 );
1207-
1208- PyObject * res = PyUnicode_DecodeUTF8 (
1209- tok_mode -> last_expr_buffer ,
1210- tok_mode -> last_expr_size - tok_mode -> last_expr_end ,
1211- NULL
1212- );
1213- if (!res || _PyArena_AddPyObject (p -> arena , res ) < 0 ) {
1214- Py_XDECREF (res );
1215- return NULL ;
1216- }
1217-
1218- return _PyAST_Constant (res , NULL , lineno , col_offset , end_lineno , end_col_offset , p -> arena );
1219- }
1220-
12211226static expr_ty
12221227_PyPegen_decode_fstring_part (Parser * p , int is_raw , expr_ty constant ) {
12231228 assert (PyUnicode_CheckExact (constant -> v .Constant .value ));
@@ -1386,19 +1391,20 @@ expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
13861391 return _PyAST_Constant (s , kind , tok -> lineno , tok -> col_offset , tok -> end_lineno , tok -> end_col_offset , p -> arena );
13871392}
13881393
1389- expr_ty _PyPegen_formatted_value (Parser * p , expr_ty expression , Token * debug , expr_ty conversion ,
1390- expr_ty format , int lineno , int col_offset , int end_lineno , int end_col_offset ,
1391- PyArena * arena ) {
1394+ expr_ty _PyPegen_formatted_value (Parser * p , expr_ty expression , Token * debug , ResultTokenWithMetadata * conversion ,
1395+ ResultTokenWithMetadata * format , Token * closing_brace , int lineno , int col_offset ,
1396+ int end_lineno , int end_col_offset , PyArena * arena ) {
13921397 int conversion_val = -1 ;
13931398 if (conversion != NULL ) {
1394- assert (conversion -> kind == Name_kind );
1395- Py_UCS4 first = PyUnicode_READ_CHAR (conversion -> v .Name .id , 0 );
1399+ expr_ty conversion_expr = (expr_ty ) conversion -> result ;
1400+ assert (conversion_expr -> kind == Name_kind );
1401+ Py_UCS4 first = PyUnicode_READ_CHAR (conversion_expr -> v .Name .id , 0 );
13961402
1397- if (PyUnicode_GET_LENGTH (conversion -> v .Name .id ) > 1 ||
1403+ if (PyUnicode_GET_LENGTH (conversion_expr -> v .Name .id ) > 1 ||
13981404 !(first == 's' || first == 'r' || first == 'a' )) {
1399- RAISE_SYNTAX_ERROR_KNOWN_LOCATION (conversion ,
1405+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION (conversion_expr ,
14001406 "f-string: invalid conversion character %R: expected 's', 'r', or 'a'" ,
1401- conversion -> v .Name .id );
1407+ conversion_expr -> v .Name .id );
14021408 return NULL ;
14031409 }
14041410
@@ -1410,30 +1416,34 @@ expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ex
14101416 }
14111417
14121418 expr_ty formatted_value = _PyAST_FormattedValue (
1413- expression , conversion_val , format ,
1419+ expression , conversion_val , format ? ( expr_ty ) format -> result : NULL ,
14141420 lineno , col_offset , end_lineno ,
14151421 end_col_offset , arena
14161422 );
14171423
14181424 if (debug ) {
14191425 /* Find the non whitespace token after the "=" */
14201426 int debug_end_line , debug_end_offset ;
1427+ PyObject * debug_metadata ;
14211428
14221429 if (conversion ) {
1423- debug_end_line = conversion -> lineno ;
1424- debug_end_offset = conversion -> col_offset ;
1430+ debug_end_line = ((expr_ty ) conversion -> result )-> lineno ;
1431+ debug_end_offset = ((expr_ty ) conversion -> result )-> col_offset ;
1432+ debug_metadata = conversion -> metadata ;
14251433 }
14261434 else if (format ) {
1427- debug_end_line = format -> lineno ;
1428- debug_end_offset = format -> col_offset + 1 ; // HACK: ??
1435+ debug_end_line = ((expr_ty ) format -> result )-> lineno ;
1436+ debug_end_offset = ((expr_ty ) format -> result )-> col_offset + 1 ;
1437+ debug_metadata = format -> metadata ;
14291438 }
14301439 else {
14311440 debug_end_line = end_lineno ;
14321441 debug_end_offset = end_col_offset ;
1442+ debug_metadata = closing_brace -> metadata ;
14331443 }
14341444
1435- expr_ty debug_text = decode_fstring_buffer ( p , lineno , col_offset + 1 ,
1436- debug_end_line , debug_end_offset - 1 );
1445+ expr_ty debug_text = _PyAST_Constant ( debug_metadata , NULL , lineno , col_offset + 1 , debug_end_line ,
1446+ debug_end_offset - 1 , p -> arena );
14371447 if (!debug_text ) {
14381448 return NULL ;
14391449 }
0 commit comments