Mercurial > vim
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 |