Mercurial > vim
comparison src/vim9compile.c @ 25800:fe8d153cb268 v8.2.3435
patch 8.2.3435: Vim9: dict is not passed to dict function
Commit: https://github.com/vim/vim/commit/b1b6f4de2b0edc3b6622912132ddb8994ec52709
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Sep 13 18:25:54 2021 +0200
patch 8.2.3435: Vim9: dict is not passed to dict function
Problem: Vim9: dict is not passed to dict function.
Solution: Keep the dict used until a function call.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 13 Sep 2021 18:30:04 +0200 |
parents | f31cf0388eab |
children | dd4e86558836 |
comparison
equal
deleted
inserted
replaced
25799:0493410eba74 | 25800:fe8d153cb268 |
---|---|
2876 } | 2876 } |
2877 | 2877 |
2878 /* | 2878 /* |
2879 * Compile getting a member from a list/dict/string/blob. Stack has the | 2879 * Compile getting a member from a list/dict/string/blob. Stack has the |
2880 * indexable value and the index or the two indexes of a slice. | 2880 * indexable value and the index or the two indexes of a slice. |
2881 */ | 2881 * "keeping_dict" is used for dict[func](arg) to pass dict to func. |
2882 static int | 2882 */ |
2883 compile_member(int is_slice, cctx_T *cctx) | 2883 static int |
2884 compile_member(int is_slice, int *keeping_dict, cctx_T *cctx) | |
2884 { | 2885 { |
2885 type_T **typep; | 2886 type_T **typep; |
2886 garray_T *stack = &cctx->ctx_type_stack; | 2887 garray_T *stack = &cctx->ctx_type_stack; |
2887 vartype_T vartype; | 2888 vartype_T vartype; |
2888 type_T *idxtype; | 2889 type_T *idxtype; |
2933 } | 2934 } |
2934 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL) | 2935 if (may_generate_2STRING(-1, FALSE, cctx) == FAIL) |
2935 return FAIL; | 2936 return FAIL; |
2936 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) | 2937 if (generate_instr_drop(cctx, ISN_MEMBER, 1) == FAIL) |
2937 return FAIL; | 2938 return FAIL; |
2939 if (keeping_dict != NULL) | |
2940 *keeping_dict = TRUE; | |
2938 } | 2941 } |
2939 else if (vartype == VAR_STRING) | 2942 else if (vartype == VAR_STRING) |
2940 { | 2943 { |
2941 *typep = &t_string; | 2944 *typep = &t_string; |
2942 if ((is_slice | 2945 if ((is_slice |
4312 char_u *start_leader, | 4315 char_u *start_leader, |
4313 char_u **end_leader, | 4316 char_u **end_leader, |
4314 ppconst_T *ppconst) | 4317 ppconst_T *ppconst) |
4315 { | 4318 { |
4316 char_u *name_start = *end_leader; | 4319 char_u *name_start = *end_leader; |
4320 int keeping_dict = FALSE; | |
4317 | 4321 |
4318 for (;;) | 4322 for (;;) |
4319 { | 4323 { |
4320 char_u *p = skipwhite(*arg); | 4324 char_u *p = skipwhite(*arg); |
4321 | 4325 |
4358 *arg = skipwhite(p + 1); | 4362 *arg = skipwhite(p + 1); |
4359 if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL) | 4363 if (compile_arguments(arg, cctx, &argcount, FALSE) == FAIL) |
4360 return FAIL; | 4364 return FAIL; |
4361 if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL) | 4365 if (generate_PCALL(cctx, argcount, name_start, type, TRUE) == FAIL) |
4362 return FAIL; | 4366 return FAIL; |
4367 if (keeping_dict) | |
4368 { | |
4369 keeping_dict = FALSE; | |
4370 if (generate_instr(cctx, ISN_CLEARDICT) == NULL) | |
4371 return FAIL; | |
4372 } | |
4363 } | 4373 } |
4364 else if (*p == '-' && p[1] == '>') | 4374 else if (*p == '-' && p[1] == '>') |
4365 { | 4375 { |
4366 char_u *pstart = p; | 4376 char_u *pstart = p; |
4367 | 4377 |
4466 { | 4476 { |
4467 semsg(_(e_missing_paren), *arg); | 4477 semsg(_(e_missing_paren), *arg); |
4468 return FAIL; | 4478 return FAIL; |
4469 } | 4479 } |
4470 if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL) | 4480 if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL) |
4481 return FAIL; | |
4482 } | |
4483 if (keeping_dict) | |
4484 { | |
4485 keeping_dict = FALSE; | |
4486 if (generate_instr(cctx, ISN_CLEARDICT) == NULL) | |
4471 return FAIL; | 4487 return FAIL; |
4472 } | 4488 } |
4473 } | 4489 } |
4474 else if (**arg == '[') | 4490 else if (**arg == '[') |
4475 { | 4491 { |
4535 emsg(_(e_missbrac)); | 4551 emsg(_(e_missbrac)); |
4536 return FAIL; | 4552 return FAIL; |
4537 } | 4553 } |
4538 *arg = *arg + 1; | 4554 *arg = *arg + 1; |
4539 | 4555 |
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) | |
4541 return FAIL; | 4563 return FAIL; |
4542 } | 4564 } |
4543 else if (*p == '.' && p[1] != '.') | 4565 else if (*p == '.' && p[1] != '.') |
4544 { | 4566 { |
4545 // dictionary member: dict.name | 4567 // dictionary member: dict.name |
4560 if (p == *arg) | 4582 if (p == *arg) |
4561 { | 4583 { |
4562 semsg(_(e_syntax_error_at_str), *arg); | 4584 semsg(_(e_syntax_error_at_str), *arg); |
4563 return FAIL; | 4585 return FAIL; |
4564 } | 4586 } |
4587 if (keeping_dict && generate_instr(cctx, ISN_CLEARDICT) == NULL) | |
4588 return FAIL; | |
4565 if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL) | 4589 if (generate_STRINGMEMBER(cctx, *arg, p - *arg) == FAIL) |
4566 return FAIL; | 4590 return FAIL; |
4591 keeping_dict = TRUE; | |
4567 *arg = p; | 4592 *arg = p; |
4568 } | 4593 } |
4569 else | 4594 else |
4570 break; | 4595 break; |
4571 } | 4596 } |
4572 | 4597 |
4573 // TODO - see handle_subscript(): | |
4574 // Turn "dict.Func" into a partial for "Func" bound to "dict". | 4598 // 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 | 4599 // This needs to be done at runtime to be able to check the type. |
4576 // explicitly (pt_auto is FALSE). | 4600 if (keeping_dict && generate_instr(cctx, ISN_USEDICT) == NULL) |
4601 return FAIL; | |
4577 | 4602 |
4578 return OK; | 4603 return OK; |
4579 } | 4604 } |
4580 | 4605 |
4581 /* | 4606 /* |
6659 var_start); | 6684 var_start); |
6660 return FAIL; | 6685 return FAIL; |
6661 } | 6686 } |
6662 | 6687 |
6663 // Get the member. | 6688 // Get the member. |
6664 if (compile_member(FALSE, cctx) == FAIL) | 6689 if (compile_member(FALSE, NULL, cctx) == FAIL) |
6665 return FAIL; | 6690 return FAIL; |
6666 } | 6691 } |
6667 return OK; | 6692 return OK; |
6668 } | 6693 } |
6669 | 6694 |
10404 case ISN_BLOBSLICE: | 10429 case ISN_BLOBSLICE: |
10405 case ISN_CATCH: | 10430 case ISN_CATCH: |
10406 case ISN_CEXPR_AUCMD: | 10431 case ISN_CEXPR_AUCMD: |
10407 case ISN_CHECKLEN: | 10432 case ISN_CHECKLEN: |
10408 case ISN_CHECKNR: | 10433 case ISN_CHECKNR: |
10434 case ISN_CLEARDICT: | |
10409 case ISN_CMDMOD_REV: | 10435 case ISN_CMDMOD_REV: |
10410 case ISN_COMPAREANY: | 10436 case ISN_COMPAREANY: |
10411 case ISN_COMPAREBLOB: | 10437 case ISN_COMPAREBLOB: |
10412 case ISN_COMPAREBOOL: | 10438 case ISN_COMPAREBOOL: |
10413 case ISN_COMPAREDICT: | 10439 case ISN_COMPAREDICT: |
10480 case ISN_THROW: | 10506 case ISN_THROW: |
10481 case ISN_TRYCONT: | 10507 case ISN_TRYCONT: |
10482 case ISN_UNLETINDEX: | 10508 case ISN_UNLETINDEX: |
10483 case ISN_UNLETRANGE: | 10509 case ISN_UNLETRANGE: |
10484 case ISN_UNPACK: | 10510 case ISN_UNPACK: |
10511 case ISN_USEDICT: | |
10485 // nothing allocated | 10512 // nothing allocated |
10486 break; | 10513 break; |
10487 } | 10514 } |
10488 } | 10515 } |
10489 | 10516 |