Mercurial > vim
comparison src/evalvars.c @ 20859:876e16c48bd1 v8.2.0981
patch 8.2.0981: Vim9: cannot compile "[var, var] = list"
Commit: https://github.com/vim/vim/commit/47a519a933e8bcaf703a5feaac5c01491a658ee3
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jun 14 23:05:10 2020 +0200
patch 8.2.0981: Vim9: cannot compile "[var, var] = list"
Problem: Vim9: cannot compile "[var, var] = list".
Solution: Implement list assignment.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 14 Jun 2020 23:15:04 +0200 |
parents | bacc2ab11810 |
children | 69055d27e85e |
comparison
equal
deleted
inserted
replaced
20858:e20d1d3b411c | 20859:876e16c48bd1 |
---|---|
162 #define vimvarht vimvardict.dv_hashtab | 162 #define vimvarht vimvardict.dv_hashtab |
163 | 163 |
164 // for VIM_VERSION_ defines | 164 // for VIM_VERSION_ defines |
165 #include "version.h" | 165 #include "version.h" |
166 | 166 |
167 static char_u *skip_var_one(char_u *arg, int include_type); | |
168 static void list_glob_vars(int *first); | 167 static void list_glob_vars(int *first); |
169 static void list_buf_vars(int *first); | 168 static void list_buf_vars(int *first); |
170 static void list_win_vars(int *first); | 169 static void list_win_vars(int *first); |
171 static void list_tab_vars(int *first); | 170 static void list_tab_vars(int *first); |
172 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); | 171 static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first); |
707 | 706 |
708 // detect Vim9 assignment without ":let" or ":const" | 707 // detect Vim9 assignment without ":let" or ":const" |
709 if (eap->arg == eap->cmd) | 708 if (eap->arg == eap->cmd) |
710 flags |= LET_NO_COMMAND; | 709 flags |= LET_NO_COMMAND; |
711 | 710 |
712 argend = skip_var_list(arg, TRUE, &var_count, &semicolon); | 711 argend = skip_var_list(arg, TRUE, &var_count, &semicolon, FALSE); |
713 if (argend == NULL) | 712 if (argend == NULL) |
714 return; | 713 return; |
715 if (argend > arg && argend[-1] == '.') // for var.='str' | 714 if (argend > arg && argend[-1] == '.') // for var.='str' |
716 --argend; | 715 --argend; |
717 expr = skipwhite(argend); | 716 expr = skipwhite(argend); |
914 | 913 |
915 /* | 914 /* |
916 * Skip over assignable variable "var" or list of variables "[var, var]". | 915 * Skip over assignable variable "var" or list of variables "[var, var]". |
917 * Used for ":let varvar = expr" and ":for varvar in expr". | 916 * Used for ":let varvar = expr" and ":for varvar in expr". |
918 * For "[var, var]" increment "*var_count" for each variable. | 917 * For "[var, var]" increment "*var_count" for each variable. |
919 * for "[var, var; var]" set "semicolon". | 918 * for "[var, var; var]" set "semicolon" to 1. |
919 * If "silent" is TRUE do not give an "invalid argument" error message. | |
920 * Return NULL for an error. | 920 * Return NULL for an error. |
921 */ | 921 */ |
922 char_u * | 922 char_u * |
923 skip_var_list( | 923 skip_var_list( |
924 char_u *arg, | 924 char_u *arg, |
925 int include_type, | 925 int include_type, |
926 int *var_count, | 926 int *var_count, |
927 int *semicolon) | 927 int *semicolon, |
928 int silent) | |
928 { | 929 { |
929 char_u *p, *s; | 930 char_u *p, *s; |
930 | 931 |
931 if (*arg == '[') | 932 if (*arg == '[') |
932 { | 933 { |
933 // "[var, var]": find the matching ']'. | 934 // "[var, var]": find the matching ']'. |
934 p = arg; | 935 p = arg; |
935 for (;;) | 936 for (;;) |
936 { | 937 { |
937 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' | 938 p = skipwhite(p + 1); // skip whites after '[', ';' or ',' |
938 s = skip_var_one(p, TRUE); | 939 s = skip_var_one(p, FALSE); |
939 if (s == p) | 940 if (s == p) |
940 { | 941 { |
941 semsg(_(e_invarg2), p); | 942 if (!silent) |
943 semsg(_(e_invarg2), p); | |
942 return NULL; | 944 return NULL; |
943 } | 945 } |
944 ++*var_count; | 946 ++*var_count; |
945 | 947 |
946 p = skipwhite(s); | 948 p = skipwhite(s); |
955 } | 957 } |
956 *semicolon = 1; | 958 *semicolon = 1; |
957 } | 959 } |
958 else if (*p != ',') | 960 else if (*p != ',') |
959 { | 961 { |
960 semsg(_(e_invarg2), p); | 962 if (!silent) |
963 semsg(_(e_invarg2), p); | |
961 return NULL; | 964 return NULL; |
962 } | 965 } |
963 } | 966 } |
964 return p + 1; | 967 return p + 1; |
965 } | 968 } |
970 /* | 973 /* |
971 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, | 974 * Skip one (assignable) variable name, including @r, $VAR, &option, d.key, |
972 * l[idx]. | 975 * l[idx]. |
973 * In Vim9 script also skip over ": type" if "include_type" is TRUE. | 976 * In Vim9 script also skip over ": type" if "include_type" is TRUE. |
974 */ | 977 */ |
975 static char_u * | 978 char_u * |
976 skip_var_one(char_u *arg, int include_type) | 979 skip_var_one(char_u *arg, int include_type) |
977 { | 980 { |
978 char_u *end; | 981 char_u *end; |
979 | 982 |
980 if (*arg == '@' && arg[1] != NUL) | 983 if (*arg == '@' && arg[1] != NUL) |
981 return arg + 2; | 984 return arg + 2; |
982 end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, | 985 end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, |
983 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); | 986 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); |
984 if (include_type && current_sctx.sc_version == SCRIPT_VERSION_VIM9 | 987 if (include_type && current_sctx.sc_version == SCRIPT_VERSION_VIM9) |
985 && *end == ':') | 988 { |
986 { | 989 // "a: type" is declaring variable "a" with a type, not "a:". |
987 end = skip_type(skipwhite(end + 1)); | 990 if (end == arg + 2 && end[-1] == ':') |
991 --end; | |
992 if (*end == ':') | |
993 end = skip_type(skipwhite(end + 1)); | |
988 } | 994 } |
989 return end; | 995 return end; |
990 } | 996 } |
991 | 997 |
992 /* | 998 /* |