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