Mercurial > vim
comparison src/list.c @ 20649:1fa0ace0ba65 v8.2.0878
patch 8.2.0878: no reduce() function
Commit: https://github.com/vim/vim/commit/85629985b71035608a37ba3bde86968481490d46
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jun 1 18:39:20 2020 +0200
patch 8.2.0878: no reduce() function
Problem: No reduce() function.
Solution: Add a reduce() function. (closes https://github.com/vim/vim/issues/5481)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 01 Jun 2020 18:45:03 +0200 |
parents | 09143ab0fbbd |
children | a1e6d9353736 |
comparison
equal
deleted
inserted
replaced
20648:78db823f74d0 | 20649:1fa0ace0ba65 |
---|---|
2303 rettv_list_set(rettv, l); | 2303 rettv_list_set(rettv, l); |
2304 l->lv_u.mat.lv_idx = l->lv_len - l->lv_u.mat.lv_idx - 1; | 2304 l->lv_u.mat.lv_idx = l->lv_len - l->lv_u.mat.lv_idx - 1; |
2305 } | 2305 } |
2306 } | 2306 } |
2307 | 2307 |
2308 /* | |
2309 * "reduce(list, { accumlator, element -> value } [, initial])" function | |
2310 */ | |
2311 void | |
2312 f_reduce(typval_T *argvars, typval_T *rettv) | |
2313 { | |
2314 typval_T accum; | |
2315 char_u *func_name; | |
2316 partial_T *partial = NULL; | |
2317 funcexe_T funcexe; | |
2318 typval_T argv[3]; | |
2319 | |
2320 if (argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) | |
2321 { | |
2322 emsg(_(e_listblobreq)); | |
2323 return; | |
2324 } | |
2325 | |
2326 if (argvars[1].v_type == VAR_FUNC) | |
2327 func_name = argvars[1].vval.v_string; | |
2328 else if (argvars[1].v_type == VAR_PARTIAL) | |
2329 { | |
2330 partial = argvars[1].vval.v_partial; | |
2331 func_name = partial_name(partial); | |
2332 } | |
2333 else | |
2334 func_name = tv_get_string(&argvars[1]); | |
2335 if (*func_name == NUL) | |
2336 return; // type error or empty name | |
2337 | |
2338 vim_memset(&funcexe, 0, sizeof(funcexe)); | |
2339 funcexe.evaluate = TRUE; | |
2340 funcexe.partial = partial; | |
2341 | |
2342 if (argvars[0].v_type == VAR_LIST) | |
2343 { | |
2344 list_T *l = argvars[0].vval.v_list; | |
2345 listitem_T *li = NULL; | |
2346 | |
2347 CHECK_LIST_MATERIALIZE(l); | |
2348 if (argvars[2].v_type == VAR_UNKNOWN) | |
2349 { | |
2350 if (l == NULL || l->lv_first == NULL) | |
2351 { | |
2352 semsg(_(e_reduceempty), "List"); | |
2353 return; | |
2354 } | |
2355 accum = l->lv_first->li_tv; | |
2356 li = l->lv_first->li_next; | |
2357 } | |
2358 else | |
2359 { | |
2360 accum = argvars[2]; | |
2361 if (l != NULL) | |
2362 li = l->lv_first; | |
2363 } | |
2364 | |
2365 copy_tv(&accum, rettv); | |
2366 for ( ; li != NULL; li = li->li_next) | |
2367 { | |
2368 argv[0] = accum; | |
2369 argv[1] = li->li_tv; | |
2370 if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) | |
2371 return; | |
2372 accum = *rettv; | |
2373 } | |
2374 } | |
2375 else | |
2376 { | |
2377 blob_T *b = argvars[0].vval.v_blob; | |
2378 int i; | |
2379 | |
2380 if (argvars[2].v_type == VAR_UNKNOWN) | |
2381 { | |
2382 if (b == NULL || b->bv_ga.ga_len == 0) | |
2383 { | |
2384 semsg(_(e_reduceempty), "Blob"); | |
2385 return; | |
2386 } | |
2387 accum.v_type = VAR_NUMBER; | |
2388 accum.vval.v_number = blob_get(b, 0); | |
2389 i = 1; | |
2390 } | |
2391 else | |
2392 { | |
2393 accum = argvars[2]; | |
2394 i = 0; | |
2395 } | |
2396 | |
2397 copy_tv(&accum, rettv); | |
2398 if (b != NULL) | |
2399 { | |
2400 for ( ; i < b->bv_ga.ga_len; i++) | |
2401 { | |
2402 argv[0] = accum; | |
2403 argv[1].v_type = VAR_NUMBER; | |
2404 argv[1].vval.v_number = blob_get(b, i); | |
2405 if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) | |
2406 return; | |
2407 accum = *rettv; | |
2408 } | |
2409 } | |
2410 } | |
2411 } | |
2412 | |
2308 #endif // defined(FEAT_EVAL) | 2413 #endif // defined(FEAT_EVAL) |