@@ -282,21 +282,61 @@ static bool cpython_c_tuple_is_const(py_parse_node_t pn) {
282282 return true;
283283}
284284
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 ) {
286326 assert (PY_PARSE_NODE_IS_LEAF (pn ));
287327 int arg = PY_PARSE_NODE_LEAF_ARG (pn );
288328 switch (PY_PARSE_NODE_LEAF_KIND (pn )) {
289329 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 ;
295335 case PY_PARSE_NODE_TOKEN :
296336 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 ;
300340 default : assert (0 );
301341 }
302342 break ;
@@ -325,25 +365,28 @@ static void cpython_c_tuple(compiler_t *comp, py_parse_node_t pn, py_parse_node_
325365 }
326366 if (total > 0 && is_const ) {
327367 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 , "(" );
330370 if (!PY_PARSE_NODE_IS_NULL (pn )) {
331- cpython_c_tuple_emit_const (comp , pn );
371+ cpython_c_tuple_emit_const (comp , pn , vstr );
332372 need_comma = true;
333373 }
334374 for (int i = 0 ; i < n ; i ++ ) {
335375 if (need_comma ) {
336- EMIT ( load_const_verbatim_str , ", " );
376+ vstr_printf ( vstr , ", " );
337377 }
338- cpython_c_tuple_emit_const (comp , pns_list -> nodes [i ]);
378+ cpython_c_tuple_emit_const (comp , pns_list -> nodes [i ], vstr );
339379 need_comma = true;
340380 }
341381 if (total == 1 ) {
342- EMIT ( load_const_verbatim_str , ",)" );
382+ vstr_printf ( vstr , ",)" );
343383 } else {
344- EMIT ( load_const_verbatim_str , ")" );
384+ vstr_printf ( vstr , ")" );
345385 }
386+ EMIT (load_const_verbatim_start );
387+ EMIT (load_const_verbatim_str , vstr_str (vstr ));
346388 EMIT (load_const_verbatim_end );
389+ vstr_free (vstr );
347390 } else {
348391 if (!PY_PARSE_NODE_IS_NULL (pn )) {
349392 compile_node (comp , pn );
@@ -1198,24 +1241,29 @@ void compile_import_from(compiler_t *comp, py_parse_node_struct_t *pns) {
11981241 py_parse_node_t * pn_nodes ;
11991242 int n = list_get (& pns -> nodes [1 ], PN_import_as_names , & pn_nodes );
12001243#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 , "'" );
12091257 }
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 );
12161266 }
1217- EMIT (load_const_verbatim_str , ")" );
1218- EMIT (load_const_verbatim_end );
12191267#else
12201268 for (int i = 0 ; i < n ; i ++ ) {
12211269 assert (PY_PARSE_NODE_IS_STRUCT_KIND (pn_nodes [i ], PN_import_as_name ));
0 commit comments