@@ -2878,9 +2878,10 @@ clear_ppconst(ppconst_T *ppconst)
28782878/*
28792879 * Compile getting a member from a list/dict/string/blob. Stack has the
28802880 * indexable value and the index or the two indexes of a slice.
2881+ * "keeping_dict" is used for dict[func](arg) to pass dict to func.
28812882 */
28822883 static int
2883- compile_member (int is_slice , cctx_T * cctx )
2884+ compile_member (int is_slice , int * keeping_dict , cctx_T * cctx )
28842885{
28852886 type_T * * typep ;
28862887 garray_T * stack = & cctx -> ctx_type_stack ;
@@ -2935,6 +2936,8 @@ compile_member(int is_slice, cctx_T *cctx)
29352936 return FAIL ;
29362937 if (generate_instr_drop (cctx , ISN_MEMBER , 1 ) == FAIL )
29372938 return FAIL ;
2939+ if (keeping_dict != NULL )
2940+ * keeping_dict = TRUE;
29382941 }
29392942 else if (vartype == VAR_STRING )
29402943 {
@@ -4314,6 +4317,7 @@ compile_subscript(
43144317 ppconst_T * ppconst )
43154318{
43164319 char_u * name_start = * end_leader ;
4320+ int keeping_dict = FALSE;
43174321
43184322 for (;;)
43194323 {
@@ -4360,6 +4364,12 @@ compile_subscript(
43604364 return FAIL ;
43614365 if (generate_PCALL (cctx , argcount , name_start , type , TRUE) == FAIL )
43624366 return FAIL ;
4367+ if (keeping_dict )
4368+ {
4369+ keeping_dict = FALSE;
4370+ if (generate_instr (cctx , ISN_CLEARDICT ) == NULL )
4371+ return FAIL ;
4372+ }
43634373 }
43644374 else if (* p == '-' && p [1 ] == '>' )
43654375 {
@@ -4470,6 +4480,12 @@ compile_subscript(
44704480 if (compile_call (arg , p - * arg , cctx , ppconst , 1 ) == FAIL )
44714481 return FAIL ;
44724482 }
4483+ if (keeping_dict )
4484+ {
4485+ keeping_dict = FALSE;
4486+ if (generate_instr (cctx , ISN_CLEARDICT ) == NULL )
4487+ return FAIL ;
4488+ }
44734489 }
44744490 else if (* * arg == '[' )
44754491 {
@@ -4537,7 +4553,13 @@ compile_subscript(
45374553 }
45384554 * arg = * arg + 1 ;
45394555
4540- if (compile_member (is_slice , cctx ) == FAIL )
4556+ if (keeping_dict )
4557+ {
4558+ keeping_dict = FALSE;
4559+ if (generate_instr (cctx , ISN_CLEARDICT ) == NULL )
4560+ return FAIL ;
4561+ }
4562+ if (compile_member (is_slice , & keeping_dict , cctx ) == FAIL )
45414563 return FAIL ;
45424564 }
45434565 else if (* p == '.' && p [1 ] != '.' )
@@ -4562,18 +4584,21 @@ compile_subscript(
45624584 semsg (_ (e_syntax_error_at_str ), * arg );
45634585 return FAIL ;
45644586 }
4587+ if (keeping_dict && generate_instr (cctx , ISN_CLEARDICT ) == NULL )
4588+ return FAIL ;
45654589 if (generate_STRINGMEMBER (cctx , * arg , p - * arg ) == FAIL )
45664590 return FAIL ;
4591+ keeping_dict = TRUE;
45674592 * arg = p ;
45684593 }
45694594 else
45704595 break ;
45714596 }
45724597
4573- // TODO - see handle_subscript():
45744598 // Turn "dict.Func" into a partial for "Func" bound to "dict".
4575- // Don't do this when "Func" is already a partial that was bound
4576- // explicitly (pt_auto is FALSE).
4599+ // This needs to be done at runtime to be able to check the type.
4600+ if (keeping_dict && generate_instr (cctx , ISN_USEDICT ) == NULL )
4601+ return FAIL ;
45774602
45784603 return OK ;
45794604}
@@ -6661,7 +6686,7 @@ compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx)
66616686 }
66626687
66636688 // Get the member.
6664- if (compile_member (FALSE, cctx ) == FAIL )
6689+ if (compile_member (FALSE, NULL , cctx ) == FAIL )
66656690 return FAIL ;
66666691 }
66676692 return OK ;
@@ -10406,6 +10431,7 @@ delete_instr(isn_T *isn)
1040610431 case ISN_CEXPR_AUCMD :
1040710432 case ISN_CHECKLEN :
1040810433 case ISN_CHECKNR :
10434+ case ISN_CLEARDICT :
1040910435 case ISN_CMDMOD_REV :
1041010436 case ISN_COMPAREANY :
1041110437 case ISN_COMPAREBLOB :
@@ -10482,6 +10508,7 @@ delete_instr(isn_T *isn)
1048210508 case ISN_UNLETINDEX :
1048310509 case ISN_UNLETRANGE :
1048410510 case ISN_UNPACK :
10511+ case ISN_USEDICT :
1048510512 // nothing allocated
1048610513 break ;
1048710514 }
0 commit comments