comparison src/eval.c @ 21277:1e5c29d4e5b3 v8.2.1189

patch 8.2.1189: Vim9: line continuation in lambda doesn't always work Commit: https://github.com/vim/vim/commit/8af81d656a4c501611f6211b6379ea9dd650c545 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Jul 12 16:32:19 2020 +0200 patch 8.2.1189: Vim9: line continuation in lambda doesn't always work Problem: Vim9: line continuation in lambda doesn't always work. Solution: Do not use a local evalarg unless there isn't one. (closes https://github.com/vim/vim/issues/6439)
author Bram Moolenaar <Bram@vim.org>
date Sun, 12 Jul 2020 16:45:04 +0200
parents d1215fcdbca8
children 8d1d11afd8c8
comparison
equal deleted inserted replaced
21276:18bfb4c4732e 21277:1e5c29d4e5b3
2086 p = eval_next_non_blank(*arg, evalarg, &getnext); 2086 p = eval_next_non_blank(*arg, evalarg, &getnext);
2087 if (*p == '?') 2087 if (*p == '?')
2088 { 2088 {
2089 int result; 2089 int result;
2090 typval_T var2; 2090 typval_T var2;
2091 evalarg_T nested_evalarg; 2091 evalarg_T *evalarg_used = evalarg;
2092 evalarg_T local_evalarg;
2092 int orig_flags; 2093 int orig_flags;
2093 int evaluate; 2094 int evaluate;
2094 2095
2096 if (evalarg == NULL)
2097 {
2098 CLEAR_FIELD(local_evalarg);
2099 evalarg_used = &local_evalarg;
2100 }
2101 orig_flags = evalarg_used->eval_flags;
2102 evaluate = evalarg_used->eval_flags & EVAL_EVALUATE;
2103
2095 if (getnext) 2104 if (getnext)
2096 *arg = eval_next_line(evalarg); 2105 *arg = eval_next_line(evalarg_used);
2097 2106
2098 if (evalarg == NULL)
2099 {
2100 CLEAR_FIELD(nested_evalarg);
2101 orig_flags = 0;
2102 }
2103 else
2104 {
2105 nested_evalarg = *evalarg;
2106 orig_flags = evalarg->eval_flags;
2107 }
2108
2109 evaluate = nested_evalarg.eval_flags & EVAL_EVALUATE;
2110 result = FALSE; 2107 result = FALSE;
2111 if (evaluate) 2108 if (evaluate)
2112 { 2109 {
2113 int error = FALSE; 2110 int error = FALSE;
2114 2111
2120 } 2117 }
2121 2118
2122 /* 2119 /*
2123 * Get the second variable. Recursive! 2120 * Get the second variable. Recursive!
2124 */ 2121 */
2125 *arg = skipwhite_and_linebreak(*arg + 1, evalarg); 2122 *arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
2126 nested_evalarg.eval_flags = result ? orig_flags 2123 evalarg_used->eval_flags = result ? orig_flags
2127 : orig_flags & ~EVAL_EVALUATE; 2124 : orig_flags & ~EVAL_EVALUATE;
2128 if (eval1(arg, rettv, &nested_evalarg) == FAIL) 2125 if (eval1(arg, rettv, evalarg_used) == FAIL)
2129 return FAIL; 2126 return FAIL;
2130 2127
2131 /* 2128 /*
2132 * Check for the ":". 2129 * Check for the ":".
2133 */ 2130 */
2134 p = eval_next_non_blank(*arg, evalarg, &getnext); 2131 p = eval_next_non_blank(*arg, evalarg_used, &getnext);
2135 if (*p != ':') 2132 if (*p != ':')
2136 { 2133 {
2137 emsg(_(e_missing_colon)); 2134 emsg(_(e_missing_colon));
2138 if (evaluate && result) 2135 if (evaluate && result)
2139 clear_tv(rettv); 2136 clear_tv(rettv);
2140 return FAIL; 2137 return FAIL;
2141 } 2138 }
2142 if (getnext) 2139 if (getnext)
2143 *arg = eval_next_line(evalarg); 2140 *arg = eval_next_line(evalarg_used);
2144 2141
2145 /* 2142 /*
2146 * Get the third variable. Recursive! 2143 * Get the third variable. Recursive!
2147 */ 2144 */
2148 *arg = skipwhite_and_linebreak(*arg + 1, evalarg); 2145 *arg = skipwhite_and_linebreak(*arg + 1, evalarg_used);
2149 nested_evalarg.eval_flags = !result ? orig_flags 2146 evalarg_used->eval_flags = !result ? orig_flags
2150 : orig_flags & ~EVAL_EVALUATE; 2147 : orig_flags & ~EVAL_EVALUATE;
2151 if (eval1(arg, &var2, &nested_evalarg) == FAIL) 2148 if (eval1(arg, &var2, evalarg_used) == FAIL)
2152 { 2149 {
2153 if (evaluate && result) 2150 if (evaluate && result)
2154 clear_tv(rettv); 2151 clear_tv(rettv);
2155 return FAIL; 2152 return FAIL;
2156 } 2153 }
2157 if (evaluate && !result) 2154 if (evaluate && !result)
2158 *rettv = var2; 2155 *rettv = var2;
2156
2157 if (evalarg == NULL)
2158 clear_evalarg(&local_evalarg, NULL);
2159 else
2160 evalarg->eval_flags = orig_flags;
2159 } 2161 }
2160 2162
2161 return OK; 2163 return OK;
2162 } 2164 }
2163 2165
2173 static int 2175 static int
2174 eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg) 2176 eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2175 { 2177 {
2176 char_u *p; 2178 char_u *p;
2177 int getnext; 2179 int getnext;
2178 typval_T var2;
2179 long result;
2180 int first;
2181 int error = FALSE;
2182 2180
2183 /* 2181 /*
2184 * Get the first variable. 2182 * Get the first variable.
2185 */ 2183 */
2186 if (eval3(arg, rettv, evalarg) == FAIL) 2184 if (eval3(arg, rettv, evalarg) == FAIL)
2187 return FAIL; 2185 return FAIL;
2188 2186
2189 /* 2187 /*
2190 * Repeat until there is no following "||". 2188 * Handle the "||" operator.
2191 */ 2189 */
2192 first = TRUE;
2193 result = FALSE;
2194 p = eval_next_non_blank(*arg, evalarg, &getnext); 2190 p = eval_next_non_blank(*arg, evalarg, &getnext);
2195 while (p[0] == '|' && p[1] == '|') 2191 if (p[0] == '|' && p[1] == '|')
2196 { 2192 {
2197 evalarg_T nested_evalarg; 2193 evalarg_T *evalarg_used = evalarg;
2194 evalarg_T local_evalarg;
2198 int evaluate; 2195 int evaluate;
2199 int orig_flags; 2196 int orig_flags;
2200 2197 long result = FALSE;
2201 if (getnext) 2198 typval_T var2;
2202 *arg = eval_next_line(evalarg); 2199 int error;
2203 2200
2204 if (evalarg == NULL) 2201 if (evalarg == NULL)
2205 { 2202 {
2206 CLEAR_FIELD(nested_evalarg); 2203 CLEAR_FIELD(local_evalarg);
2207 orig_flags = 0; 2204 evalarg_used = &local_evalarg;
2208 evaluate = FALSE; 2205 }
2209 } 2206 orig_flags = evalarg_used->eval_flags;
2210 else 2207 evaluate = orig_flags & EVAL_EVALUATE;
2211 { 2208 if (evaluate)
2212 nested_evalarg = *evalarg; 2209 {
2213 orig_flags = evalarg->eval_flags; 2210 error = FALSE;
2214 evaluate = orig_flags & EVAL_EVALUATE;
2215 }
2216
2217 if (evaluate && first)
2218 {
2219 if (tv_get_number_chk(rettv, &error) != 0) 2211 if (tv_get_number_chk(rettv, &error) != 0)
2220 result = TRUE; 2212 result = TRUE;
2221 clear_tv(rettv); 2213 clear_tv(rettv);
2222 if (error) 2214 if (error)
2223 return FAIL; 2215 return FAIL;
2224 first = FALSE;
2225 } 2216 }
2226 2217
2227 /* 2218 /*
2228 * Get the second variable. 2219 * Repeat until there is no following "||".
2229 */ 2220 */
2230 *arg = skipwhite_and_linebreak(*arg + 2, evalarg); 2221 while (p[0] == '|' && p[1] == '|')
2231 nested_evalarg.eval_flags = !result ? orig_flags 2222 {
2223 if (getnext)
2224 *arg = eval_next_line(evalarg_used);
2225
2226 /*
2227 * Get the second variable.
2228 */
2229 *arg = skipwhite_and_linebreak(*arg + 2, evalarg_used);
2230 evalarg_used->eval_flags = !result ? orig_flags
2232 : orig_flags & ~EVAL_EVALUATE; 2231 : orig_flags & ~EVAL_EVALUATE;
2233 if (eval3(arg, &var2, &nested_evalarg) == FAIL) 2232 if (eval3(arg, &var2, evalarg_used) == FAIL)
2234 return FAIL;
2235
2236 /*
2237 * Compute the result.
2238 */
2239 if (evaluate && !result)
2240 {
2241 if (tv_get_number_chk(&var2, &error) != 0)
2242 result = TRUE;
2243 clear_tv(&var2);
2244 if (error)
2245 return FAIL; 2233 return FAIL;
2246 } 2234
2247 if (evaluate) 2235 /*
2248 { 2236 * Compute the result.
2249 rettv->v_type = VAR_NUMBER; 2237 */
2250 rettv->vval.v_number = result; 2238 if (evaluate && !result)
2251 } 2239 {
2252 2240 if (tv_get_number_chk(&var2, &error) != 0)
2253 p = eval_next_non_blank(*arg, evalarg, &getnext); 2241 result = TRUE;
2242 clear_tv(&var2);
2243 if (error)
2244 return FAIL;
2245 }
2246 if (evaluate)
2247 {
2248 rettv->v_type = VAR_NUMBER;
2249 rettv->vval.v_number = result;
2250 }
2251
2252 p = eval_next_non_blank(*arg, evalarg_used, &getnext);
2253 }
2254
2255 if (evalarg == NULL)
2256 clear_evalarg(&local_evalarg, NULL);
2257 else
2258 evalarg->eval_flags = orig_flags;
2254 } 2259 }
2255 2260
2256 return OK; 2261 return OK;
2257 } 2262 }
2258 2263
2268 static int 2273 static int
2269 eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg) 2274 eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
2270 { 2275 {
2271 char_u *p; 2276 char_u *p;
2272 int getnext; 2277 int getnext;
2273 typval_T var2;
2274 long result;
2275 int first;
2276 int error = FALSE;
2277 2278
2278 /* 2279 /*
2279 * Get the first variable. 2280 * Get the first variable.
2280 */ 2281 */
2281 if (eval4(arg, rettv, evalarg) == FAIL) 2282 if (eval4(arg, rettv, evalarg) == FAIL)
2282 return FAIL; 2283 return FAIL;
2283 2284
2284 /* 2285 /*
2285 * Repeat until there is no following "&&". 2286 * Handle the "&&" operator.
2286 */ 2287 */
2287 first = TRUE;
2288 result = TRUE;
2289 p = eval_next_non_blank(*arg, evalarg, &getnext); 2288 p = eval_next_non_blank(*arg, evalarg, &getnext);
2290 while (p[0] == '&' && p[1] == '&') 2289 if (p[0] == '&' && p[1] == '&')
2291 { 2290 {
2292 evalarg_T nested_evalarg; 2291 evalarg_T *evalarg_used = evalarg;
2292 evalarg_T local_evalarg;
2293 int orig_flags; 2293 int orig_flags;
2294 int evaluate; 2294 int evaluate;
2295 2295 long result = TRUE;
2296 if (getnext) 2296 typval_T var2;
2297 *arg = eval_next_line(evalarg); 2297 int error;
2298 2298
2299 if (evalarg == NULL) 2299 if (evalarg == NULL)
2300 { 2300 {
2301 CLEAR_FIELD(nested_evalarg); 2301 CLEAR_FIELD(local_evalarg);
2302 orig_flags = 0; 2302 evalarg_used = &local_evalarg;
2303 evaluate = FALSE; 2303 }
2304 } 2304 orig_flags = evalarg_used->eval_flags;
2305 else 2305 evaluate = orig_flags & EVAL_EVALUATE;
2306 { 2306 if (evaluate)
2307 nested_evalarg = *evalarg; 2307 {
2308 orig_flags = evalarg->eval_flags; 2308 error = FALSE;
2309 evaluate = orig_flags & EVAL_EVALUATE;
2310 }
2311 if (evaluate && first)
2312 {
2313 if (tv_get_number_chk(rettv, &error) == 0) 2309 if (tv_get_number_chk(rettv, &error) == 0)
2314 result = FALSE; 2310 result = FALSE;
2315 clear_tv(rettv); 2311 clear_tv(rettv);
2316 if (error) 2312 if (error)
2317 return FAIL; 2313 return FAIL;
2318 first = FALSE;
2319 } 2314 }
2320 2315
2321 /* 2316 /*
2322 * Get the second variable. 2317 * Repeat until there is no following "&&".
2323 */ 2318 */
2324 *arg = skipwhite_and_linebreak(*arg + 2, evalarg); 2319 while (p[0] == '&' && p[1] == '&')
2325 nested_evalarg.eval_flags = result ? orig_flags 2320 {
2321 if (getnext)
2322 *arg = eval_next_line(evalarg_used);
2323
2324 /*
2325 * Get the second variable.
2326 */
2327 *arg = skipwhite_and_linebreak(*arg + 2, evalarg_used);
2328 evalarg_used->eval_flags = result ? orig_flags
2326 : orig_flags & ~EVAL_EVALUATE; 2329 : orig_flags & ~EVAL_EVALUATE;
2327 if (eval4(arg, &var2, &nested_evalarg) == FAIL) 2330 if (eval4(arg, &var2, evalarg_used) == FAIL)
2328 return FAIL;
2329
2330 /*
2331 * Compute the result.
2332 */
2333 if (evaluate && result)
2334 {
2335 if (tv_get_number_chk(&var2, &error) == 0)
2336 result = FALSE;
2337 clear_tv(&var2);
2338 if (error)
2339 return FAIL; 2331 return FAIL;
2340 } 2332
2341 if (evaluate) 2333 /*
2342 { 2334 * Compute the result.
2343 rettv->v_type = VAR_NUMBER; 2335 */
2344 rettv->vval.v_number = result; 2336 if (evaluate && result)
2345 } 2337 {
2346 2338 if (tv_get_number_chk(&var2, &error) == 0)
2347 p = eval_next_non_blank(*arg, evalarg, &getnext); 2339 result = FALSE;
2340 clear_tv(&var2);
2341 if (error)
2342 return FAIL;
2343 }
2344 if (evaluate)
2345 {
2346 rettv->v_type = VAR_NUMBER;
2347 rettv->vval.v_number = result;
2348 }
2349
2350 p = eval_next_non_blank(*arg, evalarg_used, &getnext);
2351 }
2352
2353 if (evalarg == NULL)
2354 clear_evalarg(&local_evalarg, NULL);
2355 else
2356 evalarg->eval_flags = orig_flags;
2348 } 2357 }
2349 2358
2350 return OK; 2359 return OK;
2351 } 2360 }
2352 2361