Mercurial > vim
comparison src/vim9compile.c @ 20988:ae4b1d497a06 v8.2.1045
patch 8.2.1045: Vim9: line break before operator does not work
Commit: https://github.com/vim/vim/commit/67fbdfefd26a237831c3838f799d3e6198c8a34a
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jun 23 22:26:05 2020 +0200
patch 8.2.1045: Vim9: line break before operator does not work
Problem: Vim9: line break before operator does not work.
Solution: Peek the next line for an operator.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 23 Jun 2020 22:30:04 +0200 |
parents | bb49b5090a9c |
children | 7acceb76669f |
comparison
equal
deleted
inserted
replaced
20987:bccc75504b67 | 20988:ae4b1d497a06 |
---|---|
2409 p = skipwhite(line); | 2409 p = skipwhite(line); |
2410 if (*p != NUL && !comment_start(p)) | 2410 if (*p != NUL && !comment_start(p)) |
2411 return p; | 2411 return p; |
2412 } | 2412 } |
2413 return NULL; | 2413 return NULL; |
2414 } | |
2415 | |
2416 /* | |
2417 * Called when checking for a following operator at "arg". When the rest of | |
2418 * the line is empty or only a comment, peek the next line. If there is a next | |
2419 * line return a pointer to it and set "nextp". | |
2420 * Otherwise skip over white space. | |
2421 */ | |
2422 static char_u * | |
2423 may_peek_next_line(cctx_T *cctx, char_u *arg, char_u **nextp) | |
2424 { | |
2425 char_u *p = skipwhite(arg); | |
2426 | |
2427 *nextp = NULL; | |
2428 if (*p == NUL || (VIM_ISWHITE(*arg) && comment_start(p))) | |
2429 { | |
2430 *nextp = peek_next_line(cctx); | |
2431 if (*nextp != NULL) | |
2432 return *nextp; | |
2433 } | |
2434 return p; | |
2414 } | 2435 } |
2415 | 2436 |
2416 /* | 2437 /* |
2417 * Get the next line of the function from "cctx". | 2438 * Get the next line of the function from "cctx". |
2418 * Skips over empty lines. Skips over comment lines if "skip_comment" is TRUE. | 2439 * Skips over empty lines. Skips over comment lines if "skip_comment" is TRUE. |
3945 */ | 3966 */ |
3946 static int | 3967 static int |
3947 compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) | 3968 compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) |
3948 { | 3969 { |
3949 char_u *op; | 3970 char_u *op; |
3971 char_u *next; | |
3950 int ppconst_used = ppconst->pp_used; | 3972 int ppconst_used = ppconst->pp_used; |
3951 | 3973 |
3952 // get the first expression | 3974 // get the first expression |
3953 if (compile_expr7(arg, cctx, ppconst) == FAIL) | 3975 if (compile_expr7(arg, cctx, ppconst) == FAIL) |
3954 return FAIL; | 3976 return FAIL; |
3956 /* | 3978 /* |
3957 * Repeat computing, until no "*", "/" or "%" is following. | 3979 * Repeat computing, until no "*", "/" or "%" is following. |
3958 */ | 3980 */ |
3959 for (;;) | 3981 for (;;) |
3960 { | 3982 { |
3961 op = skipwhite(*arg); | 3983 op = may_peek_next_line(cctx, *arg, &next); |
3962 if (*op != '*' && *op != '/' && *op != '%') | 3984 if (*op != '*' && *op != '/' && *op != '%') |
3963 break; | 3985 break; |
3986 if (next != NULL) | |
3987 { | |
3988 *arg = next_line_from_context(cctx, TRUE); | |
3989 op = skipwhite(*arg); | |
3990 } | |
3964 | 3991 |
3965 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1])) | 3992 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1])) |
3966 { | 3993 { |
3967 char_u buf[3]; | 3994 char_u buf[3]; |
3968 | 3995 |
4016 */ | 4043 */ |
4017 static int | 4044 static int |
4018 compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) | 4045 compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) |
4019 { | 4046 { |
4020 char_u *op; | 4047 char_u *op; |
4048 char_u *next; | |
4021 int oplen; | 4049 int oplen; |
4022 int ppconst_used = ppconst->pp_used; | 4050 int ppconst_used = ppconst->pp_used; |
4023 | 4051 |
4024 // get the first variable | 4052 // get the first variable |
4025 if (compile_expr6(arg, cctx, ppconst) == FAIL) | 4053 if (compile_expr6(arg, cctx, ppconst) == FAIL) |
4028 /* | 4056 /* |
4029 * Repeat computing, until no "+", "-" or ".." is following. | 4057 * Repeat computing, until no "+", "-" or ".." is following. |
4030 */ | 4058 */ |
4031 for (;;) | 4059 for (;;) |
4032 { | 4060 { |
4033 op = skipwhite(*arg); | 4061 op = may_peek_next_line(cctx, *arg, &next); |
4034 if (*op != '+' && *op != '-' && !(*op == '.' && (*(*arg + 1) == '.'))) | 4062 if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.')) |
4035 break; | 4063 break; |
4036 oplen = (*op == '.' ? 2 : 1); | 4064 oplen = (*op == '.' ? 2 : 1); |
4065 if (next != NULL) | |
4066 { | |
4067 *arg = next_line_from_context(cctx, TRUE); | |
4068 op = skipwhite(*arg); | |
4069 } | |
4037 | 4070 |
4038 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen])) | 4071 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen])) |
4039 { | 4072 { |
4040 char_u buf[3]; | 4073 char_u buf[3]; |
4041 | 4074 |
4125 static int | 4158 static int |
4126 compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) | 4159 compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) |
4127 { | 4160 { |
4128 exptype_T type = EXPR_UNKNOWN; | 4161 exptype_T type = EXPR_UNKNOWN; |
4129 char_u *p; | 4162 char_u *p; |
4163 char_u *next; | |
4130 int len = 2; | 4164 int len = 2; |
4131 int type_is = FALSE; | 4165 int type_is = FALSE; |
4132 int ppconst_used = ppconst->pp_used; | 4166 int ppconst_used = ppconst->pp_used; |
4133 | 4167 |
4134 // get the first variable | 4168 // get the first variable |
4135 if (compile_expr5(arg, cctx, ppconst) == FAIL) | 4169 if (compile_expr5(arg, cctx, ppconst) == FAIL) |
4136 return FAIL; | 4170 return FAIL; |
4137 | 4171 |
4138 p = skipwhite(*arg); | 4172 p = may_peek_next_line(cctx, *arg, &next); |
4139 type = get_compare_type(p, &len, &type_is); | 4173 type = get_compare_type(p, &len, &type_is); |
4140 | 4174 |
4141 /* | 4175 /* |
4142 * If there is a comparative operator, use it. | 4176 * If there is a comparative operator, use it. |
4143 */ | 4177 */ |
4144 if (type != EXPR_UNKNOWN) | 4178 if (type != EXPR_UNKNOWN) |
4145 { | 4179 { |
4146 int ic = FALSE; // Default: do not ignore case | 4180 int ic = FALSE; // Default: do not ignore case |
4147 | 4181 |
4182 if (next != NULL) | |
4183 { | |
4184 *arg = next_line_from_context(cctx, TRUE); | |
4185 p = skipwhite(*arg); | |
4186 } | |
4148 if (type_is && (p[len] == '?' || p[len] == '#')) | 4187 if (type_is && (p[len] == '?' || p[len] == '#')) |
4149 { | 4188 { |
4150 semsg(_(e_invexpr2), *arg); | 4189 semsg(_(e_invexpr2), *arg); |
4151 return FAIL; | 4190 return FAIL; |
4152 } | 4191 } |
4219 cctx_T *cctx, | 4258 cctx_T *cctx, |
4220 char *op, | 4259 char *op, |
4221 ppconst_T *ppconst, | 4260 ppconst_T *ppconst, |
4222 int ppconst_used UNUSED) | 4261 int ppconst_used UNUSED) |
4223 { | 4262 { |
4224 char_u *p = skipwhite(*arg); | 4263 char_u *next; |
4264 char_u *p = may_peek_next_line(cctx, *arg, &next); | |
4225 int opchar = *op; | 4265 int opchar = *op; |
4226 | 4266 |
4227 if (p[0] == opchar && p[1] == opchar) | 4267 if (p[0] == opchar && p[1] == opchar) |
4228 { | 4268 { |
4229 garray_T *instr = &cctx->ctx_instr; | 4269 garray_T *instr = &cctx->ctx_instr; |
4233 * Repeat until there is no following "||" or "&&" | 4273 * Repeat until there is no following "||" or "&&" |
4234 */ | 4274 */ |
4235 ga_init2(&end_ga, sizeof(int), 10); | 4275 ga_init2(&end_ga, sizeof(int), 10); |
4236 while (p[0] == opchar && p[1] == opchar) | 4276 while (p[0] == opchar && p[1] == opchar) |
4237 { | 4277 { |
4278 if (next != NULL) | |
4279 { | |
4280 *arg = next_line_from_context(cctx, TRUE); | |
4281 p = skipwhite(*arg); | |
4282 } | |
4283 | |
4238 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2])) | 4284 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[2])) |
4239 { | 4285 { |
4240 semsg(_(e_white_both), op); | 4286 semsg(_(e_white_both), op); |
4241 return FAIL; | 4287 return FAIL; |
4242 } | 4288 } |
4263 : compile_expr4(arg, cctx, ppconst)) == FAIL) | 4309 : compile_expr4(arg, cctx, ppconst)) == FAIL) |
4264 { | 4310 { |
4265 ga_clear(&end_ga); | 4311 ga_clear(&end_ga); |
4266 return FAIL; | 4312 return FAIL; |
4267 } | 4313 } |
4268 p = skipwhite(*arg); | 4314 |
4315 p = may_peek_next_line(cctx, *arg, &next); | |
4269 } | 4316 } |
4270 generate_ppconst(cctx, ppconst); | 4317 generate_ppconst(cctx, ppconst); |
4271 | 4318 |
4272 // Fill in the end label in all jumps. | 4319 // Fill in the end label in all jumps. |
4273 while (end_ga.ga_len > 0) | 4320 while (end_ga.ga_len > 0) |
4347 static int | 4394 static int |
4348 compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) | 4395 compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst) |
4349 { | 4396 { |
4350 char_u *p; | 4397 char_u *p; |
4351 int ppconst_used = ppconst->pp_used; | 4398 int ppconst_used = ppconst->pp_used; |
4399 char_u *next; | |
4352 | 4400 |
4353 // Evaluate the first expression. | 4401 // Evaluate the first expression. |
4354 if (compile_expr2(arg, cctx, ppconst) == FAIL) | 4402 if (compile_expr2(arg, cctx, ppconst) == FAIL) |
4355 return FAIL; | 4403 return FAIL; |
4356 | 4404 |
4357 p = skipwhite(*arg); | 4405 p = may_peek_next_line(cctx, *arg, &next); |
4358 if (*p == '?') | 4406 if (*p == '?') |
4359 { | 4407 { |
4360 garray_T *instr = &cctx->ctx_instr; | 4408 garray_T *instr = &cctx->ctx_instr; |
4361 garray_T *stack = &cctx->ctx_type_stack; | 4409 garray_T *stack = &cctx->ctx_type_stack; |
4362 int alt_idx = instr->ga_len; | 4410 int alt_idx = instr->ga_len; |
4366 type_T *type2; | 4414 type_T *type2; |
4367 int has_const_expr = FALSE; | 4415 int has_const_expr = FALSE; |
4368 int const_value = FALSE; | 4416 int const_value = FALSE; |
4369 int save_skip = cctx->ctx_skip; | 4417 int save_skip = cctx->ctx_skip; |
4370 | 4418 |
4419 if (next != NULL) | |
4420 { | |
4421 *arg = next_line_from_context(cctx, TRUE); | |
4422 p = skipwhite(*arg); | |
4423 } | |
4424 | |
4371 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1])) | 4425 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1])) |
4372 { | 4426 { |
4373 semsg(_(e_white_both), "?"); | 4427 semsg(_(e_white_both), "?"); |
4374 return FAIL; | 4428 return FAIL; |
4375 } | 4429 } |
4413 isn = ((isn_T *)instr->ga_data) + alt_idx; | 4467 isn = ((isn_T *)instr->ga_data) + alt_idx; |
4414 isn->isn_arg.jump.jump_where = instr->ga_len; | 4468 isn->isn_arg.jump.jump_where = instr->ga_len; |
4415 } | 4469 } |
4416 | 4470 |
4417 // Check for the ":". | 4471 // Check for the ":". |
4418 p = skipwhite(*arg); | 4472 p = may_peek_next_line(cctx, *arg, &next); |
4419 if (*p != ':') | 4473 if (*p != ':') |
4420 { | 4474 { |
4421 emsg(_(e_missing_colon)); | 4475 emsg(_(e_missing_colon)); |
4422 return FAIL; | 4476 return FAIL; |
4423 } | 4477 } |
4478 if (next != NULL) | |
4479 { | |
4480 *arg = next_line_from_context(cctx, TRUE); | |
4481 p = skipwhite(*arg); | |
4482 } | |
4483 | |
4424 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1])) | 4484 if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[1])) |
4425 { | 4485 { |
4426 semsg(_(e_white_both), ":"); | 4486 semsg(_(e_white_both), ":"); |
4427 return FAIL; | 4487 return FAIL; |
4428 } | 4488 } |