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 }