Просмотр исходного кода

Refining the precedence chart with `if`, struct literals, and links. (#1089)

This is intended to be a more iterative edit to the chart:

- Adding `if` and struct literals, since it came up in arithmetic.
- Adding links to address a comment of mine about wanting references
- Rephrasing slightly to reduce the implication that it's only for operators (particularly since I don't think we want to call `if` an operator)
- Shifting operators below because similar 

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Jon Meow 4 лет назад
Родитель
Сommit
fae7f0d007
3 измененных файлов с 54 добавлено и 40 удалено
  1. 0 5
      .pre-commit-config.yaml
  2. 0 6
      .pre-commit-search-and-replace.yaml
  3. 54 29
      docs/design/expressions/README.md

+ 0 - 5
.pre-commit-config.yaml

@@ -27,11 +27,6 @@ repos:
         args: ['--fix=lf']
       - id: trailing-whitespace
         exclude: '^(.*/testdata/.*\.golden)$'
-  - repo: https://github.com/mattlqx/pre-commit-search-and-replace
-    rev: 417c99dafb534d7517d9abc17f0293de3c915a72 # frozen: v1.0.5
-    hooks:
-      - id: search-and-replace
-        files: '\.md$'
   - repo: https://github.com/google/pre-commit-tool-hooks
     rev: cb78d9293306d9f737c64d9702bbaa88e157caaa # frozen: v1.2.2
     hooks:

+ 0 - 6
.pre-commit-search-and-replace.yaml

@@ -1,6 +0,0 @@
-# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
-# Exceptions. See /LICENSE for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-- search: /https:\/\/github.com\/carbon-language\/carbon-lang\/blob\/trunk\//
-  replacement: /

+ 54 - 29
docs/design/expressions/README.md

@@ -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