new approach to these

This commit is contained in:
Kat Marchán 2025-04-17 13:20:56 -07:00
parent 662917ce0b
commit 1362646825
No known key found for this signature in database
GPG Key ID: AEB529C08A3C7E9E
1 changed files with 30 additions and 28 deletions

View File

@ -272,15 +272,13 @@ annotation as a "suffix", instead of prepending it between `(` and `)`. This
makes it possible to, for example, write `10px`, `10.5%`, `512GiB`, etc., which makes it possible to, for example, write `10px`, `10.5%`, `512GiB`, etc., which
are equivalent to `(px)10`, `(%)5`, and `(GiB)512`, respectively. are equivalent to `(px)10`, `(%)5`, and `(GiB)512`, respectively.
Most suffixes can be appended directly to the number Most suffixes can be appended directly to the number (a
(a ({{bare-suffix-type-annotation}})), ({{bare-suffix-type-annotation}})), as shown in the previous paragraph. To avoid
as shown in the previous paragraph. parsing ambiguity, there are some restrictions on this; an
To avoid parsing ambiguity, there are some restrictions on this; ({{explicit-suffix-type-annotation}}) avoids all these restrictions by using an
an ({{explicit-suffix-type-annotation}}) avoids all these restrictions additional `#` to explicitly indicate it. For example, `10.0u8` is invalid, but
by using an additional `#` to explicitly indicate it. `10.0#u8` is valid and equivalent to `(u8)10.0`. See
For example, `10.0u8` is invalid, but `10.0#u8` is valid ({{bare-suffix-type-annotation}}) for the full list of restrictions.
and equivalent to `(u8)10.0`.
See the "Bare Suffix Type Annotation" section for the full list of restrictions.
An implementation that finds BOTH a parenthesized and a suffix An implementation that finds BOTH a parenthesized and a suffix
({{type-annotation}}) on the same ({{number}}) MUST yield a syntax error. ({{type-annotation}}) on the same ({{number}}) MUST yield a syntax error.
@ -294,8 +292,9 @@ There are two kinds of ({{suffix-type-annotation}}) available:
#### Bare Suffix Type Annotation #### Bare Suffix Type Annotation
When a ({{value}}) is a decimal ({{number}}) WITHOUT exponential syntax (`1e+5` When a ({{value}}) is a decimal ({{number}}) WITHOUT exponential syntax (`1e+5`
etc) (and ONLY a decimal), it's possible to attach the type annotation as a etc) (and ONLY a decimal: that is, numbers which do NOT have a `0b`/`0o`/`0x`
suffix directly to the number, without any additional syntax. prefix), it's possible to attach the type annotation as a suffix directly to the
number, without any additional syntax.
They also come with some additional rules (like only being available for They also come with some additional rules (like only being available for
decimals), in order to prevent potential ambiguity or footguns with the syntax. decimals), in order to prevent potential ambiguity or footguns with the syntax.
@ -305,16 +304,17 @@ designing this feature, it was determined that the value for various real-world
DSLs outweighed the complexity of the following rules. DSLs outweighed the complexity of the following rules.
As such, to remove ambiguity, the suffix ({{identifier-string}}) MUST NOT start As such, to remove ambiguity, the suffix ({{identifier-string}}) MUST NOT start
with any of the following patterns, all of which MUST yield syntax errors with any of the following patterns, all of which MUST yield syntax errors (if
(if they can be distinguished from other syntaxes at all): they can be distinguished from other syntaxes at all):
* `.`, `,`, or `_` * `.`, `,`, or `_`
* `[a-zA-Z][0-9_]` (to disambiguate all non-decimals, with breathing room)
* `[eE][+-]?[0-9]` (to disambiguate exponentials) * `[eE][+-]?[0-9]` (to disambiguate exponentials)
* `[xX][a-fA-F]` (to disambiguate hexadecimals)
For example, `10,000` is illegal, as is `10u16`. `10e0n` is illegal, but `10e0` is a legal For example, `10,000` is illegal. `10e0n` is illegal, but `10e0` is a legal
*decimal number using exponential syntax*, __not__ equivalent to `(e0)10`. *decimal number using exponential syntax*, __not__ equivalent to `(e0)10`.
Additionally, note that since bare suffixes are only legal on _decimals_, `0u8`
is legal, but `0xs` is _not_, since hexadecimals are determined by their
prefixes. Similarly, `1xs` _is_ legal, and equivalent to `(xs)1`.
All other ({{identifier-string}})s can be safely appended to decimal numbers, so All other ({{identifier-string}})s can be safely appended to decimal numbers, so
long as the decimal does not include an exponential component. long as the decimal does not include an exponential component.
@ -329,11 +329,11 @@ Any ({{number}}) may have a `#` appended to it, followed by any valid
({{identifier-string}}). This is an explicit ({{suffix-type-annotation}}) syntax ({{identifier-string}}). This is an explicit ({{suffix-type-annotation}}) syntax
without any of the relatively complex requirements of without any of the relatively complex requirements of
({{bare-suffix-type-annotation}}), which can be a useful escape hatch. For ({{bare-suffix-type-annotation}}), which can be a useful escape hatch. For
example: `10.0#u8` is invalid syntax without the `#` prefix. example: `0#b1` is invalid syntax without the `#` prefix.
Note again that, unlike ({{bare-suffix-type-annotation}})s, Explicit Suffixes Note again that, unlike ({{bare-suffix-type-annotation}})s, Explicit Suffixes
may be used with ALL ({{number}}) formats (hexadecimal, decimal, octal, and may be used with ALL ({{number}}) formats (hexadecimal, decimal, octal, and
binary). For example, `0x1234#u16` is valid. binary). For example, `0x1234#u32` is valid.
### Reserved Type Annotations for Numbers Without Decimals ### Reserved Type Annotations for Numbers Without Decimals
@ -1022,8 +1022,9 @@ node-children := '{' nodes final-node? '}'
node-terminator := single-line-comment | newline | ';' | eof node-terminator := single-line-comment | newline | ';' | eof
prop := string node-space* '=' node-space* value prop := string node-space* '=' node-space* value
value := type? node-space* (string | number | keyword) value := normal-value | suffixed-decimal
type := '(' node-space* string node-space* ')' type := '(' node-space* string node-space* ')'
normal-value := type? node-space* (string | number | keyword)
// Strings // Strings
string := identifier-string | quoted-string | raw-string ¶ string := identifier-string | quoted-string | raw-string ¶
@ -1084,24 +1085,25 @@ multi-line-raw-string-body :=
// Numbers // Numbers
number := keyword-number | hex | octal | binary | decimal number := keyword-number | hex | octal | binary | decimal
decimal := sign? integer ('.' integer)? ( decimal := significand exponent?
// NOTE: This grammar does not explicitly guard against having both suffixed-decimal := significand (
// parenthesized and type suffixes. bare-type-suffix
bare-type-suffix | | (exponent? explicit-type-suffix)
explicit-type-suffix | )
(exponent explicit-type-suffix?) significand := sign? significand-initial integer? ('.' integer)?
)?
exponent := ('e' | 'E') sign? integer exponent := ('e' | 'E') sign? integer
integer := digit (digit | '_')* integer := digit (digit | '_')*
significand-initial = digit
- '0b'
- '0o'
- '0x'
digit := [0-9] digit := [0-9]
sign := '+' | '-' sign := '+' | '-'
bare-type-suffix := bare-type-suffix-initial identifier-char* bare-type-suffix := bare-type-suffix-initial identifier-char*
bare-type-suffix-initial := identifier-char bare-type-suffix-initial := identifier-char
- '.' - ',' - '_' - '.' - ',' - '_'
- ([a-zA-Z] [0-9_])
- (('e' | 'E') sign? digit) - (('e' | 'E') sign? digit)
- (('x' | 'X') [a-fA-F])
explicit-type-suffix := '#' identifier-string explicit-type-suffix := '#' identifier-string
hex := sign? '0x' hex-digit (hex-digit | '_')* hex := sign? '0x' hex-digit (hex-digit | '_')*