Skip to content

Commit

Permalink
Add precedence docs (#1070)
Browse files Browse the repository at this point in the history
Drawing upon #555.
  • Loading branch information
jonmeow authored Feb 18, 2022
1 parent 50f5b3f commit 4f0c878
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions docs/design/expressions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

- [Overview](#overview)
- [Operators](#operators)
- [Precedence](#precedence)
- [Conversions and casts](#conversions-and-casts)
- [`if` expressions](#if-expressions)
- [Alternatives considered](#alternatives-considered)
- [References](#references)

<!-- tocstop -->

Expand Down Expand Up @@ -48,6 +51,60 @@ Most expressions are modeled as operators:
| Comparison | [`>`](comparison_operators.md) | `x > y` | Greater than: `true` if `x` is greater than to `y`. |
| Comparison | [`>=`](comparison_operators.md) | `x >= y` | Greater than or equal: `true` if `x` is greater than or equal to `y`. |

### Precedence

Operators have a partial
[precedence ordering](https://en.wikipedia.org/wiki/Order_of_operations).
Expressions using operators that lack a relative ordering must be disambiguated
by the developer, for example by adding parentheses; when a program's meaning
depends on an undefined relative ordering of two operators, it will be rejected
due to ambiguity. Precedence orderings will only be added when it's reasonable
to expect most developers to understand the precedence without parentheses.

The precedence diagram is defined thusly:

```mermaid
graph BT
parens["(...)"]
as["x as T"]
not["not x"]
comparison["x == y<br> x != y<br> x < y<br> x <= y<br> x > y<br> x >= y"]
and>"x and y"]
or>"x or y"]
as & not --> parens
comparison --> as
and & or --> comparison & not
```

The diagram's attributes are:

- Each node represents a precedence group.

- When an expression contains operators from different precedence groups, the
interpretation is determined by the precedence edges:

- A precedence edge A --> B means that A is lower precedence than B, so A
can contain B without parentheses. For example, `or --> not` means that
`not x or y` is treated as `(not x) or y`.

- Precedence edges are transitive. For example, `or --> == --> as` means
that `or` is lower precedence than `as`.

- When an expression contains operators from a single precedence group, the
interpretation is determined by the
[associativity](https://en.wikipedia.org/wiki/Operator_associativity) of the
precedence group:

```mermaid
graph TD
non["Non-associative"]
left>"Left associative"]
```

- For example, `+` and `-` are left-associative and in the same precedence
group, so `a + b + c - d` is treated as `((a + b) + c) - d`.

## Conversions and casts

When an expression appears in a context in which an expression of a specific
Expand Down Expand Up @@ -76,3 +133,20 @@ fn Run(args: Span(StringView)) {
```

`if` expressions are analogous to `?:` ternary expressions in C and C++.

## Alternatives considered

Other expression documents will list more references; this lists references not
noted elsewhere.

- [Total order](/proposals/p0555.md#total-order)
- [Different precedence for different operands](/proposals/p0555.md#different-precedence-for-different-operands)
- [Require less than a partial order](/proposals/p0555.md#require-less-than-a-partial-order)

## References

Other expression documents will list more references; this lists references not
noted elsewhere.

- Proposal
[#555: Operator precedence](https://github.com/carbon-language/carbon-lang/pull/555).

0 comments on commit 4f0c878

Please sign in to comment.