comparison src/vim9compile.c @ 23033:b98003d73150 v8.2.2063

patch 8.2.2063: Vim9: only one level of indexing supported Commit: https://github.com/vim/vim/commit/dc234caff22131bdc1ff9ea50d67e11843d0d73e Author: Bram Moolenaar <Bram@vim.org> Date: Sat Nov 28 18:52:33 2020 +0100 patch 8.2.2063: Vim9: only one level of indexing supported Problem: Vim9: only one level of indexing supported. Solution: Handle more than one index in an assignment.
author Bram Moolenaar <Bram@vim.org>
date Sat, 28 Nov 2020 19:00:04 +0100
parents a943b175586a
children 9775df18916b
comparison
equal deleted inserted replaced
23032:52326852b941 23033:b98003d73150
4959 dest_window, 4959 dest_window,
4960 dest_tab, 4960 dest_tab,
4961 dest_vimvar, 4961 dest_vimvar,
4962 dest_script, 4962 dest_script,
4963 dest_reg, 4963 dest_reg,
4964 dest_expr,
4964 } assign_dest_T; 4965 } assign_dest_T;
4965 4966
4966 /* 4967 /*
4967 * Generate the load instruction for "name". 4968 * Generate the load instruction for "name".
4968 */ 4969 */
5011 generate_LOAD(cctx, ISN_LOADOUTER, lvar->lv_idx, 5012 generate_LOAD(cctx, ISN_LOADOUTER, lvar->lv_idx,
5012 NULL, type); 5013 NULL, type);
5013 else 5014 else
5014 generate_LOAD(cctx, ISN_LOAD, lvar->lv_idx, NULL, type); 5015 generate_LOAD(cctx, ISN_LOAD, lvar->lv_idx, NULL, type);
5015 break; 5016 break;
5016 } 5017 case dest_expr:
5018 // list or dict value should already be on the stack.
5019 break;
5020 }
5021 }
5022
5023 /*
5024 * Skip over "[expr]" or ".member".
5025 * Does not check for any errors.
5026 */
5027 static char_u *
5028 skip_index(char_u *start)
5029 {
5030 char_u *p = start;
5031
5032 if (*p == '[')
5033 {
5034 p = skipwhite(p + 1);
5035 (void)skip_expr(&p, NULL);
5036 p = skipwhite(p);
5037 if (*p == ']')
5038 return p + 1;
5039 return p;
5040 }
5041 // if (*p == '.')
5042 return to_name_end(p + 1, TRUE);
5017 } 5043 }
5018 5044
5019 void 5045 void
5020 vim9_declare_error(char_u *name) 5046 vim9_declare_error(char_u *name)
5021 { 5047 {
5067 char_u *op; 5093 char_u *op;
5068 int oplen = 0; 5094 int oplen = 0;
5069 int heredoc = FALSE; 5095 int heredoc = FALSE;
5070 type_T *type = &t_any; 5096 type_T *type = &t_any;
5071 type_T *member_type = &t_any; 5097 type_T *member_type = &t_any;
5098 type_T *rhs_type = &t_any;
5072 char_u *name = NULL; 5099 char_u *name = NULL;
5073 char_u *sp; 5100 char_u *sp;
5074 int is_decl = cmdidx == CMD_let || cmdidx == CMD_var 5101 int is_decl = cmdidx == CMD_let || cmdidx == CMD_var
5075 || cmdidx == CMD_final || cmdidx == CMD_const; 5102 || cmdidx == CMD_final || cmdidx == CMD_const;
5076 5103
5155 FALSE, FALSE) == FAIL) 5182 FALSE, FALSE) == FAIL)
5156 goto theend; 5183 goto theend;
5157 // TODO: check the length of a constant list here 5184 // TODO: check the length of a constant list here
5158 generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count, 5185 generate_CHECKLEN(cctx, semicolon ? var_count - 1 : var_count,
5159 semicolon); 5186 semicolon);
5187 if (stacktype->tt_member != NULL)
5188 rhs_type = stacktype->tt_member;
5160 } 5189 }
5161 } 5190 }
5162 5191
5163 /* 5192 /*
5164 * Loop over variables in "[var, var] = expr". 5193 * Loop over variables in "[var, var] = expr".
5465 5494
5466 member_type = type; 5495 member_type = type;
5467 if (var_end > var_start + varlen) 5496 if (var_end > var_start + varlen)
5468 { 5497 {
5469 // Something follows after the variable: "var[idx]" or "var.key". 5498 // Something follows after the variable: "var[idx]" or "var.key".
5499 // TODO: should we also handle "->func()" here?
5470 if (is_decl) 5500 if (is_decl)
5471 { 5501 {
5472 emsg(_(e_cannot_use_index_when_declaring_variable)); 5502 emsg(_(e_cannot_use_index_when_declaring_variable));
5473 goto theend; 5503 goto theend;
5474 } 5504 }
5475 5505
5476 if (var_start[varlen] == '[' || var_start[varlen] == '.') 5506 if (var_start[varlen] == '[' || var_start[varlen] == '.')
5477 { 5507 {
5508 char_u *after = var_start + varlen;
5509
5510 // Only the last index is used below, if there are others
5511 // before it generate code for the expression. Thus for
5512 // "ll[1][2]" the expression is "ll[1]" and "[2]" is the index.
5513 for (;;)
5514 {
5515 p = skip_index(after);
5516 if (*p != '[' && *p != '.')
5517 break;
5518 after = p;
5519 }
5520 if (after > var_start + varlen)
5521 {
5522 varlen = after - var_start;
5523 dest = dest_expr;
5524 // We don't know the type before evaluating the expression,
5525 // use "any" until then.
5526 type = &t_any;
5527 }
5528
5478 has_index = TRUE; 5529 has_index = TRUE;
5479 if (type->tt_member == NULL) 5530 if (type->tt_member == NULL)
5480 member_type = &t_any; 5531 member_type = &t_any;
5481 else 5532 else
5482 member_type = type->tt_member; 5533 member_type = type->tt_member;
5509 compile_expr0(&p, cctx); 5560 compile_expr0(&p, cctx);
5510 } 5561 }
5511 } 5562 }
5512 else if (oplen > 0) 5563 else if (oplen > 0)
5513 { 5564 {
5514 type_T *stacktype;
5515 int is_const = FALSE; 5565 int is_const = FALSE;
5516 5566
5517 // For "var = expr" evaluate the expression. 5567 // For "var = expr" evaluate the expression.
5518 if (var_count == 0) 5568 if (var_count == 0)
5519 { 5569 {
5556 // list. 5606 // list.
5557 if (generate_GETITEM(cctx, var_idx) == FAIL) 5607 if (generate_GETITEM(cctx, var_idx) == FAIL)
5558 return FAIL; 5608 return FAIL;
5559 } 5609 }
5560 5610
5561 stacktype = stack->ga_len == 0 ? &t_void 5611 rhs_type = stack->ga_len == 0 ? &t_void
5562 : ((type_T **)stack->ga_data)[stack->ga_len - 1]; 5612 : ((type_T **)stack->ga_data)[stack->ga_len - 1];
5563 if (lvar != NULL && (is_decl || !has_type)) 5613 if (lvar != NULL && (is_decl || !has_type))
5564 { 5614 {
5565 if ((stacktype->tt_type == VAR_FUNC 5615 if ((rhs_type->tt_type == VAR_FUNC
5566 || stacktype->tt_type == VAR_PARTIAL) 5616 || rhs_type->tt_type == VAR_PARTIAL)
5567 && var_wrong_func_name(name, TRUE)) 5617 && var_wrong_func_name(name, TRUE))
5568 goto theend; 5618 goto theend;
5569 5619
5570 if (new_local && !has_type) 5620 if (new_local && !has_type)
5571 { 5621 {
5572 if (stacktype->tt_type == VAR_VOID) 5622 if (rhs_type->tt_type == VAR_VOID)
5573 { 5623 {
5574 emsg(_(e_cannot_use_void_value)); 5624 emsg(_(e_cannot_use_void_value));
5575 goto theend; 5625 goto theend;
5576 } 5626 }
5577 else 5627 else
5578 { 5628 {
5579 // An empty list or dict has a &t_unknown member, 5629 // An empty list or dict has a &t_unknown member,
5580 // for a variable that implies &t_any. 5630 // for a variable that implies &t_any.
5581 if (stacktype == &t_list_empty) 5631 if (rhs_type == &t_list_empty)
5582 lvar->lv_type = &t_list_any; 5632 lvar->lv_type = &t_list_any;
5583 else if (stacktype == &t_dict_empty) 5633 else if (rhs_type == &t_dict_empty)
5584 lvar->lv_type = &t_dict_any; 5634 lvar->lv_type = &t_dict_any;
5585 else if (stacktype == &t_unknown) 5635 else if (rhs_type == &t_unknown)
5586 lvar->lv_type = &t_any; 5636 lvar->lv_type = &t_any;
5587 else 5637 else
5588 lvar->lv_type = stacktype; 5638 lvar->lv_type = rhs_type;
5589 } 5639 }
5590 } 5640 }
5591 else if (*op == '=') 5641 else if (*op == '=')
5592 { 5642 {
5593 type_T *use_type = lvar->lv_type; 5643 type_T *use_type = lvar->lv_type;
5594 5644
5595 // without operator check type here, otherwise below 5645 // without operator check type here, otherwise below
5596 if (has_index) 5646 if (has_index)
5597 { 5647 {
5598 use_type = use_type->tt_member; 5648 use_type = member_type;
5599 if (use_type == NULL) 5649 if (member_type == NULL)
5600 // could be indexing "any" 5650 // could be indexing "any"
5601 use_type = &t_any; 5651 use_type = &t_any;
5602 } 5652 }
5603 if (need_type(stacktype, use_type, -1, cctx, 5653 if (need_type(rhs_type, use_type, -1, cctx,
5604 FALSE, is_const) == FAIL) 5654 FALSE, is_const) == FAIL)
5605 goto theend; 5655 goto theend;
5606 } 5656 }
5607 } 5657 }
5608 else if (*p != '=' && need_type(stacktype, member_type, -1, 5658 else if (*p != '=' && need_type(rhs_type, member_type, -1,
5609 cctx, FALSE, FALSE) == FAIL) 5659 cctx, FALSE, FALSE) == FAIL)
5610 goto theend; 5660 goto theend;
5611 } 5661 }
5612 else if (cmdidx == CMD_final) 5662 else if (cmdidx == CMD_final)
5613 { 5663 {
5769 5819
5770 // Load the dict or list. On the stack we then have: 5820 // Load the dict or list. On the stack we then have:
5771 // - value 5821 // - value
5772 // - index 5822 // - index
5773 // - variable 5823 // - variable
5774 generate_loadvar(cctx, dest, name, lvar, type); 5824 if (dest == dest_expr)
5825 {
5826 int c = var_start[varlen];
5827
5828 // Evaluate "ll[expr]" of "ll[expr][idx]"
5829 p = var_start;
5830 var_start[varlen] = NUL;
5831 if (compile_expr0(&p, cctx) == OK && p != var_start + varlen)
5832 {
5833 // this should not happen
5834 emsg(_(e_missbrac));
5835 goto theend;
5836 }
5837 var_start[varlen] = c;
5838
5839 type = stack->ga_len == 0 ? &t_void
5840 : ((type_T **)stack->ga_data)[stack->ga_len - 1];
5841 // now we can properly check the type
5842 if (type->tt_member != NULL
5843 && need_type(rhs_type, type->tt_member, -2, cctx,
5844 FALSE, FALSE) == FAIL)
5845 goto theend;
5846 }
5847 else
5848 generate_loadvar(cctx, dest, name, lvar, type);
5775 5849
5776 if (type->tt_type == VAR_LIST) 5850 if (type->tt_type == VAR_LIST)
5777 { 5851 {
5778 if (generate_instr_drop(cctx, ISN_STORELIST, 3) == FAIL) 5852 if (generate_instr_drop(cctx, ISN_STORELIST, 3) == FAIL)
5779 return FAIL; 5853 return FAIL;
5783 if (generate_instr_drop(cctx, ISN_STOREDICT, 3) == FAIL) 5857 if (generate_instr_drop(cctx, ISN_STOREDICT, 3) == FAIL)
5784 return FAIL; 5858 return FAIL;
5785 } 5859 }
5786 else 5860 else
5787 { 5861 {
5788 emsg(_(e_listreq)); 5862 emsg(_(e_indexable_type_required));
5789 goto theend; 5863 goto theend;
5790 } 5864 }
5791 } 5865 }
5792 else 5866 else
5793 { 5867 {
5879 generate_STORE(cctx, ISN_STOREOUTER, lvar->lv_idx, 5953 generate_STORE(cctx, ISN_STOREOUTER, lvar->lv_idx,
5880 NULL); 5954 NULL);
5881 else 5955 else
5882 generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); 5956 generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
5883 } 5957 }
5958 break;
5959 case dest_expr:
5960 // cannot happen
5884 break; 5961 break;
5885 } 5962 }
5886 } 5963 }
5887 5964
5888 if (var_idx + 1 < var_count) 5965 if (var_idx + 1 < var_count)