Mercurial > vim
comparison src/vim9compile.c @ 24361:f76398d79c2e v8.2.2721
patch 8.2.2721: Vim9: cannot have a linebreak inside a lambda
Commit: https://github.com/vim/vim/commit/2927c07b0ec627c13e863e1b84bec831743bce12
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Apr 5 19:41:21 2021 +0200
patch 8.2.2721: Vim9: cannot have a linebreak inside a lambda
Problem: Vim9: cannot have a linebreak inside a lambda.
Solution: Compile the expression before the arguments.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 05 Apr 2021 19:45:04 +0200 |
parents | 108a6e2497f6 |
children | 1a145eb83a28 |
comparison
equal
deleted
inserted
replaced
24360:caeae97697d1 | 24361:f76398d79c2e |
---|---|
3973 *arg = skipwhite(p); | 3973 *arg = skipwhite(p); |
3974 // No line break supported right after "->". | 3974 // No line break supported right after "->". |
3975 if (**arg == '(') | 3975 if (**arg == '(') |
3976 { | 3976 { |
3977 int argcount = 1; | 3977 int argcount = 1; |
3978 char_u *expr; | 3978 garray_T *stack = &cctx->ctx_type_stack; |
3979 garray_T *stack; | 3979 int type_idx_start = stack->ga_len; |
3980 type_T *type; | 3980 type_T *type; |
3981 int expr_isn_start = cctx->ctx_instr.ga_len; | |
3982 int expr_isn_end; | |
3983 int arg_isn_count; | |
3981 | 3984 |
3982 // Funcref call: list->(Refs[2])(arg) | 3985 // Funcref call: list->(Refs[2])(arg) |
3983 // or lambda: list->((arg) => expr)(arg) | 3986 // or lambda: list->((arg) => expr)(arg) |
3984 // Fist compile the arguments. | 3987 // |
3985 expr = *arg; | 3988 // Fist compile the function expression. |
3986 *arg = skipwhite(*arg + 1); | 3989 if (compile_parenthesis(arg, cctx, ppconst) == FAIL) |
3987 skip_expr_cctx(arg, cctx); | |
3988 *arg = skipwhite(*arg); | |
3989 if (**arg != ')') | |
3990 { | |
3991 semsg(_(e_missing_paren), *arg); | |
3992 return FAIL; | 3990 return FAIL; |
3993 } | 3991 |
3994 ++*arg; | 3992 // Remember the next instruction index, where the instructions |
3993 // for arguments are being written. | |
3994 expr_isn_end = cctx->ctx_instr.ga_len; | |
3995 | |
3996 // Compile the arguments. | |
3995 if (**arg != '(') | 3997 if (**arg != '(') |
3996 { | 3998 { |
3997 if (*skipwhite(*arg) == '(') | 3999 if (*skipwhite(*arg) == '(') |
3998 emsg(_(e_nowhitespace)); | 4000 emsg(_(e_nowhitespace)); |
3999 else | 4001 else |
4000 semsg(_(e_missing_paren), *arg); | 4002 semsg(_(e_missing_paren), *arg); |
4001 return FAIL; | 4003 return FAIL; |
4002 } | 4004 } |
4003 | |
4004 *arg = skipwhite(*arg + 1); | 4005 *arg = skipwhite(*arg + 1); |
4005 if (compile_arguments(arg, cctx, &argcount) == FAIL) | 4006 if (compile_arguments(arg, cctx, &argcount) == FAIL) |
4006 return FAIL; | 4007 return FAIL; |
4007 | 4008 |
4008 // Compile the function expression. | 4009 // Move the instructions for the arguments to before the |
4009 if (compile_parenthesis(&expr, cctx, ppconst) == FAIL) | 4010 // instructions of the expression and move the type of the |
4010 return FAIL; | 4011 // expression after the argument types. This is what ISN_PCALL |
4011 | 4012 // expects. |
4012 stack = &cctx->ctx_type_stack; | 4013 stack = &cctx->ctx_type_stack; |
4014 arg_isn_count = cctx->ctx_instr.ga_len - expr_isn_end; | |
4015 if (arg_isn_count > 0) | |
4016 { | |
4017 int expr_isn_count = expr_isn_end - expr_isn_start; | |
4018 isn_T *isn = ALLOC_MULT(isn_T, expr_isn_count); | |
4019 | |
4020 if (isn == NULL) | |
4021 return FAIL; | |
4022 mch_memmove(isn, ((isn_T *)cctx->ctx_instr.ga_data) | |
4023 + expr_isn_start, | |
4024 sizeof(isn_T) * expr_isn_count); | |
4025 mch_memmove(((isn_T *)cctx->ctx_instr.ga_data) | |
4026 + expr_isn_start, | |
4027 ((isn_T *)cctx->ctx_instr.ga_data) + expr_isn_end, | |
4028 sizeof(isn_T) * arg_isn_count); | |
4029 mch_memmove(((isn_T *)cctx->ctx_instr.ga_data) | |
4030 + expr_isn_start + arg_isn_count, | |
4031 isn, sizeof(isn_T) * expr_isn_count); | |
4032 vim_free(isn); | |
4033 | |
4034 type = ((type_T **)stack->ga_data)[type_idx_start]; | |
4035 mch_memmove(((type_T **)stack->ga_data) + type_idx_start, | |
4036 ((type_T **)stack->ga_data) + type_idx_start + 1, | |
4037 sizeof(type_T *) | |
4038 * (stack->ga_len - type_idx_start - 1)); | |
4039 ((type_T **)stack->ga_data)[stack->ga_len - 1] = type; | |
4040 } | |
4041 | |
4013 type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; | 4042 type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; |
4014 if (generate_PCALL(cctx, argcount, | 4043 if (generate_PCALL(cctx, argcount, |
4015 (char_u *)"[expression]", type, FALSE) == FAIL) | 4044 (char_u *)"[expression]", type, FALSE) == FAIL) |
4016 return FAIL; | 4045 return FAIL; |
4017 } | 4046 } |