From e57165b85a48daba3649b08cff3eab3519bc8dce Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Thu, 5 Jan 2023 15:16:16 +0100 Subject: [PATCH] bring back table, extract annotations this makes the table less unwieldy, and leaves enough space for extensive explanations. --- doc/manual/src/language/operators.md | 249 +++++++++------------------ doc/manual/src/language/values.md | 7 +- 2 files changed, 82 insertions(+), 174 deletions(-) diff --git a/doc/manual/src/language/operators.md b/doc/manual/src/language/operators.md index 1f11e6ac5..797f13bd3 100644 --- a/doc/manual/src/language/operators.md +++ b/doc/manual/src/language/operators.md @@ -1,117 +1,96 @@ # Operators +| Name | Syntax | Associativity | Precedence | +|----------------------------------------|--------------------------------------------|---------------|------------| +| [Attribute selection] | *attrset* `.` *attrpath* \[ `or` *expr* \] | none | 1 | +| Function application | *func* *expr* | left | 2 | +| [Arithmetic negation][arithmetic] | `-` *number* | none | 3 | +| [Has attribute] | *attrset* `?` *attrpath* | none | 4 | +| List concatenation | *list* `++` *list* | right | 5 | +| [Multiplication][arithmetic] | *number* `*` *number* | left | 6 | +| [Division][arithmetic] | *number* `/` *number* | left | 6 | +| [Subtraction][arithmetic] | *number* `-` *number* | left | 7 | +| [Addition][arithmetic] | *number* `+` *number* | left | 7 | +| [String concatenation] | *string* `+` *string* | left | 7 | +| [Path concatenation] | *path* `+` *path* | left | 7 | +| [Path and string concatenation] | *path* `+` *string* | left | 7 | +| [String and path concatenation] | *string* `+` *path* | left | 7 | +| Logical negation (`NOT`) | `!` *bool* | none | 8 | +| [Update] | *attrset* `//` *attrset* | right | 9 | +| [Less than][Comparison] | *expr* `<` *expr* | none | 10 | +| [Less than or equal to][Comparison] | *expr* `<=` *expr* | none | 10 | +| [Greater than][Comparison] | *expr* `>` *expr* | none | 10 | +| [Greater than or equal to][Comparison] | *expr* `>=` *expr* | none | 10 | +| [Equality] | *expr* `==` *expr* | none | 11 | +| Inequality | *expr* `!=` *expr* | none | 11 | +| Logical conjunction (`AND`) | *bool* `&&` *bool* | left | 12 | +| Logical disjunction (`OR`) | *bool* `||` *bool* | left | 13 | +| [Logical implication] | *bool* `->` *bool* | none | 14 | + +[string]: ./values.md#type-string +[path]: ./values.md#type-path +[number]: ./values.md#type-number +[list]: ./values.md#list +[attribute set]: ./values.md#attribute-set + ## Attribute selection -> *attrset* `.` *attrpath* \[ `or` *value* \] - Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*. -An attribute path is a dot-separated list of attribute names. If the attribute doesn’t exist, return *value* if provided, otherwise abort evaluation. -Associativity: none + -Precedence: 1 +An attribute path is a dot-separated list of attribute names. +An attribute name can be an identifier or a string. -## Function application +> *attrpath* = *name* [ `.` *name* ]... +> *name* = *identifier* | *string* +> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*` -> *f* *a* - -Call [function] *f* with argument *a*. - -Associativity: left - -Precedence: 2 - -## Arithmetic negation - -> `-` *n* - -Flip the sign of the [number] *n*. - -Associativity: none - -Precedence: 3 +[Attribute selection]: #attribute-selection ## Has attribute > *attrset* `?` *attrpath* -Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*; return `true` or `false`. +Test whether [attribute set] *attrset* contains the attribute denoted by *attrpath*. +The result is a [Boolean] value. -Associativity: none +[Boolean]: ./values.md#type-boolean -Precedence: 4 +[Has attribute]: #has-attribute -## List concatenation +## Arithmetic -> *list1* `++` *list2* +Numbers are type-compatible: +Pure integer operations will always return integers, whereas any operation involving at least one floating point number return a floating point number. -Concatenate [list]s *list1* and *list2*. +See also [Comparison] and [Equality]. -Associativity: right +The `+` operator is overloaded to also work on strings and paths. -Precedence: 5 - -## Multiplication - -> *n1* `*` *n2*, - -Multiply [number]s *n1* and *n2*. - -Associativity: left - -Precedence: 6 - -## Division - -> *n1* `/` *n2* - -Divide [number]s *n1* and *n2*. - -Associativity: left - -Precedence: 6 - -## Subtraction - -> *n1* `-` *n2* - -Subtract [number] *n2* from *n1*. - -Associativity: left - -Precedence: 7 - -## Addition - -> *n1* `+` *n2* - -Add [number]s *n1* and *n2*. - -Associativity: left - -Precedence: 7 +[arithmetic]: #arithmetic ## String concatenation -> *string1* `+` *string2* +> *string* `+` *string* Concatenate two [string]s and merge their string contexts. -Associativity: left - -Precedence: 7 +[String concatenation]: #string-concatenation ## Path concatenation -> *path1* `+` *path2* +> *path* `+` *path* Concatenate two [path]s. The result is a path. +[Path concatenation]: #path-concatenation + ## Path and string concatenation -> *path* `+` *string* +> *path* + *string* Concatenate *[path]* with *[string]*. The result is a path. @@ -120,13 +99,11 @@ The result is a path. > > The string must not have a string context that refers to a [store path]. -Associativity: left - -Precedence: 7 +[Path and string concatenation]: #path-and-string-concatenation ## String and path concatenation -> *string* `+` *path* +> *string* + *path* Concatenate *[string]* with *[path]*. The result is a string. @@ -136,123 +113,55 @@ The result is a string. > The file or directory at *path* must exist and is copied to the [store]. > The path appears in the result as the corresponding [store path]. -Associativity: left +[store path]: ../glossary.md#gloss-store-path +[store]: ../glossary.md#gloss-store -Precedence: 7 - -## Logical negation (`NOT`) - -> `!` *b* - -Negate the [Boolean] value *b*. - -Associativity: none - -Precedence: 8 +[Path and string concatenation]: #path-and-string-concatenation ## Update -> *attrset1* `//` *attrset1* +> *attrset1* + *attrset2* Update [attribute set] *attrset1* with names and values from *attrset2*. The returned attribute set will have of all the attributes in *e1* and *e2*. If an attribute name is present in both, the attribute value from the former is taken. -Associativity: right - -Precedence: 9 +[Update]: #update ## Comparison -- Arithmetic comparison for [number]s -- Lexicographic comparison for [string]s and [path]s -- Lexicographic comparison for [list]s: - Elements at the same index in both lists are compared according to their type and skipped if they are equal. +Comparison is -Associativity: none +- [arithmetic] for [number]s +- lexicographic for [string]s and [path]s +- item-wise lexicographic for [list]s: + elements at the same index in both lists are compared according to their type and skipped if they are equal. -Precedence: 10 +All comparison operators are implemented in terms of `<`, and the following equivalencies hold: -### Less than +| comparison | implementation | +|--------------|-----------------------| +| *a* `<=` *b* | `! (` *b* `<` *a* `)` | +| *a* `>` *b* | *b* `<` *a* | +| *a* `>=` *b* | `! (` *a* `<` *b* `)` | -> *e1* `<` *e2*, - -### Less than or equal to - -> *e1* `<=` *e2* - -### Greater than - -> *e1* `>` *e2* - -### Greater than or equal to - -> *e1* `>=` *e2* +[Comparison]: #comparison-operators ## Equality -> *e1* `==` *e2* - -Check expressions *e1* and *e2* for value equality. - - [Attribute sets][attribute set] and [list]s are compared recursively, and therefore are fully evaluated. - Comparison of [function]s always returns `false`. -- Integers are coerced to floating point numbers if compared to floating point numbers. +- Numbers are type-compatible, see [arithmetic] operators. - Floating point numbers only differ up to a limited precision. -Associativity: none +[function]: ./constructs.md#functions -Precedence: 11 - -## Inequality - -> *e1* `!=` *e2* - -Equivalent to `! (`*e1* `==` *e2* `)` - -Associativity: none - -Precedence: 11 - -## Logical conjunction (`AND`) - -> *b1* `&&` *b2* - -Return `true` if and only if both `b1` and `b2` evaluate to `true`, otherwise `false`. - -Associativity: left - -Precedence: 12 - -## Logical disjunction (`OR`) - -> *b1* `||` *b2* - -Return `true` if at least one of `b1` or `b2` evaluate to `true`, otherwise `false`. - -Associativity: left - -Precedence: 13 +[Equality]: #equality ## Logical implication -> *b1* `->` *b2* - -Return `false` if *b1* evaluates to `true` and *b2* evaluates to `false`, otherwise `true`. - Equivalent to `!`*b1* `||` *b2*. -Associativity: none +[Logical implication]: #logical-implication -Precedence: 14 - -[string]: ./values.md#type-string -[path]: ./values.md#type-path -[number]: ./values.md#type-number -[Boolean]: ./values.md#type-boolean -[list]: ./values.md#list -[attribute set]: ./values.md#attribute-set -[function]: ./constructs.md#functions -[store path]: ../glossary.md#gloss-store-path -[store]: ../glossary.md#gloss-store diff --git a/doc/manual/src/language/values.md b/doc/manual/src/language/values.md index d92f287a3..3973518ca 100644 --- a/doc/manual/src/language/values.md +++ b/doc/manual/src/language/values.md @@ -85,11 +85,10 @@ Numbers, which can be *integers* (like `123`) or *floating point* (like `123.43` or `.27e13`). - Numbers are type-compatible: pure integer operations will always - return integers, whereas any operation involving at least one - floating point number will have a floating point number as a result. + See [arithmetic] and [comparison] operators for semantics. - Floating point numbers only differ up to a limited precision. + [arithmetic]: ./operators.md#arithmetic + [comparison]: ./operators.md#comparison - Path