A general purpose notation for data interchange.
.fin
.application/fin
.U+FEFF
at the start of input.U+000A
code point.U+0020
U+0009
U+000A
U+000D
examples = [
# symbols
foo, foo_bar, _98, foo_, _98_, _
:key, crypto:sha256, :a:b:c:_:_98_
]
U+003A
U+005F
U+0061 - U+007A
U+0030 - U+0039
examples = [
# numbers
98, 1.23e4, -42, 0, 84e0
0.55, -0.123e-4, -0.00
]
U+0030 - U+0039
U+002D
U+002E
U+0065
.dig = "0" ... "9" . dig1 = "1" ... "9" . int = "0" | dig1 {dig} . frac = "." dig {dig} . exp = "e" [ "-" ] int . number = [ "-" ] int [ frac ] [ exp ] .
NaN
or +/- infinity
. Use extensions.U+0022
that represents valid Unicode text.\
backslash U+005C
initiates an escape sequence.\\
backslash U+005C
.\"
double quotation U+0022
. Prevents early termination of the string.\n
line feed U+000A
.\r
carriage return U+OOOD
.\t
horizontal tab U+0009
.\u{hex}
Unicode escape. Where hex
is the hexadecimal number for a Unicode code point.examples = [
""
"fin 🐬"
"escape sequences \\ \" \t \n \r \u{7f}"
]
accept
U+007C
.U+000A
which transitions the state to ignore
.ignore
U+0020
and horizontal tabs U+0009
.|
transitions the state back to accept
.examples = [
|a raw string
|raw strings are not interpreted.
| - unescaped \n, #not a comment,
| - this bar | is part of the string.
|can span multiple lines.
|another raw string 🐬
|this one ends with a line feed
|
# below is an empty raw string
|
]
U+0023
and are not treated as values.# comments can span multiple
# lines just like raw strings
# unlike raw strings they're not values. 🐬
U+005B
and ] U+005D
expanded_array = [
# expanded array elements are indented with tabs.
# consecutive empty lines are removed.
# comma is used to separate values on the same line.
a, 98, [
# commas can be used pre/post expanded notation.
| comments and raw strings trigger expansion.
], "foo"
# for inline arrays - elements are comma separated
# on the same line as the surrounding brackets
[], tagged["array"], [98, goal, []]
]
U+0028
and ) U+0029
expanded_map = (
# like arrays expanded map elements are indented with tabs.
# consecutive empty lines are removed.
# comma is used to separate entries on the same line.
a = b, 1 = "two"
# keys and vals can also be other collections
# inline maps have entries on the same line comma separated
() = tag(cb = 98, kk = 55)
)
U+003D
# example map entries
# most keys in the wild are symbols, strings or numbers
# however, fin supports all value types as keys
# inline-inline
a = 98, nested = (a = 98)
# inline-block
b =
|raw
# block-inline
|c
= 98
# block-block
|d
=
|e
(
# key is an expanded map
a = 98
) = [
# val is an expanded array
], f =
| line continuation (comma) works
| after expanded vals & before expanded keys
_
they are non-values.extensions = [
# builtin extensions (start with fin:)
fin:timestamp["2024-02-26T03:01:13.644Z"]
fin:bytes[
|f6 69 6e 20 54 d6 78 74
|2a 46 6f 72 6d 61 74 0a
]
fin:uuid["c83ccbb6-44d0-4d62-8263-b8afec01f3a2"]
# booleans are builtins
true, false
# extensions ending with _ are discarded
fin:_(is_value = false, treated_as = "comment")
# custom extensions (start with ext:)
ext:null, ext:nan, ext:int:hex_10fe
ext:loc(x = 1, y = 2)
ext:markdown[
|# title
|
|a **markdown** extension!
]
]