Skip to content

Commit b14de21

Browse files
committed
Optimise typedargslist_name to not create a node if just an id.
1 parent a2f2f7d commit b14de21

2 files changed

Lines changed: 62 additions & 52 deletions

File tree

py/compile.c

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -643,9 +643,8 @@ void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_
643643
}
644644

645645
void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
646-
assert(PY_PARSE_NODE_IS_STRUCT(pn));
647-
py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
648-
if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_name) {
646+
if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_name)) {
647+
py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
649648
if (!PY_PARSE_NODE_IS_NULL(pns->nodes[2])) {
650649
// this parameter has a default value
651650
// in CPython, None (and True, False?) as default parameters are loaded with LOAD_NAME; don't understandy why
@@ -662,7 +661,8 @@ void compile_funcdef_param(compiler_t *comp, py_parse_node_t pn) {
662661
}
663662
}
664663
}
665-
} else if (PY_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_star) {
664+
} else if (PY_PARSE_NODE_IS_STRUCT_KIND(pn, PN_typedargslist_star)) {
665+
py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
666666
if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
667667
// bare star
668668
comp->have_bare_star = true;
@@ -2206,65 +2206,74 @@ void compile_node(compiler_t *comp, py_parse_node_t pn) {
22062206

22072207
void compile_scope_func_lambda_param(compiler_t *comp, py_parse_node_t pn, pn_kind_t pn_name, pn_kind_t pn_star, pn_kind_t pn_dbl_star, bool allow_annotations) {
22082208
// TODO verify that *k and **k are last etc
2209-
assert(PY_PARSE_NODE_IS_STRUCT(pn));
2210-
py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
22112209
qstr param_name = 0;
22122210
py_parse_node_t pn_annotation = PY_PARSE_NODE_NULL;
2213-
if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
2214-
param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2215-
//int node_index = 1; unused
2216-
if (allow_annotations) {
2217-
if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2218-
// this parameter has an annotation
2219-
pn_annotation = pns->nodes[1];
2220-
}
2221-
//node_index = 2; unused
2222-
}
2223-
/* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2224-
if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2225-
// this parameter has a default value
2226-
if (comp->have_bare_star) {
2227-
comp->scope_cur->num_dict_params += 1;
2228-
} else {
2229-
comp->scope_cur->num_default_params += 1;
2230-
}
2231-
}
2232-
*/
2211+
if (PY_PARSE_NODE_IS_ID(pn)) {
2212+
param_name = PY_PARSE_NODE_LEAF_ARG(pn);
22332213
if (comp->have_bare_star) {
22342214
// comes after a bare star, so doesn't count as a parameter
22352215
} else {
22362216
comp->scope_cur->num_params += 1;
22372217
}
2238-
} else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2239-
if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2240-
// bare star
2241-
// TODO see http://www.python.org/dev/peps/pep-3102/
2242-
comp->have_bare_star = true;
2243-
//assert(comp->scope_cur->num_dict_params == 0);
2244-
} else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2245-
// named star
2246-
comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2218+
} else {
2219+
assert(PY_PARSE_NODE_IS_STRUCT(pn));
2220+
py_parse_node_struct_t *pns = (py_parse_node_struct_t*)pn;
2221+
if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_name) {
22472222
param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2248-
} else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2249-
// named star with annotation
2250-
comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2251-
pns = (py_parse_node_struct_t*)pns->nodes[0];
2223+
//int node_index = 1; unused
2224+
if (allow_annotations) {
2225+
if (!PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2226+
// this parameter has an annotation
2227+
pn_annotation = pns->nodes[1];
2228+
}
2229+
//node_index = 2; unused
2230+
}
2231+
/* this is obsolete now that num dict/default params are calculated in compile_funcdef_param
2232+
if (!PY_PARSE_NODE_IS_NULL(pns->nodes[node_index])) {
2233+
// this parameter has a default value
2234+
if (comp->have_bare_star) {
2235+
comp->scope_cur->num_dict_params += 1;
2236+
} else {
2237+
comp->scope_cur->num_default_params += 1;
2238+
}
2239+
}
2240+
*/
2241+
if (comp->have_bare_star) {
2242+
// comes after a bare star, so doesn't count as a parameter
2243+
} else {
2244+
comp->scope_cur->num_params += 1;
2245+
}
2246+
} else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_star) {
2247+
if (PY_PARSE_NODE_IS_NULL(pns->nodes[0])) {
2248+
// bare star
2249+
// TODO see http://www.python.org/dev/peps/pep-3102/
2250+
comp->have_bare_star = true;
2251+
//assert(comp->scope_cur->num_dict_params == 0);
2252+
} else if (PY_PARSE_NODE_IS_ID(pns->nodes[0])) {
2253+
// named star
2254+
comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2255+
param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2256+
} else if (allow_annotations && PY_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_tfpdef)) {
2257+
// named star with annotation
2258+
comp->scope_cur->flags |= SCOPE_FLAG_VARARGS;
2259+
pns = (py_parse_node_struct_t*)pns->nodes[0];
2260+
param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2261+
pn_annotation = pns->nodes[1];
2262+
} else {
2263+
// shouldn't happen
2264+
assert(0);
2265+
}
2266+
} else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
22522267
param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2253-
pn_annotation = pns->nodes[1];
2268+
if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2269+
// this parameter has an annotation
2270+
pn_annotation = pns->nodes[1];
2271+
}
2272+
comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
22542273
} else {
2255-
// shouldn't happen
2274+
// TODO anything to implement?
22562275
assert(0);
22572276
}
2258-
} else if (PY_PARSE_NODE_STRUCT_KIND(pns) == pn_dbl_star) {
2259-
param_name = PY_PARSE_NODE_LEAF_ARG(pns->nodes[0]);
2260-
if (allow_annotations && !PY_PARSE_NODE_IS_NULL(pns->nodes[1])) {
2261-
// this parameter has an annotation
2262-
pn_annotation = pns->nodes[1];
2263-
}
2264-
comp->scope_cur->flags |= SCOPE_FLAG_VARKEYWORDS;
2265-
} else {
2266-
// TODO anything to implement?
2267-
assert(0);
22682277
}
22692278

