Mercurial > vim
comparison src/evalfunc.c @ 34126:da670b1549b3 v9.1.0027
patch 9.1.0027: Vim is missing a foreach() func
Commit: https://github.com/vim/vim/commit/e79e2077607e8f829ba823308c91104a795736ba
Author: Ernie Rael <errael@raelity.com>
Date: Sat Jan 13 11:47:33 2024 +0100
patch 9.1.0027: Vim is missing a foreach() func
Problem: Vim is missing a foreach() func
Solution: Implement foreach({expr1}, {expr2}) function,
which applies {expr2} for each item in {expr1}
without changing it (Ernie Rael)
closes: #12166
Signed-off-by: Ernie Rael <errael@raelity.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 13 Jan 2024 12:00:06 +0100 |
parents | 034445b3af10 |
children | cce6b834635c |
comparison
equal
deleted
inserted
replaced
34125:93171f4925c5 | 34126:da670b1549b3 |
---|---|
605 return FAIL; | 605 return FAIL; |
606 return arg_type_modifiable(type, context->arg_idx + 1); | 606 return arg_type_modifiable(type, context->arg_idx + 1); |
607 } | 607 } |
608 | 608 |
609 /* | 609 /* |
610 * Check second argument of map() or filter(). | 610 * Check second argument of map(), filter(), foreach(). |
611 */ | 611 */ |
612 static int | 612 static int |
613 check_map_filter_arg2(type_T *type, argcontext_T *context, int is_map) | 613 check_map_filter_arg2(type_T *type, argcontext_T *context, |
614 filtermap_T filtermap) | |
614 { | 615 { |
615 type_T *expected_member = NULL; | 616 type_T *expected_member = NULL; |
616 type_T *(args[2]); | 617 type_T *(args[2]); |
617 type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, NULL, args}; | 618 type_T t_func_exp = {VAR_FUNC, 2, 0, 0, NULL, NULL, args}; |
618 | 619 |
661 | 662 |
662 if (!type_any_or_unknown(type->tt_member) || args[0] != NULL) | 663 if (!type_any_or_unknown(type->tt_member) || args[0] != NULL) |
663 { | 664 { |
664 where_T where = WHERE_INIT; | 665 where_T where = WHERE_INIT; |
665 | 666 |
666 if (is_map) | 667 if (filtermap == FILTERMAP_MAP) |
667 t_func_exp.tt_member = expected_member == NULL | 668 t_func_exp.tt_member = expected_member == NULL |
668 || type_any_or_unknown(type->tt_member) | 669 || type_any_or_unknown(type->tt_member) |
669 ? &t_any : expected_member; | 670 ? &t_any : expected_member; |
670 else | 671 else if (filtermap == FILTERMAP_FILTER) |
671 t_func_exp.tt_member = &t_bool; | 672 t_func_exp.tt_member = &t_bool; |
673 else // filtermap == FILTERMAP_FOREACH | |
674 t_func_exp.tt_member = &t_unknown; | |
672 if (args[0] == NULL) | 675 if (args[0] == NULL) |
673 args[0] = &t_unknown; | 676 args[0] = &t_unknown; |
674 if (type->tt_argcount == -1) | 677 if (type->tt_argcount == -1) |
675 t_func_exp.tt_argcount = -1; | 678 t_func_exp.tt_argcount = -1; |
676 | 679 |
691 || type->tt_type == VAR_PARTIAL | 694 || type->tt_type == VAR_PARTIAL |
692 || type_any_or_unknown(type)) | 695 || type_any_or_unknown(type)) |
693 return OK; | 696 return OK; |
694 | 697 |
695 if (type->tt_type == VAR_FUNC) | 698 if (type->tt_type == VAR_FUNC) |
696 return check_map_filter_arg2(type, context, FALSE); | 699 return check_map_filter_arg2(type, context, FILTERMAP_FILTER); |
697 semsg(_(e_string_or_function_required_for_argument_nr), 2); | 700 semsg(_(e_string_or_function_required_for_argument_nr), 2); |
698 return FAIL; | 701 return FAIL; |
699 } | 702 } |
700 | 703 |
701 /* | 704 /* |
708 || type->tt_type == VAR_PARTIAL | 711 || type->tt_type == VAR_PARTIAL |
709 || type_any_or_unknown(type)) | 712 || type_any_or_unknown(type)) |
710 return OK; | 713 return OK; |
711 | 714 |
712 if (type->tt_type == VAR_FUNC) | 715 if (type->tt_type == VAR_FUNC) |
713 return check_map_filter_arg2(type, context, TRUE); | 716 return check_map_filter_arg2(type, context, FILTERMAP_MAP); |
717 semsg(_(e_string_or_function_required_for_argument_nr), 2); | |
718 return FAIL; | |
719 } | |
720 | |
721 /* | |
722 * Check second argument of foreach(), the function. | |
723 */ | |
724 static int | |
725 arg_foreach_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context) | |
726 { | |
727 if (type->tt_type == VAR_STRING | |
728 || type->tt_type == VAR_PARTIAL | |
729 || type_any_or_unknown(type)) | |
730 return OK; | |
731 | |
732 if (type->tt_type == VAR_FUNC) | |
733 return check_map_filter_arg2(type, context, FILTERMAP_FOREACH); | |
714 semsg(_(e_string_or_function_required_for_argument_nr), 2); | 734 semsg(_(e_string_or_function_required_for_argument_nr), 2); |
715 return FAIL; | 735 return FAIL; |
716 } | 736 } |
717 | 737 |
718 /* | 738 /* |
1171 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number}; | 1191 static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number}; |
1172 static argcheck_T arg1_len[] = {arg_len1}; | 1192 static argcheck_T arg1_len[] = {arg_len1}; |
1173 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr}; | 1193 static argcheck_T arg3_libcall[] = {arg_string, arg_string, arg_string_or_nr}; |
1174 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool}; | 1194 static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool}; |
1175 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string_mod, arg_filter_func}; | 1195 static argcheck_T arg2_filter[] = {arg_list_or_dict_or_blob_or_string_mod, arg_filter_func}; |
1196 static argcheck_T arg2_foreach[] = {arg_list_or_dict_or_blob_or_string, arg_foreach_func}; | |
1176 static argcheck_T arg2_instanceof[] = {arg_object, varargs_class, NULL }; | 1197 static argcheck_T arg2_instanceof[] = {arg_object, varargs_class, NULL }; |
1177 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string_mod, arg_map_func}; | 1198 static argcheck_T arg2_map[] = {arg_list_or_dict_or_blob_or_string_mod, arg_map_func}; |
1178 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, arg_any}; | 1199 static argcheck_T arg2_mapnew[] = {arg_list_or_dict_or_blob_or_string, arg_any}; |
1179 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any}; | 1200 static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any}; |
1180 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any}; | 1201 static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_any, arg_number, arg_number, arg_dict_any}; |
2011 ret_number, f_foldlevel}, | 2032 ret_number, f_foldlevel}, |
2012 {"foldtext", 0, 0, 0, NULL, | 2033 {"foldtext", 0, 0, 0, NULL, |
2013 ret_string, f_foldtext}, | 2034 ret_string, f_foldtext}, |
2014 {"foldtextresult", 1, 1, FEARG_1, arg1_lnum, | 2035 {"foldtextresult", 1, 1, FEARG_1, arg1_lnum, |
2015 ret_string, f_foldtextresult}, | 2036 ret_string, f_foldtextresult}, |
2037 {"foreach", 2, 2, FEARG_1, arg2_foreach, | |
2038 ret_first_arg, f_foreach}, | |
2016 {"foreground", 0, 0, 0, NULL, | 2039 {"foreground", 0, 0, 0, NULL, |
2017 ret_void, f_foreground}, | 2040 ret_void, f_foreground}, |
2018 {"fullcommand", 1, 2, FEARG_1, arg2_string_bool, | 2041 {"fullcommand", 1, 2, FEARG_1, arg2_string_bool, |
2019 ret_string, f_fullcommand}, | 2042 ret_string, f_fullcommand}, |
2020 {"funcref", 1, 3, FEARG_1, arg3_any_list_dict, | 2043 {"funcref", 1, 3, FEARG_1, arg3_any_list_dict, |