@@ -106,39 +106,45 @@ id_info_t *scope_find_global(scope_t *scope, qstr qst) {
106106 return scope_find (scope , qst );
107107}
108108
109- id_info_t * scope_find_local_in_parent (scope_t * scope , qstr qst ) {
110- if (scope -> parent == NULL ) {
111- return NULL ;
112- }
113- for (scope_t * s = scope -> parent ; s -> parent != NULL ; s = s -> parent ) {
114- id_info_t * id = scope_find (s , qst );
115- if (id != NULL ) {
116- return id ;
117- }
118- }
119- return NULL ;
120- }
121-
122- void scope_close_over_in_parents (scope_t * scope , qstr qst ) {
109+ STATIC void scope_close_over_in_parents (scope_t * scope , qstr qst ) {
123110 assert (scope -> parent != NULL ); // we should have at least 1 parent
124- for (scope_t * s = scope -> parent ; s -> parent != NULL ; s = s -> parent ) {
111+ for (scope_t * s = scope -> parent ;; s = s -> parent ) {
112+ assert (s -> parent != NULL ); // we should not get to the outer scope
125113 bool added ;
126114 id_info_t * id = scope_find_or_add_id (s , qst , & added );
127115 if (added ) {
128116 // variable not previously declared in this scope, so declare it as free and keep searching parents
129117 id -> kind = ID_INFO_KIND_FREE ;
130118 } else {
131119 // variable is declared in this scope, so finish
132- switch (id -> kind ) {
133- case ID_INFO_KIND_LOCAL : id -> kind = ID_INFO_KIND_CELL ; break ; // variable local to this scope, close it over
134- case ID_INFO_KIND_FREE : break ; // variable already closed over in a parent scope
135- case ID_INFO_KIND_CELL : break ; // variable already closed over in this scope
136- default : assert (0 ); // TODO
120+ if (id -> kind == ID_INFO_KIND_LOCAL ) {
121+ // variable local to this scope, close it over
122+ id -> kind = ID_INFO_KIND_CELL ;
123+ } else {
124+ // ID_INFO_KIND_FREE: variable already closed over in a parent scope
125+ // ID_INFO_KIND_CELL: variable already closed over in this scope
126+ assert (id -> kind == ID_INFO_KIND_FREE || id -> kind == ID_INFO_KIND_CELL );
137127 }
138128 return ;
139129 }
140130 }
141- assert (0 ); // we should have found the variable in one of the parents
131+ }
132+
133+ void scope_find_local_and_close_over (scope_t * scope , id_info_t * id , qstr qst ) {
134+ if (scope -> parent != NULL ) {
135+ for (scope_t * s = scope -> parent ; s -> parent != NULL ; s = s -> parent ) {
136+ id_info_t * id2 = scope_find (s , qst );
137+ if (id2 != NULL ) {
138+ if (id2 -> kind == ID_INFO_KIND_LOCAL || id2 -> kind == ID_INFO_KIND_CELL || id2 -> kind == ID_INFO_KIND_FREE ) {
139+ id -> kind = ID_INFO_KIND_FREE ;
140+ scope_close_over_in_parents (scope , qst );
141+ return ;
142+ }
143+ break ;
144+ }
145+ }
146+ }
147+ id -> kind = ID_INFO_KIND_GLOBAL_IMPLICIT ;
142148}
143149
144150#endif // MICROPY_ENABLE_COMPILER
0 commit comments