22702279
if (param_name != 0) {

py/parse.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ py_parse_node_t py_parse(py_lexer_t *lex, int wanted_rule) {
414414

415415
// never emit these rules if they have only 1 argument
416416
// NOTE: can't put atom_paren here because we need it to distinguisg, for example, [a,b] from [(a,b)]
417-
if (rule->rule_id == RULE_else_stmt || rule->rule_id == RULE_testlist_comp_3b || rule->rule_id == RULE_import_as_names_paren || rule->rule_id == RULE_typedargslist_colon || rule->rule_id == RULE_typedargslist_equal || rule->rule_id == RULE_dictorsetmaker_colon || rule->rule_id == RULE_classdef_2 || rule->rule_id == RULE_with_item_as || rule->rule_id == RULE_assert_stmt_extra || rule->rule_id == RULE_as_name || rule->rule_id == RULE_raise_stmt_from || rule->rule_id == RULE_vfpdef) {
417+
// TODO possibly put varargslist_name, varargslist_equal here as well
418+
if (rule->rule_id == RULE_else_stmt || rule->rule_id == RULE_testlist_comp_3b || rule->rule_id == RULE_import_as_names_paren || rule->rule_id == RULE_typedargslist_name || rule->rule_id == RULE_typedargslist_colon || rule->rule_id == RULE_typedargslist_equal || rule->rule_id == RULE_dictorsetmaker_colon || rule->rule_id == RULE_classdef_2 || rule->rule_id == RULE_with_item_as || rule->rule_id == RULE_assert_stmt_extra || rule->rule_id == RULE_as_name || rule->rule_id == RULE_raise_stmt_from || rule->rule_id == RULE_vfpdef) {
418419
emit_rule = false;
419420
}
420421

0 commit comments

Comments
 (0)