comparison src/vim9compile.c @ 19328:e99e6d794597 v8.2.0222

patch 8.2.0222: Vim9: optional function arguments don't work yet Commit: https://github.com/vim/vim/commit/170fcfcf250954d76fca86e3fed088ddfdb49383 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 6 17:51:35 2020 +0100 patch 8.2.0222: Vim9: optional function arguments don't work yet Problem: Vim9: optional function arguments don't work yet. Solution: Implement optional function arguments.
author Bram Moolenaar <Bram@vim.org>
date Thu, 06 Feb 2020 18:00:04 +0100
parents 17dc6282f370
children 9c8b803fe598
comparison
equal deleted inserted replaced
19327:6bbb4ad91d21 19328:e99e6d794597
954 /* 954 /*
955 * Generate an ISN_DCALL or ISN_UCALL instruction. 955 * Generate an ISN_DCALL or ISN_UCALL instruction.
956 * Return FAIL if the number of arguments is wrong. 956 * Return FAIL if the number of arguments is wrong.
957 */ 957 */
958 static int 958 static int
959 generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int argcount) 959 generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
960 { 960 {
961 isn_T *isn; 961 isn_T *isn;
962 garray_T *stack = &cctx->ctx_type_stack; 962 garray_T *stack = &cctx->ctx_type_stack;
963 int regular_args = ufunc->uf_args.ga_len; 963 int regular_args = ufunc->uf_args.ga_len;
964 int argcount = pushed_argcount;
964 965
965 if (argcount > regular_args && !has_varargs(ufunc)) 966 if (argcount > regular_args && !has_varargs(ufunc))
966 { 967 {
967 semsg(_(e_toomanyarg), ufunc->uf_name); 968 semsg(_(e_toomanyarg), ufunc->uf_name);
968 return FAIL; 969 return FAIL;
976 // Turn varargs into a list. 977 // Turn varargs into a list.
977 if (ufunc->uf_va_name != NULL) 978 if (ufunc->uf_va_name != NULL)
978 { 979 {
979 int count = argcount - regular_args; 980 int count = argcount - regular_args;
980 981
981 // TODO: add default values for optional arguments? 982 // If count is negative an empty list will be added after evaluating
982 generate_NEWLIST(cctx, count < 0 ? 0 : count); 983 // default values for missing optional arguments.
983 argcount = regular_args + 1; 984 if (count >= 0)
985 {
986 generate_NEWLIST(cctx, count);
987 argcount = regular_args + 1;
988 }
984 } 989 }
985 990
986 if ((isn = generate_instr(cctx, 991 if ((isn = generate_instr(cctx,
987 ufunc->uf_dfunc_idx >= 0 ? ISN_DCALL : ISN_UCALL)) == NULL) 992 ufunc->uf_dfunc_idx >= 0 ? ISN_DCALL : ISN_UCALL)) == NULL)
988 return FAIL; 993 return FAIL;
4598 instr = &cctx.ctx_instr; 4603 instr = &cctx.ctx_instr;
4599 4604
4600 // Most modern script version. 4605 // Most modern script version.
4601 current_sctx.sc_version = SCRIPT_VERSION_VIM9; 4606 current_sctx.sc_version = SCRIPT_VERSION_VIM9;
4602 4607
4608 if (ufunc->uf_def_args.ga_len > 0)
4609 {
4610 int count = ufunc->uf_def_args.ga_len;
4611 int i;
4612 char_u *arg;
4613 int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
4614
4615 // Produce instructions for the default values of optional arguments.
4616 // Store the instruction index in uf_def_arg_idx[] so that we know
4617 // where to start when the function is called, depending on the number
4618 // of arguments.
4619 ufunc->uf_def_arg_idx = ALLOC_CLEAR_MULT(int, count + 1);
4620 if (ufunc->uf_def_arg_idx == NULL)
4621 goto erret;
4622 for (i = 0; i < count; ++i)
4623 {
4624 ufunc->uf_def_arg_idx[i] = instr->ga_len;
4625 arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
4626 if (compile_expr1(&arg, &cctx) == FAIL
4627 || generate_STORE(&cctx, ISN_STORE,
4628 i - count - off, NULL) == FAIL)
4629 goto erret;
4630 }
4631
4632 // If a varargs is following, push an empty list.
4633 if (ufunc->uf_va_name != NULL)
4634 {
4635 if (generate_NEWLIST(&cctx, 0) == FAIL
4636 || generate_STORE(&cctx, ISN_STORE, -off, NULL) == FAIL)
4637 goto erret;
4638 }
4639
4640 ufunc->uf_def_arg_idx[count] = instr->ga_len;
4641 }
4642
4643 /*
4644 * Loop over all the lines of the function and generate instructions.
4645 */
4603 for (;;) 4646 for (;;)
4604 { 4647 {
4605 if (line != NULL && *line == '|') 4648 if (line != NULL && *line == '|')
4606 // the line continues after a '|' 4649 // the line continues after a '|'
4607 ++line; 4650 ++line;