Commit 1ad169d
authored
parser: parenthesize unary operands that would reparse differently (#1434)
* parser: parenthesize unary operands that would reparse differently
visitCallUnary decides whether to parenthesize its operand with
isComplexOperator, which only returns true for a call with two or more
arguments. It was added by #262 to fix `-(1 + 2)`, and never covered an
operand that is itself a unary call or a negative numeric literal.
Two grammar rules make that unsound. `unary` parses a run of leading '-'
or '!' tokens as one expression and drops the operator when the count is
even, and `literal` binds a leading '-' into an int or double constant.
So the unparser emits text that either means something else or does not
parse:
!(!a) -> !!a reparses as a
-(-a) -> --a reparses as a
-(-(-a)) -> ---a reparses as -a
-(!a) -> -!a syntax error
!(-a) -> !-a syntax error
-(-1) -> --1 reparses as 1
-(-9223372036854775808) -> --9223372036854775808 invalid int literal
Since AstToString is the public way to render a checked AST back to
source, round-tripping changes evaluation: `-(-x)` with x = MinInt64 must
raise integer overflow but returns -9223372036854775808 afterwards, and
`!(!a)` on a non-bool must raise no such overload but returns a value.
Parenthesize an operand that is a single-argument logical-not or negate
call, or a negative int or double literal. math.Signbit is used for
doubles so negative zero is covered too.
* parser: simplify the unary operand check to the function name
The member-function and argument-count guards cannot change the outcome,
since the logical-not and negate operator names are unary by definition.1 parent d9ae4c8 commit 1ad169d
2 files changed
Lines changed: 39 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| |||
270 | 271 | | |
271 | 272 | | |
272 | 273 | | |
273 | | - | |
| 274 | + | |
274 | 275 | | |
275 | 276 | | |
276 | 277 | | |
| |||
507 | 508 | | |
508 | 509 | | |
509 | 510 | | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
510 | 535 | | |
511 | 536 | | |
512 | 537 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
116 | 129 | | |
117 | 130 | | |
118 | 131 | | |
| |||
0 commit comments