py/compile: Combine global and nonlocal statement compile functions.

This commit is contained in:
Damien George 2018-06-19 14:04:05 +10:00
parent d23bec3fc8
commit 1a7109d65a
2 changed files with 17 additions and 21 deletions

View File

@ -1162,9 +1162,7 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
} }
} }
STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qst) { STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qst, bool added, id_info_t *id_info) {
bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
if (!added && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) { if (!added && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) {
compile_syntax_error(comp, pn, "identifier redefined as global"); compile_syntax_error(comp, pn, "identifier redefined as global");
return; return;
@ -1178,19 +1176,7 @@ STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, qstr qs
} }
} }
STATIC void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr qst, bool added, id_info_t *id_info) {
if (comp->pass == MP_PASS_SCOPE) {
mp_parse_node_t *nodes;
int n = mp_parse_node_extract_list(&pns->nodes[0], PN_name_list, &nodes);
for (int i = 0; i < n; i++) {
compile_declare_global(comp, (mp_parse_node_t)pns, MP_PARSE_NODE_LEAF_ARG(nodes[i]));
}
}
}
STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr qst) {
bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
if (added) { if (added) {
scope_find_local_and_close_over(comp->scope_cur, id_info, qst); scope_find_local_and_close_over(comp->scope_cur, id_info, qst);
if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) { if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
@ -1201,16 +1187,26 @@ STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr
} }
} }
STATIC void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { STATIC void compile_global_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
if (comp->pass == MP_PASS_SCOPE) { if (comp->pass == MP_PASS_SCOPE) {
if (comp->scope_cur->kind == SCOPE_MODULE) { bool is_global = MP_PARSE_NODE_STRUCT_KIND(pns) == PN_global_stmt;
if (!is_global && comp->scope_cur->kind == SCOPE_MODULE) {
compile_syntax_error(comp, (mp_parse_node_t)pns, "can't declare nonlocal in outer code"); compile_syntax_error(comp, (mp_parse_node_t)pns, "can't declare nonlocal in outer code");
return; return;
} }
mp_parse_node_t *nodes; mp_parse_node_t *nodes;
int n = mp_parse_node_extract_list(&pns->nodes[0], PN_name_list, &nodes); int n = mp_parse_node_extract_list(&pns->nodes[0], PN_name_list, &nodes);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
compile_declare_nonlocal(comp, (mp_parse_node_t)pns, MP_PARSE_NODE_LEAF_ARG(nodes[i])); qstr qst = MP_PARSE_NODE_LEAF_ARG(nodes[i]);
bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
if (is_global) {
compile_declare_global(comp, (mp_parse_node_t)pns, qst, added, id_info);
} else {
compile_declare_nonlocal(comp, (mp_parse_node_t)pns, qst, added, id_info);
}
} }
} }
} }

View File

@ -157,8 +157,8 @@ DEF_RULE_NC(as_name, and_ident(2), tok(KW_AS), tok(NAME))
DEF_RULE_NC(import_as_names, list_with_end, rule(import_as_name), tok(DEL_COMMA)) DEF_RULE_NC(import_as_names, list_with_end, rule(import_as_name), tok(DEL_COMMA))
DEF_RULE_NC(dotted_as_names, list, rule(dotted_as_name), tok(DEL_COMMA)) DEF_RULE_NC(dotted_as_names, list, rule(dotted_as_name), tok(DEL_COMMA))
DEF_RULE_NC(dotted_name, list, tok(NAME), tok(DEL_PERIOD)) DEF_RULE_NC(dotted_name, list, tok(NAME), tok(DEL_PERIOD))
DEF_RULE(global_stmt, c(global_stmt), and(2), tok(KW_GLOBAL), rule(name_list)) DEF_RULE(global_stmt, c(global_nonlocal_stmt), and(2), tok(KW_GLOBAL), rule(name_list))
DEF_RULE(nonlocal_stmt, c(nonlocal_stmt), and(2), tok(KW_NONLOCAL), rule(name_list)) DEF_RULE(nonlocal_stmt, c(global_nonlocal_stmt), and(2), tok(KW_NONLOCAL), rule(name_list))
DEF_RULE_NC(name_list, list, tok(NAME), tok(DEL_COMMA)) DEF_RULE_NC(name_list, list, tok(NAME), tok(DEL_COMMA))
DEF_RULE(assert_stmt, c(assert_stmt), and(3), tok(KW_ASSERT), rule(test), opt_rule(assert_stmt_extra)) DEF_RULE(assert_stmt, c(assert_stmt), and(3), tok(KW_ASSERT), rule(test), opt_rule(assert_stmt_extra))
DEF_RULE_NC(assert_stmt_extra, and_ident(2), tok(DEL_COMMA), rule(test)) DEF_RULE_NC(assert_stmt_extra, and_ident(2), tok(DEL_COMMA), rule(test))