@@ -965,17 +965,43 @@ _PyPegen_check_legacy_stmt(Parser *p, expr_ty name) {
965
965
return 0 ;
966
966
}
967
967
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 ) {
971
984
return RAISE_SYNTAX_ERROR_KNOWN_RANGE (
972
- symbol , conv ,
985
+ conv_token , conv ,
973
986
"f-string: conversion type must come right after the exclamanation mark"
974
987
);
975
988
}
976
- return conv ;
989
+ return result_token_with_metadata ( p , conv , conv_token -> metadata ) ;
977
990
}
978
991
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
+ }
979
1005
980
1006
const char *
981
1007
_PyPegen_get_expr_name (expr_ty e )
@@ -1197,27 +1223,6 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq
1197
1223
1198
1224
// Fstring stuff
1199
1225
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
-
1221
1226
static expr_ty
1222
1227
_PyPegen_decode_fstring_part (Parser * p , int is_raw , expr_ty constant ) {
1223
1228
assert (PyUnicode_CheckExact (constant -> v .Constant .value ));
@@ -1386,19 +1391,20 @@ expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
1386
1391
return _PyAST_Constant (s , kind , tok -> lineno , tok -> col_offset , tok -> end_lineno , tok -> end_col_offset , p -> arena );
1387
1392
}
1388
1393
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 ) {
1392
1397
int conversion_val = -1 ;
1393
1398
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 );
1396
1402
1397
- if (PyUnicode_GET_LENGTH (conversion -> v .Name .id ) > 1 ||
1403
+ if (PyUnicode_GET_LENGTH (conversion_expr -> v .Name .id ) > 1 ||
1398
1404
!(first == 's' || first == 'r' || first == 'a' )) {
1399
- RAISE_SYNTAX_ERROR_KNOWN_LOCATION (conversion ,
1405
+ RAISE_SYNTAX_ERROR_KNOWN_LOCATION (conversion_expr ,
1400
1406
"f-string: invalid conversion character %R: expected 's', 'r', or 'a'" ,
1401
- conversion -> v .Name .id );
1407
+ conversion_expr -> v .Name .id );
1402
1408
return NULL ;
1403
1409
}
1404
1410
@@ -1410,30 +1416,34 @@ expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ex
1410
1416
}
1411
1417
1412
1418
expr_ty formatted_value = _PyAST_FormattedValue (
1413
- expression , conversion_val , format ,
1419
+ expression , conversion_val , format ? ( expr_ty ) format -> result : NULL ,
1414
1420
lineno , col_offset , end_lineno ,
1415
1421
end_col_offset , arena
1416
1422
);
1417
1423
1418
1424
if (debug ) {
1419
1425
/* Find the non whitespace token after the "=" */
1420
1426
int debug_end_line , debug_end_offset ;
1427
+ PyObject * debug_metadata ;
1421
1428
1422
1429
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 ;
1425
1433
}
1426
1434
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 ;
1429
1438
}
1430
1439
else {
1431
1440
debug_end_line = end_lineno ;
1432
1441
debug_end_offset = end_col_offset ;
1442
+ debug_metadata = closing_brace -> metadata ;
1433
1443
}
1434
1444
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 );
1437
1447
if (!debug_text ) {
1438
1448
return NULL ;
1439
1449
}
0 commit comments