Skip to content

Commit 58f3d2a

Browse files
committed
number suffix type annotations
Fixes: #510
1 parent a88c450 commit 58f3d2a

File tree

1 file changed

+74
-4
lines changed

1 file changed

+74
-4
lines changed

draft-marchan-kdl2.md

+74-4
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,65 @@ KDL does not specify any restrictions on what implementations might do with
265265
these annotations. They are free to ignore them, or use them to make decisions
266266
about how to interpret a value.
267267

268-
Additionally, the following type annotations MAY be recognized by KDL parsers
269-
and, if used, SHOULD interpret these types as follows:
268+
### Suffix Type Annotation
269+
270+
When a ({{value}}) is a ({{number}}), it's possible to attach the type
271+
annotation as a "suffix", instead of prepending it between `(` and `)`. This
272+
makes it possible to, for example, write `10px`, `10.5%`, `512GiB`, etc., which
273+
are equivalent to `(px)10`, `(%)5`, and `(GiB)512`, respectively.
274+
275+
An implementation that finds BOTH a parenthesized and a suffix
276+
({{type-annotation}}) on the same ({{number}}) MUST yield a syntax error.
277+
278+
Suffixes MUST BE plain ({{identifier-string}})s. No other ({{string}}) is
279+
acceptable.
280+
281+
There are two kinds of ({{suffix-type-annotation}}) available:
282+
({{bare-suffix-type-annotation}})s and ({{explicit-suffix-type-annotation}}).
283+
284+
#### Bare Suffix Type Annotation
285+
286+
When a ({{value}}) is a decimal ({{number}}) WITHOUT exponential syntax (`1e+5`
287+
etc) (and ONLY a decimal), it's possible to attach the type annotation as a
288+
suffix directly to the number, without any additional syntax.
289+
290+
They also come with some additional rules (like only being available for
291+
decimals), in order to prevent potential ambiguity or footguns with the syntax.
292+
This is generally acceptable, as type annotations in particular tend to be
293+
application-defined and limited in scope, rather than arbitrary user data. In
294+
designing this feature, it was determined that the value for various real-world
295+
DSLs outweighed the complexity of the following rules.
296+
297+
As such, to remove ambiguity, the suffix ({{identifier-string}}) MUST NOT start
298+
with any of the following patterns, all of which MUST yield syntax errors:
270299

271-
### Reserved Type Annotations for Numbers Without Decimals:
300+
* `.`, `,`, or `_`
301+
* `[a-zA-Z][0-9_]` (to disambiguate all non-decimals, with breathing room)
302+
* `[eE][+-]?[0-9]` (to disambiguate exponentials)
303+
* `[xX][a-fA-F]` (to disambiguate hexadecimals)
304+
305+
All other ({{identifier-strings}}) can be safely appended to decimal numbers, so
306+
long as the decimal does not include an exponential component.
307+
308+
If the desired suffix would violate any of the above rules, either regular
309+
parenthetical ({{type-annotation}})s, or ({{explicit-suffix-type-annotation}})s
310+
may be used.
311+
312+
#### Explicit Suffix Type Annotation
313+
314+
Any ({{number}}) may have a `#` attached to it, followed by any valid
315+
({{identifier-string}}). This is an explicit ({{suffix-type-annotation}}) syntax
316+
without any of the relatively complex requirements of
317+
({{bare-suffix-type-annotation}}), which can be a useful escape hatch. For
318+
example: `10.0#u8` is invalid syntax without the `#` prefix.
319+
320+
Note again that, unlike Bare Suffixes, Explicit Suffixes may be used with ALL
321+
({{number}}) formats (hexadecimal, decimal, octal, and binary).
322+
323+
### Reserved Type Annotations for Numbers Without Decimals
324+
325+
Additionally, the following type annotations MAY be recognized by KDL parsers
326+
and, if used, SHOULD interpret these types as follows.
272327

273328
Signed integers of various sizes (the number is the bit size):
274329

@@ -335,6 +390,7 @@ IEEE 754-2008 decimal floating point numbers
335390

336391
~~~kdl
337392
node (u8)123
393+
node 123#i64
338394
node prop=(regex).*
339395
(published)date "1970-01-01"
340396
(contributor)person name="Foo McBar"
@@ -1013,12 +1069,26 @@ multi-line-raw-string-body :=
10131069
// Numbers
10141070
number := keyword-number | hex | octal | binary | decimal
10151071

1016-
decimal := sign? integer ('.' integer)? exponent?
1072+
decimal := sign? integer ('.' integer)? (
1073+
// NOTE: This grammar does not explicitly guard against having both
1074+
// parenthesized and type suffixes.
1075+
bare-type-suffix |
1076+
explicit-type-suffix |
1077+
(exponent explicit-type-suffix?)
1078+
)?
10171079
exponent := ('e' | 'E') sign? integer
10181080
integer := digit (digit | '_')*
10191081
digit := [0-9]
10201082
sign := '+' | '-'
10211083

1084+
bare-type-suffix := bare-type-suffix-initial identifier-char*
1085+
bare-type-suffix-initial := identifier-char
1086+
- '.' - ',' - '_'
1087+
- ([a-zA-Z] [0-9_])
1088+
- (('e' | 'E') sign? digit)
1089+
- (('x' | 'X') [a-fA-F])
1090+
explicit-type-suffix := '#' identifier-string
1091+
10221092
hex := sign? '0x' hex-digit (hex-digit | '_')*
10231093
octal := sign? '0o' [0-7] [0-7_]*
10241094
binary := sign? '0b' ('0' | '1') ('0' | '1' | '_')*

0 commit comments

Comments
 (0)