Skip to content

Commit 07788d1

Browse files
committed
number suffix type annotations
Fixes: #510
1 parent a88c450 commit 07788d1

25 files changed

+99
-4
lines changed

draft-marchan-kdl2.md

+75-4
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,66 @@ 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-string}})s 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-suffix-type-annotation}})s, Explicit Suffixes
321+
may be used with ALL ({{number}}) formats (hexadecimal, decimal, octal, and
322+
binary). For example, `0x1234#u16` is valid.
323+
324+
### Reserved Type Annotations for Numbers Without Decimals
325+
326+
Additionally, the following type annotations MAY be recognized by KDL parsers
327+
and, if used, SHOULD interpret these types as follows.
272328

273329
Signed integers of various sizes (the number is the bit size):
274330

@@ -335,6 +391,7 @@ IEEE 754-2008 decimal floating point numbers
335391

336392
~~~kdl
337393
node (u8)123
394+
node 123#i64
338395
node prop=(regex).*
339396
(published)date "1970-01-01"
340397
(contributor)person name="Foo McBar"
@@ -1013,12 +1070,26 @@ multi-line-raw-string-body :=
10131070
// Numbers
10141071
number := keyword-number | hex | octal | binary | decimal
10151072

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

1085+
bare-type-suffix := bare-type-suffix-initial identifier-char*
1086+
bare-type-suffix-initial := identifier-char
1087+
- '.' - ',' - '_'
1088+
- ([a-zA-Z] [0-9_])
1089+
- (('e' | 'E') sign? digit)
1090+
- (('x' | 'X') [a-fA-F])
1091+
explicit-type-suffix := '#' identifier-string
1092+
10221093
hex := sign? '0x' hex-digit (hex-digit | '_')*
10231094
octal := sign? '0o' [0-7] [0-7_]*
10241095
binary := sign? '0b' ('0' | '1') ('0' | '1' | '_')*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node (abc)123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node (abc)123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node (abc)12300000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node (abc)5 (def)83 (zzz)291
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123,abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123e5e5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123e5abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123xabc123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node #truefoo #false#bar #nullish #nan#no #inf123 #-inf#123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123u8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 0b0101abc 0o123def 0x123zzz
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123"astring" 456#"rawstring"#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123.abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node (abc)123def
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node "foo"bar
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123_abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123#abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123e5#abc
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123#true 456#false 789#null 012#nan 345#inf 678#-inf
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 0b0101#abc 0o123#def 0x123#zzz
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123#"string" 456##"rawstring"#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node 123#123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node (abc)123#def

0 commit comments

Comments
 (0)