Skip to content

Commit 02f8941

Browse files
committed
py: reduce use of emit_verbatim calls to minimum.
1 parent 9ecbcff commit 02f8941

File tree

1 file changed

+80
-32
lines changed

1 file changed

+80
-32
lines changed

py/compile.c

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)