Simpler Preserves Binary Syntax
Sun 15 Oct 2023 15:21 CEST
I’ve just updated the Preserves spec to version 0.990.0. I feel like a 1.0-rc is approaching!
The main change since spec version 0.7.1 has been to simplify the binary syntax for Preserves
Value
s:
-
Both “short” and “medium”
SignedInteger
representations (starting with tags0x9x
/0xAx
) were removed. They weren’t pulling their weight. EverySignedInteger
now has tag0xB0
. -
Float
andDouble
are now encoded with tag0x87
and a length, rather than with fixed tags0x82
and0x83
, opening the door to other IEEE754 formats in future.
Here’s the 0.990.0 syntax in “reference card” format,
where we write «V»
for the binary encoding of some value V
:
«#f» = [0x80]
«#t» = [0x81]
«@W V» = [0x85] ++ «W» ++ «V»
«#!V» = [0x86] ++ «V»
«V» if V ∈ Float = [0x87, 0x04] ++ binary32(V)
«V» if V ∈ Double = [0x87, 0x08] ++ binary64(V)
«V» if V ∈ SignedInteger = [0xB0] ++ varint(|intbytes(V)|) ++ intbytes(V)
«V» if V ∈ String = [0xB1] ++ varint(|utf8(V)|) ++ utf8(V)
«V» if V ∈ ByteString = [0xB2] ++ varint(|V|) ++ V
«V» if V ∈ Symbol = [0xB3] ++ varint(|utf8(V)|) ++ utf8(V)
«<L F_1...F_m>» = [0xB4] ++ «L» ++ «F_1» ++...++ «F_m» ++ [0x84]
«[X_1...X_m]» = [0xB5] ++ «X_1» ++...++ «X_m» ++ [0x84]
«#{E_1...E_m}» = [0xB6] ++ «E_1» ++...++ «E_m» ++ [0x84]
«{K_1:V_1...K_m:V_m}» = [0xB7] ++ «K_1» ++ «V_1» ++...++ «K_m» ++ «V_m» ++ [0x84]
varint(v) = [v] if v < 128
[(v & 0x7F) + 128] ++ varint(v >> 7) if v ≥ 128