Add precedence rules for assignment operators to the precedence diagram. (#3083)

Also indicate what can appear within parentheses.

This is intended to be a clarification, not a design change. Note that
while we previously described the operand of `++` or `--` as being
simply an expression, the operand can never be anything other than the
kinds of expression the diagram now shows due to the expression category
rules added in #2006.

Fixes #3079.
This commit is contained in:
Richard Smith
2023-08-10 22:35:51 +00:00
committed by GitHub
parent 6e01b90394
commit 7b22173cba
4 changed files with 32 additions and 19 deletions
@@ -23,6 +23,10 @@ fn F() {
// CHECK:STDERR: a + ++a;
// CHECK:STDERR: ^
a + ++a;
// CHECK:STDERR: fail_precedence_assign.carbon:[[@LINE+3]]:5: Parentheses are required around this unary `if` operator.
// CHECK:STDERR: ++if c then a else b;
// CHECK:STDERR: ^
++if c then a else b;
}
// CHECK:STDOUT: [
@@ -56,6 +60,14 @@ fn F() {
// CHECK:STDOUT: {kind: 'PrefixOperator', text: '++', subtree_size: 2},
// CHECK:STDOUT: {kind: 'InfixOperator', text: '+', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 5},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 31},
// CHECK:STDOUT: {kind: 'NameExpression', text: 'c'},
// CHECK:STDOUT: {kind: 'IfExpressionIf', text: 'if', subtree_size: 2},
// CHECK:STDOUT: {kind: 'NameExpression', text: 'a'},
// CHECK:STDOUT: {kind: 'IfExpressionThen', text: 'then', subtree_size: 2},
// CHECK:STDOUT: {kind: 'NameExpression', text: 'b'},
// CHECK:STDOUT: {kind: 'IfExpressionElse', text: 'else', subtree_size: 6},
// CHECK:STDOUT: {kind: 'PrefixOperator', text: '++', subtree_size: 7},
// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 8},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 39},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
@@ -9,9 +9,8 @@ fn F(c: bool) {
var b: i32;
var p: i32*;
*p = if c then 1 else 2;
// These are valid to _parse_ even though rejected semantically.
// This is valid to _parse_ even though rejected semantically.
(if c then a else b) += if c then 1 else 2;
++if c then a else b;
}
// CHECK:STDOUT: [
@@ -65,14 +64,6 @@ fn F(c: bool) {
// CHECK:STDOUT: {kind: 'IfExpressionElse', text: 'else', subtree_size: 6},
// CHECK:STDOUT: {kind: 'InfixOperator', text: '+=', subtree_size: 15},
// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 16},
// CHECK:STDOUT: {kind: 'NameExpression', text: 'c'},
// CHECK:STDOUT: {kind: 'IfExpressionIf', text: 'if', subtree_size: 2},
// CHECK:STDOUT: {kind: 'NameExpression', text: 'a'},
// CHECK:STDOUT: {kind: 'IfExpressionThen', text: 'then', subtree_size: 2},
// CHECK:STDOUT: {kind: 'NameExpression', text: 'b'},
// CHECK:STDOUT: {kind: 'IfExpressionElse', text: 'else', subtree_size: 6},
// CHECK:STDOUT: {kind: 'PrefixOperator', text: '++', subtree_size: 7},
// CHECK:STDOUT: {kind: 'ExpressionStatement', text: ';', subtree_size: 8},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 59},
// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 51},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]