|
|
@@ -11,8 +11,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
## Table of contents
|
|
|
|
|
|
- [Overview](#overview)
|
|
|
+- [Precedence](#precedence)
|
|
|
- [Operators](#operators)
|
|
|
- - [Precedence](#precedence)
|
|
|
- [Conversions and casts](#conversions-and-casts)
|
|
|
- [`if` expressions](#if-expressions)
|
|
|
- [Alternatives considered](#alternatives-considered)
|
|
|
@@ -34,54 +34,62 @@ fn Foo(a: i32*) -> i32 {
|
|
|
Here, the parameter type `i32*`, the return type `i32`, and the operand `*a` of
|
|
|
the `return` statement are all expressions.
|
|
|
|
|
|
-## Operators
|
|
|
-
|
|
|
-Most expressions are modeled as operators:
|
|
|
+## Precedence
|
|
|
|
|
|
-| Category | Operator | Syntax | Function |
|
|
|
-| ---------- | ------------------------------- | --------- | --------------------------------------------------------------------- |
|
|
|
-| Conversion | [`as`](as_expressions.md) | `x as T` | Converts the value `x` to the type `T`. |
|
|
|
-| Logical | [`and`](logical_operators.md) | `x and y` | A short-circuiting logical AND: `true` if both operands are `true`. |
|
|
|
-| Logical | [`or`](logical_operators.md) | `x or y` | A short-circuiting logical OR: `true` if either operand is `true`. |
|
|
|
-| Logical | [`not`](logical_operators.md) | `not x` | Logical NOT: `true` if the operand is `false`. |
|
|
|
-| Comparison | [`==`](comparison_operators.md) | `x == y` | Equality: `true` if `x` is equal to `y`. |
|
|
|
-| Comparison | [`!=`](comparison_operators.md) | `x != y` | Inequality: `true` if `x` is not equal to `y`. |
|
|
|
-| Comparison | [`<`](comparison_operators.md) | `x < y` | Less than: `true` if `x` is less than `y`. |
|
|
|
-| Comparison | [`<=`](comparison_operators.md) | `x <= y` | Less than or equal: `true` if `x` is less than or equal to `y`. |
|
|
|
-| 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
|
|
|
+Expressions are interpreted based on 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.
|
|
|
+Expression components which lack a relative ordering must be disambiguated by
|
|
|
+the developer, for example by adding parentheses; otherwise, the expression will
|
|
|
+be invalid 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
|
|
|
+%%{init: {'themeVariables': {'fontFamily': 'monospace'}}}%%
|
|
|
graph BT
|
|
|
parens["(...)"]
|
|
|
+
|
|
|
+ braces["{...}"]
|
|
|
+ click braces "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#literals"
|
|
|
+
|
|
|
as["x as T"]
|
|
|
+ click as "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/implicit_conversions.md"
|
|
|
+
|
|
|
not["not x"]
|
|
|
- comparison["x == y<br> x != y<br> x < y<br> x <= y<br> x > y<br> x >= y"]
|
|
|
+ click not "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/logical_operators.md"
|
|
|
+
|
|
|
+ comparison["x == y<br>
|
|
|
+ x != y<br>
|
|
|
+ x < y<br>
|
|
|
+ x <= y<br>
|
|
|
+ x > y<br>
|
|
|
+ x >= y"]
|
|
|
+ click comparison "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/comparison_operators.md"
|
|
|
+
|
|
|
and>"x and y"]
|
|
|
+ click and "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/logical_operators.md"
|
|
|
+
|
|
|
or>"x or y"]
|
|
|
+ click or "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/logical_operators.md"
|
|
|
+
|
|
|
+ if>"if x then y else z"]
|
|
|
+ click if "https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/if.md"
|
|
|
|
|
|
- as & not --> parens
|
|
|
+ expressionEnd["x;"]
|
|
|
+
|
|
|
+ as & not --> parens & braces
|
|
|
comparison --> as
|
|
|
and & or --> comparison & not
|
|
|
+ if & expressionEnd --> and & or
|
|
|
```
|
|
|
|
|
|
The diagram's attributes are:
|
|
|
|
|
|
- Each node represents a precedence group.
|
|
|
|
|
|
-- When an expression contains operators from different precedence groups, the
|
|
|
+- When an expression is composed 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
|
|
|
@@ -91,7 +99,7 @@ The diagram's attributes are:
|
|
|
- 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
|
|
|
+- When an expression is composed from a single precedence group, the
|
|
|
interpretation is determined by the
|
|
|
[associativity](https://en.wikipedia.org/wiki/Operator_associativity) of the
|
|
|
precedence group:
|
|
|
@@ -105,6 +113,23 @@ The diagram's attributes are:
|
|
|
- For example, `+` and `-` are left-associative and in the same precedence
|
|
|
group, so `a + b + c - d` is treated as `((a + b) + c) - d`.
|
|
|
|
|
|
+## Operators
|
|
|
+
|
|
|
+Most expressions are modeled as operators:
|
|
|
+
|
|
|
+| Category | Operator | Syntax | Function |
|
|
|
+| ---------- | ------------------------------- | --------- | --------------------------------------------------------------------- |
|
|
|
+| Conversion | [`as`](as_expressions.md) | `x as T` | Converts the value `x` to the type `T`. |
|
|
|
+| Logical | [`and`](logical_operators.md) | `x and y` | A short-circuiting logical AND: `true` if both operands are `true`. |
|
|
|
+| Logical | [`or`](logical_operators.md) | `x or y` | A short-circuiting logical OR: `true` if either operand is `true`. |
|
|
|
+| Logical | [`not`](logical_operators.md) | `not x` | Logical NOT: `true` if the operand is `false`. |
|
|
|
+| Comparison | [`==`](comparison_operators.md) | `x == y` | Equality: `true` if `x` is equal to `y`. |
|
|
|
+| Comparison | [`!=`](comparison_operators.md) | `x != y` | Inequality: `true` if `x` is not equal to `y`. |
|
|
|
+| Comparison | [`<`](comparison_operators.md) | `x < y` | Less than: `true` if `x` is less than `y`. |
|
|
|
+| Comparison | [`<=`](comparison_operators.md) | `x <= y` | Less than or equal: `true` if `x` is less than or equal to `y`. |
|
|
|
+| 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`. |
|
|
|
+
|
|
|
## Conversions and casts
|
|
|
|
|
|
When an expression appears in a context in which an expression of a specific
|