@@ -1614,30 +1614,58 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
16141614 }
16151615}
16161616
1617+ STATIC void compile_declare_global (compiler_t * comp , mp_parse_node_t pn , qstr qst ) {
1618+ bool added ;
1619+ id_info_t * id_info = scope_find_or_add_id (comp -> scope_cur , qst , & added );
1620+ if (!added ) {
1621+ compile_syntax_error (comp , pn , "identifier already used" );
1622+ return ;
1623+ }
1624+ id_info -> kind = ID_INFO_KIND_GLOBAL_EXPLICIT ;
1625+
1626+ // if the id exists in the global scope, set its kind to EXPLICIT_GLOBAL
1627+ id_info = scope_find_global (comp -> scope_cur , qst );
1628+ if (id_info != NULL ) {
1629+ id_info -> kind = ID_INFO_KIND_GLOBAL_EXPLICIT ;
1630+ }
1631+ }
1632+
16171633STATIC void compile_global_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
16181634 if (comp -> pass == MP_PASS_SCOPE ) {
1619- if (MP_PARSE_NODE_IS_LEAF (pns -> nodes [0 ])) {
1620- scope_declare_global (comp -> scope_cur , MP_PARSE_NODE_LEAF_ARG (pns -> nodes [0 ]));
1621- } else {
1622- pns = (mp_parse_node_struct_t * )pns -> nodes [0 ];
1623- int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES (pns );
1624- for (int i = 0 ; i < num_nodes ; i ++ ) {
1625- scope_declare_global (comp -> scope_cur , MP_PARSE_NODE_LEAF_ARG (pns -> nodes [i ]));
1626- }
1635+ mp_parse_node_t * nodes ;
1636+ int n = list_get (& pns -> nodes [0 ], PN_name_list , & nodes );
1637+ for (int i = 0 ; i < n ; i ++ ) {
1638+ compile_declare_global (comp , (mp_parse_node_t )pns , MP_PARSE_NODE_LEAF_ARG (nodes [i ]));
16271639 }
16281640 }
16291641}
16301642
1643+ STATIC void compile_declare_nonlocal (compiler_t * comp , mp_parse_node_t pn , qstr qst ) {
1644+ bool added ;
1645+ id_info_t * id_info = scope_find_or_add_id (comp -> scope_cur , qst , & added );
1646+ if (!added ) {
1647+ compile_syntax_error (comp , pn , "identifier already used" );
1648+ return ;
1649+ }
1650+ id_info_t * id_info2 = scope_find_local_in_parent (comp -> scope_cur , qst );
1651+ if (id_info2 == NULL || !(id_info2 -> kind == ID_INFO_KIND_LOCAL || id_info2 -> kind == ID_INFO_KIND_CELL || id_info2 -> kind == ID_INFO_KIND_FREE )) {
1652+ compile_syntax_error (comp , pn , "no binding for nonlocal found" );
1653+ return ;
1654+ }
1655+ id_info -> kind = ID_INFO_KIND_FREE ;
1656+ scope_close_over_in_parents (comp -> scope_cur , qst );
1657+ }
1658+
16311659STATIC void compile_nonlocal_stmt (compiler_t * comp , mp_parse_node_struct_t * pns ) {
16321660 if (comp -> pass == MP_PASS_SCOPE ) {
1633- if (MP_PARSE_NODE_IS_LEAF ( pns -> nodes [ 0 ]) ) {
1634- scope_declare_nonlocal (comp -> scope_cur , MP_PARSE_NODE_LEAF_ARG ( pns -> nodes [ 0 ]) );
1635- } else {
1636- pns = ( mp_parse_node_struct_t * ) pns -> nodes [ 0 ];
1637- int num_nodes = MP_PARSE_NODE_STRUCT_NUM_NODES ( pns ) ;
1638- for ( int i = 0 ; i < num_nodes ; i ++ ) {
1639- scope_declare_nonlocal ( comp -> scope_cur , MP_PARSE_NODE_LEAF_ARG ( pns -> nodes [ i ]));
1640- }
1661+ if (comp -> scope_cur -> kind == SCOPE_MODULE ) {
1662+ compile_syntax_error (comp , ( mp_parse_node_t ) pns , "can't declare nonlocal in outer code" );
1663+ return ;
1664+ }
1665+ mp_parse_node_t * nodes ;
1666+ int n = list_get ( & pns -> nodes [ 0 ], PN_name_list , & nodes );
1667+ for ( int i = 0 ; i < n ; i ++ ) {
1668+ compile_declare_nonlocal ( comp , ( mp_parse_node_t ) pns , MP_PARSE_NODE_LEAF_ARG ( nodes [ i ]));
16411669 }
16421670 }
16431671}
0 commit comments