@@ -8041,151 +8041,154 @@ compile_for(char_u *arg_start, cctx_T *cctx)
80418041 }
80428042 arg_end = arg ;
80438043
8044- // If we know the type of "var" and it is a not a supported type we can
8045- // give an error now.
8046- vartype = ((type_T * * )stack -> ga_data )[stack -> ga_len - 1 ];
8047- if (vartype -> tt_type != VAR_LIST && vartype -> tt_type != VAR_STRING
8048- && vartype -> tt_type != VAR_BLOB && vartype -> tt_type != VAR_ANY )
8044+ if (cctx -> ctx_skip != SKIP_YES )
80498045 {
8050- semsg (_ (e_for_loop_on_str_not_supported ),
8046+ // If we know the type of "var" and it is a not a supported type we can
8047+ // give an error now.
8048+ vartype = ((type_T * * )stack -> ga_data )[stack -> ga_len - 1 ];
8049+ if (vartype -> tt_type != VAR_LIST && vartype -> tt_type != VAR_STRING
8050+ && vartype -> tt_type != VAR_BLOB && vartype -> tt_type != VAR_ANY )
8051+ {
8052+ semsg (_ (e_for_loop_on_str_not_supported ),
80518053 vartype_name (vartype -> tt_type ));
8052- drop_scope (cctx );
8053- return NULL ;
8054- }
8054+ drop_scope (cctx );
8055+ return NULL ;
8056+ }
80558057
8056- if (vartype -> tt_type == VAR_STRING )
8057- item_type = & t_string ;
8058- else if (vartype -> tt_type == VAR_BLOB )
8059- item_type = & t_number ;
8060- else if (vartype -> tt_type == VAR_LIST
8058+ if (vartype -> tt_type == VAR_STRING )
8059+ item_type = & t_string ;
8060+ else if (vartype -> tt_type == VAR_BLOB )
8061+ item_type = & t_number ;
8062+ else if (vartype -> tt_type == VAR_LIST
80618063 && vartype -> tt_member -> tt_type != VAR_ANY )
8062- {
8063- if (!var_list )
8064- item_type = vartype -> tt_member ;
8065- else if (vartype -> tt_member -> tt_type == VAR_LIST
8066- && vartype -> tt_member -> tt_member -> tt_type != VAR_ANY )
8067- // TODO: should get the type for each lhs
8068- item_type = vartype -> tt_member -> tt_member ;
8069- }
8064+ {
8065+ if (!var_list )
8066+ item_type = vartype -> tt_member ;
8067+ else if (vartype -> tt_member -> tt_type == VAR_LIST
8068+ && vartype -> tt_member -> tt_member -> tt_type != VAR_ANY )
8069+ // TODO: should get the type for each lhs
8070+ item_type = vartype -> tt_member -> tt_member ;
8071+ }
80708072
8071- // CMDMOD_REV must come before the FOR instruction.
8072- generate_undo_cmdmods (cctx );
8073+ // CMDMOD_REV must come before the FOR instruction.
8074+ generate_undo_cmdmods (cctx );
80738075
8074- // "for_end" is set when ":endfor" is found
8075- scope -> se_u .se_for .fs_top_label = current_instr_idx (cctx );
8076+ // "for_end" is set when ":endfor" is found
8077+ scope -> se_u .se_for .fs_top_label = current_instr_idx (cctx );
80768078
8077- generate_FOR (cctx , loop_lvar -> lv_idx );
8079+ generate_FOR (cctx , loop_lvar -> lv_idx );
80788080
8079- arg = arg_start ;
8080- if (var_list )
8081- {
8082- generate_UNPACK (cctx , var_count , semicolon );
8083- arg = skipwhite (arg + 1 ); // skip white after '['
8084-
8085- // the list item is replaced by a number of items
8086- if (GA_GROW_FAILS (stack , var_count - 1 ))
8081+ arg = arg_start ;
8082+ if (var_list )
80878083 {
8088- drop_scope (cctx );
8089- return NULL ;
8084+ generate_UNPACK (cctx , var_count , semicolon );
8085+ arg = skipwhite (arg + 1 ); // skip white after '['
8086+
8087+ // the list item is replaced by a number of items
8088+ if (GA_GROW_FAILS (stack , var_count - 1 ))
8089+ {
8090+ drop_scope (cctx );
8091+ return NULL ;
8092+ }
8093+ -- stack -> ga_len ;
8094+ for (idx = 0 ; idx < var_count ; ++ idx )
8095+ {
8096+ ((type_T * * )stack -> ga_data )[stack -> ga_len ] =
8097+ (semicolon && idx == 0 ) ? vartype : item_type ;
8098+ ++ stack -> ga_len ;
8099+ }
80908100 }
8091- -- stack -> ga_len ;
8101+
80928102 for (idx = 0 ; idx < var_count ; ++ idx )
80938103 {
8094- ((type_T * * )stack -> ga_data )[stack -> ga_len ] =
8095- (semicolon && idx == 0 ) ? vartype : item_type ;
8096- ++ stack -> ga_len ;
8097- }
8098- }
8104+ assign_dest_T dest = dest_local ;
8105+ int opt_flags = 0 ;
8106+ int vimvaridx = -1 ;
8107+ type_T * type = & t_any ;
8108+ type_T * lhs_type = & t_any ;
8109+ where_T where = WHERE_INIT ;
80998110
8100- for (idx = 0 ; idx < var_count ; ++ idx )
8101- {
8102- assign_dest_T dest = dest_local ;
8103- int opt_flags = 0 ;
8104- int vimvaridx = -1 ;
8105- type_T * type = & t_any ;
8106- type_T * lhs_type = & t_any ;
8107- where_T where = WHERE_INIT ;
8108-
8109- p = skip_var_one (arg , FALSE);
8110- varlen = p - arg ;
8111- name = vim_strnsave (arg , varlen );
8112- if (name == NULL )
8113- goto failed ;
8114- if (* p == ':' )
8115- {
8116- p = skipwhite (p + 1 );
8117- lhs_type = parse_type (& p , cctx -> ctx_type_list , TRUE);
8118- }
8111+ p = skip_var_one (arg , FALSE);
8112+ varlen = p - arg ;
8113+ name = vim_strnsave (arg , varlen );
8114+ if (name == NULL )
8115+ goto failed ;
8116+ if (* p == ':' )
8117+ {
8118+ p = skipwhite (p + 1 );
8119+ lhs_type = parse_type (& p , cctx -> ctx_type_list , TRUE);
8120+ }
81198121
8120- // TODO: script var not supported?
8121- if (get_var_dest (name , & dest , CMD_for , & opt_flags ,
8122+ // TODO: script var not supported?
8123+ if (get_var_dest (name , & dest , CMD_for , & opt_flags ,
81228124 & vimvaridx , & type , cctx ) == FAIL )
8123- goto failed ;
8124- if (dest != dest_local )
8125- {
8126- if (generate_store_var (cctx , dest , opt_flags , vimvaridx ,
8127- 0 , 0 , type , name ) == FAIL )
8128- goto failed ;
8129- }
8130- else if (varlen == 1 && * arg == '_' )
8131- {
8132- // Assigning to "_": drop the value.
8133- if (generate_instr_drop (cctx , ISN_DROP , 1 ) == NULL )
81348125 goto failed ;
8135- }
8136- else
8137- {
8138- if (lookup_local (arg , varlen , NULL , cctx ) == OK )
8126+ if (dest != dest_local )
81398127 {
8140- semsg (_ (e_variable_already_declared ), arg );
8141- goto failed ;
8128+ if (generate_store_var (cctx , dest , opt_flags , vimvaridx ,
8129+ 0 , 0 , type , name ) == FAIL )
8130+ goto failed ;
81428131 }
8143-
8144- if (STRNCMP (name , "s:" , 2 ) == 0 )
8132+ else if (varlen == 1 && * arg == '_' )
81458133 {
8146- semsg (_ (e_cannot_declare_script_variable_in_function ), name );
8147- goto failed ;
8134+ // Assigning to "_": drop the value.
8135+ if (generate_instr_drop (cctx , ISN_DROP , 1 ) == NULL )
8136+ goto failed ;
81488137 }
8138+ else
8139+ {
8140+ if (lookup_local (arg , varlen , NULL , cctx ) == OK )
8141+ {
8142+ semsg (_ (e_variable_already_declared ), arg );
8143+ goto failed ;
8144+ }
81498145
8150- // Reserve a variable to store "var".
8151- where .wt_index = var_list ? idx + 1 : 0 ;
8152- where .wt_variable = TRUE;
8153- if (lhs_type == & t_any )
8154- lhs_type = item_type ;
8155- else if (item_type != & t_unknown
8156- && (item_type == & t_any
8157- ? need_type (item_type , lhs_type ,
8146+ if (STRNCMP (name , "s:" , 2 ) == 0 )
8147+ {
8148+ semsg (_ (e_cannot_declare_script_variable_in_function ), name );
8149+ goto failed ;
8150+ }
8151+
8152+ // Reserve a variable to store "var".
8153+ where .wt_index = var_list ? idx + 1 : 0 ;
8154+ where .wt_variable = TRUE;
8155+ if (lhs_type == & t_any )
8156+ lhs_type = item_type ;
8157+ else if (item_type != & t_unknown
8158+ && (item_type == & t_any
8159+ ? need_type (item_type , lhs_type ,
81588160 -1 , 0 , cctx , FALSE, FALSE)
8159- : check_type (lhs_type , item_type , TRUE, where ))
8160- == FAIL )
8161- goto failed ;
8162- var_lvar = reserve_local (cctx , arg , varlen , TRUE, lhs_type );
8163- if (var_lvar == NULL )
8164- // out of memory or used as an argument
8165- goto failed ;
8161+ : check_type (lhs_type , item_type , TRUE, where ))
8162+ == FAIL )
8163+ goto failed ;
8164+ var_lvar = reserve_local (cctx , arg , varlen , TRUE, lhs_type );
8165+ if (var_lvar == NULL )
8166+ // out of memory or used as an argument
8167+ goto failed ;
8168+
8169+ if (semicolon && idx == var_count - 1 )
8170+ var_lvar -> lv_type = vartype ;
8171+ else
8172+ var_lvar -> lv_type = item_type ;
8173+ generate_STORE (cctx , ISN_STORE , var_lvar -> lv_idx , NULL );
8174+ }
81668175
8167- if (semicolon && idx == var_count - 1 )
8168- var_lvar -> lv_type = vartype ;
8169- else
8170- var_lvar -> lv_type = item_type ;
8171- generate_STORE (cctx , ISN_STORE , var_lvar -> lv_idx , NULL );
8176+ if (* p == ',' || * p == ';' )
8177+ ++ p ;
8178+ arg = skipwhite (p );
8179+ vim_free (name );
81728180 }
81738181
8174- if (* p == ',' || * p == ';' )
8175- ++ p ;
8176- arg = skipwhite (p );
8177- vim_free (name );
8178- }
8179-
8180- if (cctx -> ctx_compile_type == CT_DEBUG )
8181- {
8182- int save_prev_lnum = cctx -> ctx_prev_lnum ;
8182+ if (cctx -> ctx_compile_type == CT_DEBUG )
8183+ {
8184+ int save_prev_lnum = cctx -> ctx_prev_lnum ;
81838185
8184- // Add ISN_DEBUG here, so that the loop variables can be inspected.
8185- // Use the prev_lnum from the ISN_DEBUG instruction removed above.
8186- cctx -> ctx_prev_lnum = prev_lnum ;
8187- generate_instr_debug (cctx );
8188- cctx -> ctx_prev_lnum = save_prev_lnum ;
8186+ // Add ISN_DEBUG here, so that the loop variables can be inspected.
8187+ // Use the prev_lnum from the ISN_DEBUG instruction removed above.
8188+ cctx -> ctx_prev_lnum = prev_lnum ;
8189+ generate_instr_debug (cctx );
8190+ cctx -> ctx_prev_lnum = save_prev_lnum ;
8191+ }
81898192 }
81908193
81918194 return arg_end ;
@@ -8217,21 +8220,24 @@ compile_endfor(char_u *arg, cctx_T *cctx)
82178220 }
82188221 forscope = & scope -> se_u .se_for ;
82198222 cctx -> ctx_scope = scope -> se_outer ;
8220- unwind_locals (cctx , scope -> se_local_count );
8223+ if (cctx -> ctx_skip != SKIP_YES )
8224+ {
8225+ unwind_locals (cctx , scope -> se_local_count );
82218226
8222- // At end of ":for" scope jump back to the FOR instruction.
8223- generate_JUMP (cctx , JUMP_ALWAYS , forscope -> fs_top_label );
8227+ // At end of ":for" scope jump back to the FOR instruction.
8228+ generate_JUMP (cctx , JUMP_ALWAYS , forscope -> fs_top_label );
82248229
8225- // Fill in the "end" label in the FOR statement so it can jump here.
8226- isn = ((isn_T * )instr -> ga_data ) + forscope -> fs_top_label ;
8227- isn -> isn_arg .forloop .for_end = instr -> ga_len ;
8230+ // Fill in the "end" label in the FOR statement so it can jump here.
8231+ isn = ((isn_T * )instr -> ga_data ) + forscope -> fs_top_label ;
8232+ isn -> isn_arg .forloop .for_end = instr -> ga_len ;
82288233
8229- // Fill in the "end" label any BREAK statements
8230- compile_fill_jump_to_end (& forscope -> fs_end_label , instr -> ga_len , cctx );
8234+ // Fill in the "end" label any BREAK statements
8235+ compile_fill_jump_to_end (& forscope -> fs_end_label , instr -> ga_len , cctx );
82318236
8232- // Below the ":for" scope drop the "expr" list from the stack.
8233- if (generate_instr_drop (cctx , ISN_DROP , 1 ) == NULL )
8234- return NULL ;
8237+ // Below the ":for" scope drop the "expr" list from the stack.
8238+ if (generate_instr_drop (cctx , ISN_DROP , 1 ) == NULL )
8239+ return NULL ;
8240+ }
82358241
82368242 vim_free (scope );
82378243
0 commit comments