@@ -282,21 +282,61 @@ static bool cpython_c_tuple_is_const(py_parse_node_t pn) {
282
282
return true;
283
283
}
284
284
285
- static void cpython_c_tuple_emit_const (compiler_t * comp , py_parse_node_t pn ) {
285
+ static void cpython_c_print_quoted_str (vstr_t * vstr , qstr qstr , bool bytes ) {
286
+ const char * str = qstr_str (qstr );
287
+ int len = strlen (str );
288
+ bool has_single_quote = false;
289
+ bool has_double_quote = false;
290
+ for (int i = 0 ; i < len ; i ++ ) {
291
+ if (str [i ] == '\'' ) {
292
+ has_single_quote = true;
293
+ } else if (str [i ] == '"' ) {
294
+ has_double_quote = true;
295
+ }
296
+ }
297
+ if (bytes ) {
298
+ vstr_printf (vstr , "b" );
299
+ }
300
+ bool quote_single = false;
301
+ if (has_single_quote && !has_double_quote ) {
302
+ vstr_printf (vstr , "\"" );
303
+ } else {
304
+ quote_single = true;
305
+ vstr_printf (vstr , "'" );
306
+ }
307
+ for (int i = 0 ; i < len ; i ++ ) {
308
+ if (str [i ] == '\n' ) {
309
+ vstr_printf (vstr , "\\n" );
310
+ } else if (str [i ] == '\\' ) {
311
+ vstr_printf (vstr , "\\\\" );
312
+ } else if (str [i ] == '\'' && quote_single ) {
313
+ vstr_printf (vstr , "\\'" );
314
+ } else {
315
+ vstr_printf (vstr , "%c" , str [i ]);
316
+ }
317
+ }
318
+ if (has_single_quote && !has_double_quote ) {
319
+ vstr_printf (vstr , "\"" );
320
+ } else {
321
+ vstr_printf (vstr , "'" );
322
+ }
323
+ }
324
+
325
+ static void cpython_c_tuple_emit_const (compiler_t * comp , py_parse_node_t pn , vstr_t * vstr ) {
286
326
assert (PY_PARSE_NODE_IS_LEAF (pn ));
287
327
int arg = PY_PARSE_NODE_LEAF_ARG (pn );
288
328
switch (PY_PARSE_NODE_LEAF_KIND (pn )) {
289
329
case PY_PARSE_NODE_ID : assert (0 );
290
- case PY_PARSE_NODE_SMALL_INT : EMIT ( load_const_verbatim_int , arg ); break ;
291
- case PY_PARSE_NODE_INTEGER : EMIT ( load_const_verbatim_str , qstr_str (arg )); break ;
292
- case PY_PARSE_NODE_DECIMAL : EMIT ( load_const_verbatim_str , qstr_str (arg )); break ;
293
- case PY_PARSE_NODE_STRING : EMIT ( load_const_verbatim_quoted_str , arg , false); break ;
294
- case PY_PARSE_NODE_BYTES : EMIT ( load_const_verbatim_quoted_str , arg , true); break ;
330
+ case PY_PARSE_NODE_SMALL_INT : vstr_printf ( vstr , "%d" , arg ); break ;
331
+ case PY_PARSE_NODE_INTEGER : vstr_printf ( vstr , "%s" , qstr_str (arg )); break ;
332
+ case PY_PARSE_NODE_DECIMAL : vstr_printf ( vstr , "%s" , qstr_str (arg )); break ;
333
+ case PY_PARSE_NODE_STRING : cpython_c_print_quoted_str ( vstr , arg , false); break ;
334
+ case PY_PARSE_NODE_BYTES : cpython_c_print_quoted_str ( vstr , arg , true); break ;
295
335
case PY_PARSE_NODE_TOKEN :
296
336
switch (arg ) {
297
- case PY_TOKEN_KW_FALSE : EMIT ( load_const_verbatim_str , "False" ); break ;
298
- case PY_TOKEN_KW_NONE : EMIT ( load_const_verbatim_str , "None" ); break ;
299
- case PY_TOKEN_KW_TRUE : EMIT ( load_const_verbatim_str , "True" ); break ;
337
+ case PY_TOKEN_KW_FALSE : vstr_printf ( vstr , "False" ); break ;
338
+ case PY_TOKEN_KW_NONE : vstr_printf ( vstr , "None" ); break ;
339
+ case PY_TOKEN_KW_TRUE : vstr_printf ( vstr , "True" ); break ;
300
340
default : assert (0 );
301
341
}
302
342
break ;
@@ -325,25 +365,28 @@ static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_
325
365
}
326
366
if (total > 0 && is_const ) {
327
367
bool need_comma = false;
328
- EMIT ( load_const_verbatim_start );
329
- EMIT ( load_const_verbatim_str , "(" );
368
+ vstr_t * vstr = vstr_new ( );
369
+ vstr_printf ( vstr , "(" );
330
370
if (!PY_PARSE_NODE_IS_NULL (pn )) {
331
- cpython_c_tuple_emit_const (comp , pn );
371
+ cpython_c_tuple_emit_const (comp , pn , vstr );
332
372
need_comma = true;
333
373
}
334
374
for (int i = 0 ; i < n ; i ++ ) {
335
375
if (need_comma ) {
336
- EMIT ( load_const_verbatim_str , ", " );
376
+ vstr_printf ( vstr , ", " );
337
377
}
338
- cpython_c_tuple_emit_const (comp , pns_list -> nodes [i ]);
378
+ cpython_c_tuple_emit_const (comp , pns_list -> nodes [i ], vstr );
339
379
need_comma = true;
340
380
}
341
381
if (total == 1 ) {
342
- EMIT ( load_const_verbatim_str , ",)" );
382
+ vstr_printf ( vstr , ",)" );
343
383
} else {
344
- EMIT ( load_const_verbatim_str , ")" );
384
+ vstr_printf ( vstr , ")" );
345
385
}
386
+ EMIT (load_const_verbatim_start );
387
+ EMIT (load_const_verbatim_str , vstr_str (vstr ));
346
388
EMIT (load_const_verbatim_end );
389
+ vstr_free (vstr );
347
390
} else {
348
391
if (!PY_PARSE_NODE_IS_NULL (pn )) {
349
392
compile_node (comp , pn );
@@ -1198,24 +1241,29 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
1198
1241
py_parse_node_t * pn_nodes ;
1199
1242
int n = list_get (& pns -> nodes [1 ], PN_import_as_names , & pn_nodes );
1200
1243
#if MICROPY_EMIT_CPYTHON
1201
- EMIT (load_const_verbatim_start );
1202
- EMIT (load_const_verbatim_str , "(" );
1203
- for (int i = 0 ; i < n ; i ++ ) {
1204
- assert (PY_PARSE_NODE_IS_STRUCT_KIND (pn_nodes [i ], PN_import_as_name ));
1205
- py_parse_node_struct_t * pns3 = (py_parse_node_struct_t * )pn_nodes [i ];
1206
- qstr id2 = PY_PARSE_NODE_LEAF_ARG (pns3 -> nodes [0 ]); // should be id
1207
- if (i > 0 ) {
1208
- EMIT (load_const_verbatim_str , ", " );
1244
+ {
1245
+ vstr_t * vstr = vstr_new ();
1246
+ vstr_printf (vstr , "(" );
1247
+ for (int i = 0 ; i < n ; i ++ ) {
1248
+ assert (PY_PARSE_NODE_IS_STRUCT_KIND (pn_nodes [i ], PN_import_as_name ));
1249
+ py_parse_node_struct_t * pns3 = (py_parse_node_struct_t * )pn_nodes [i ];
1250
+ qstr id2 = PY_PARSE_NODE_LEAF_ARG (pns3 -> nodes [0 ]); // should be id
1251
+ if (i > 0 ) {
1252
+ vstr_printf (vstr , ", " );
1253
+ }
1254
+ vstr_printf (vstr , "'" );
1255
+ vstr_printf (vstr , qstr_str (id2 ));
1256
+ vstr_printf (vstr , "'" );
1209
1257
}
1210
- EMIT (load_const_verbatim_str , "'" );
1211
- EMIT (load_const_verbatim_str , qstr_str (id2 ));
1212
- EMIT (load_const_verbatim_str , "'" );
1213
- }
1214
- if (n == 1 ) {
1215
- EMIT (load_const_verbatim_str , "," );
1258
+ if (n == 1 ) {
1259
+ vstr_printf (vstr , "," );
1260
+ }
1261
+ vstr_printf (vstr , ")" );
1262
+ EMIT (load_const_verbatim_start );
1263
+ EMIT (load_const_verbatim_str , vstr_str (vstr ));
1264
+ EMIT (load_const_verbatim_end );
1265
+ vstr_free (vstr );
1216
1266
}
1217
- EMIT (load_const_verbatim_str , ")" );
1218
- EMIT (load_const_verbatim_end );
1219
1267
#else
1220
1268
for (int i = 0 ; i < n ; i ++ ) {
1221
1269
assert (PY_PARSE_NODE_IS_STRUCT_KIND (pn_nodes [i ], PN_import_as_name ));
0 commit comments