comparison src/ex_eval.c @ 30247:327bca7b70ea v9.0.0459

patch 9.0.0459: Vim9: block in for loop doesn't behave like a code block Commit: https://github.com/vim/vim/commit/353b68a99189875a8460124d44fc33eae6def74e Author: Bram Moolenaar <Bram@vim.org> Date: Tue Sep 13 21:10:45 2022 +0100 patch 9.0.0459: Vim9: block in for loop doesn't behave like a code block Problem: Vim9: block in for loop doesn't behave like a code block. Solution: Use a new block ID for each loop at the script level.
author Bram Moolenaar <Bram@vim.org>
date Tue, 13 Sep 2022 22:15:04 +0200
parents 6a8c2ff5b2ef
children c0f0118b6790
comparison
equal deleted inserted replaced
30246:23088f4486a5 30247:327bca7b70ea
1228 { 1228 {
1229 if (in_vim9script() && SCRIPT_ID_VALID(current_sctx.sc_sid)) 1229 if (in_vim9script() && SCRIPT_ID_VALID(current_sctx.sc_sid))
1230 { 1230 {
1231 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); 1231 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
1232 int i; 1232 int i;
1233 int first;
1233 int func_defined = cstack->cs_flags[cstack->cs_idx] 1234 int func_defined = cstack->cs_flags[cstack->cs_idx]
1234 & CSF_FUNC_DEF; 1235 & CSF_FUNC_DEF;
1235 1236
1236 // Any variables defined in the previous round are no longer 1237 // Any variables defined in the previous round are no longer
1237 // visible. Keep the first one for ":for", it is the loop 1238 // visible. Keep the first one for ":for", it is the loop
1238 // variable that we reuse every time around. 1239 // variable that we reuse every time around.
1239 for (i = cstack->cs_script_var_len[cstack->cs_idx] 1240 // Do this backwards, so that vars defined in a later round are
1241 // found first.
1242 first = cstack->cs_script_var_len[cstack->cs_idx]
1240 + (eap->cmdidx == CMD_while ? 0 : 1); 1243 + (eap->cmdidx == CMD_while ? 0 : 1);
1241 i < si->sn_var_vals.ga_len; ++i) 1244 for (i = si->sn_var_vals.ga_len - 1; i >= first; --i)
1242 { 1245 {
1243 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + i; 1246 svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + i;
1244 1247
1245 // sv_name is set to NULL if it was already removed. This 1248 // sv_name is set to NULL if it was already removed. This
1246 // happens when it was defined in an inner block and no 1249 // happens when it was defined in an inner block and no
1248 if (sv->sv_name != NULL) 1251 if (sv->sv_name != NULL)
1249 // Remove a variable declared inside the block, if it 1252 // Remove a variable declared inside the block, if it
1250 // still exists, from sn_vars. 1253 // still exists, from sn_vars.
1251 hide_script_var(si, i, func_defined); 1254 hide_script_var(si, i, func_defined);
1252 } 1255 }
1256
1257 // Start a new block ID, so that variables defined inside the
1258 // loop are created new and not shared with the previous loop.
1259 // Matters when used in a closure.
1260 cstack->cs_block_id[cstack->cs_idx] = ++si->sn_last_block_id;
1261 si->sn_current_block_id = si->sn_last_block_id;
1253 } 1262 }
1254 } 1263 }
1255 cstack->cs_flags[cstack->cs_idx] = 1264 cstack->cs_flags[cstack->cs_idx] =
1256 eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR; 1265 eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
1257 1266