diff --git a/preserves.nimble b/preserves.nimble index 5a39704..7363ada 100644 --- a/preserves.nimble +++ b/preserves.nimble @@ -1,6 +1,6 @@ # Package -version = "20240118" +version = "20240206" author = "Emery Hemingway" description = "data model and serialization format" license = "Unlicense" diff --git a/src/preserves.nim b/src/preserves.nim index 570cfd0..6ed4c77 100644 --- a/src/preserves.nim +++ b/src/preserves.nim @@ -56,8 +56,7 @@ func isFalse*(pr: Value): bool {.inline.} = func isFloat*(pr: Value): bool {.inline.} = pr.kind == pkFloat ## Check if ``pr`` is a Preserve float. -func isDouble*(pr: Value): bool {.inline.} = pr.kind == pkDouble - ## Check if ``pr`` is a Preserve double. +func isDouble*(pr: Value): bool {.deprecated: "use isFloat".} = pr.kind == pkFloat func isInteger*(pr: Value): bool {.inline.} = ## Check if ``pr`` is a Preserve integer. @@ -363,10 +362,8 @@ proc toPreserves*[T](x: T): Value {.gcsafe.} = cannonicalize(result) elif T is bool: result = Value(kind: pkBoolean, bool: x) - elif T is float32: - result = Value(kind: pkFloat, float: x) - elif T is float64: - result = Value(kind: pkDouble, double: x) + elif T is SomeFloat: + result = Value(kind: pkFloat, float: float(x)) elif T is tuple: result = Value(kind: pkSequence, sequence: newSeqOfCap[Value](tupleLen(T))) @@ -469,8 +466,6 @@ proc toPreservesHook*(a: Atom): Value = result.bool = a.bool of pkFloat: result.float = a.float - of pkDouble: - result.double = a.double of pkRegister: result.register = a.register of pkBigInt: @@ -530,17 +525,10 @@ proc fromAtom*[T](v: var T; a: ATom): bool = if a.kind == pkByteString: v = a.bytes result = true - elif T is float32: - if a.kind == pkFloat: - v = a.float - result = true - elif T is float64: + elif T is SomeFloat: case a.kind of pkFloat: - v = a.float - result = true - of pkDouble: - v = a.double + v = T a.float result = true else: discard elif T is Ordinal | SomeInteger: @@ -615,19 +603,10 @@ proc fromPreserves*[T](v: var T; pr: Value): bool {.gcsafe.} = if not result: v.setLen 0 break - elif T is float32: + elif T is SomeFloat: if pr.kind == pkFloat: - v = pr.float + v = (T)pr.float result = true - elif T is float64: - case pr.kind - of pkFloat: - v = pr.float - result = true - of pkDouble: - v = pr.double - result = true - else: discard elif T is Ordinal | SomeInteger: case pr.kind of pkRegister: @@ -884,7 +863,7 @@ proc apply*(result: var Value; op: proc(_: var Value) {.gcsafe.}) {.gcsafe.} = proc recurse(result: var Value) = apply(result, op) op(result) case result.kind - of pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt, + of pkBoolean, pkFloat, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol, pkEmbedded: discard of pkRecord: @@ -902,7 +881,7 @@ proc apply*(result: var Value; op: proc(_: var Value) {.gcsafe.}) {.gcsafe.} = proc mapEmbeds*(pr: sink Value; op: proc (x: Value): Value {.gcsafe.}): Value {.gcsafe.} = ## Process all embeds in a `Value`. case pr.kind - of pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt, + of pkBoolean, pkFloat, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol, pkEmbedded: result = pr of pkRecord: diff --git a/src/preserves/jsonhooks.nim b/src/preserves/jsonhooks.nim index d1cdcc6..df335ff 100644 --- a/src/preserves/jsonhooks.nim +++ b/src/preserves/jsonhooks.nim @@ -41,8 +41,6 @@ proc fromPreservesHook*(js: var JsonNode; pr: Value): bool = js = newJBool(pr.bool) of pkFloat: js = newJFloat(pr.float) - of pkDouble: - js = newJFloat(pr.double) of pkRegister: js = newJInt(pr.register) of pkString: diff --git a/src/preserves/pegs.nim b/src/preserves/pegs.nim index 69c2934..34ff72c 100644 --- a/src/preserves/pegs.nim +++ b/src/preserves/pegs.nim @@ -15,7 +15,7 @@ grammar "Preserves": Document <- Value * ws * !1 - Atom <- Boolean | Float | Double | FloatRaw | DoubleRaw | SignedInteger | String | ByteString | Symbol + Atom <- Boolean | Double | DoubleRaw | SignedInteger | String | ByteString | Symbol Collection <- Sequence | Dictionary | Set @@ -40,8 +40,7 @@ grammar "Preserves": exp <- 'e' * ?('-'|'+') * +Digit flt <- int * ((frac * exp) | frac | exp) - Float <- >flt * {'f','F'} * &delimiter - Double <- flt * &delimiter + Double <- >flt * &delimiter SignedInteger <- int * &delimiter @@ -75,5 +74,4 @@ grammar "Preserves": Compact <- "#=" * ws * ByteString - FloatRaw <- "#xf\"" * >((ws * Xdigit[2])[4]) * ws * '"' DoubleRaw <- "#xd\"" * >((ws * Xdigit[2])[8]) * ws * '"' diff --git a/src/preserves/preserves_schema_nim.nim b/src/preserves/preserves_schema_nim.nim index 2914670..bcf7692 100644 --- a/src/preserves/preserves_schema_nim.nim +++ b/src/preserves/preserves_schema_nim.nim @@ -411,8 +411,7 @@ proc isAny(loc: Location; def: Definition): bool = proc typeIdent(atom: AtomKind): PNode = case atom of AtomKind.Boolean: ident"bool" - of AtomKind.Float: ident"float32" - of AtomKind.Double: ident"float64" + of AtomKind.Double: ident"float" of AtomKind.Signedinteger: ident"BiggestInt" of AtomKind.String: ident"string" of AtomKind.Bytestring: nkBracketExpr.newTree(ident"seq", ident"byte") diff --git a/src/preserves/private/decoding.nim b/src/preserves/private/decoding.nim index f9a5be0..6987d99 100644 --- a/src/preserves/private/decoding.nim +++ b/src/preserves/private/decoding.nim @@ -30,19 +30,21 @@ proc decodePreserves*(s: Stream): Value = result = decodePreserves(s) result.embedded = true of 0x87: + result = Value(kind: pkFloat) var N: int let n = int s.readUint8() case n of 4: - result = Value(kind: pkFloat) - var buf: uint32 + var + buf: uint32 + float: float32 N = s.readData(addr buf, sizeof(buf)) - bigEndian32(addr result.float, addr buf) + bigEndian32(addr float, addr buf) + result.float = BiggestFloat float of 8: - result = Value(kind: pkDouble) var buf: uint64 N = s.readData(addr buf, sizeof(buf)) - bigEndian64(addr result.double, addr buf) + bigEndian64(addr result.float, addr buf) else: raise newException(IOError, "unhandled IEEE754 value of " & $n & " bytes") if N != n: raise newException(IOError, "short read") diff --git a/src/preserves/private/encoding.nim b/src/preserves/private/encoding.nim index 985c7fd..872c2c0 100644 --- a/src/preserves/private/encoding.nim +++ b/src/preserves/private/encoding.nim @@ -21,20 +21,12 @@ proc write*(str: Stream; pr: Value) = of false: str.write(0x80'u8) of true: str.write(0x81'u8) of pkFloat: - str.write("\x87\x04") - when system.cpuEndian == bigEndian: - str.write(pr.float) - else: - var be: float32 - swapEndian32(be.addr, pr.float.unsafeAddr) - str.write(be) - of pkDouble: str.write("\x87\x08") when system.cpuEndian == bigEndian: str.write(pr.double) else: var be: float64 - swapEndian64(be.addr, pr.double.unsafeAddr) + swapEndian64(be.addr, pr.float.unsafeAddr) str.write(be) of pkRegister: if pr.register == 0: str.write("\xb0\x00") diff --git a/src/preserves/private/parsing.nim b/src/preserves/private/parsing.nim index cf9bb44..381d8ac 100644 --- a/src/preserves/private/parsing.nim +++ b/src/preserves/private/parsing.nim @@ -155,23 +155,13 @@ proc parsePreserves*(text: string): Value = of "#t": pushStack Value(kind: pkBoolean, bool: true) else: discard - Preserves.Float <- Preserves.Float: - pushStack Value(kind: pkFloat, float: parseFloat($1)) - Preserves.Double <- Preserves.Double: - pushStack Value(kind: pkDouble) - let i = stack.high - discard parseBiggestFloat($0, stack[i].value.double) - - Preserves.FloatRaw <- Preserves.FloatRaw: - var reg: uint32 - for c in $1: pushHexNibble(reg, c) - pushStack Value(kind: pkFloat, float: cast[float32](reg)) + pushStack Value(kind: pkFloat, float: parseFloat($1)) Preserves.DoubleRaw <- Preserves.DoubleRaw: var reg: uint64 for c in $1: pushHexNibble(reg, c) - pushStack Value(kind: pkDouble, double: cast[float64](reg)) + pushStack Value(kind: pkFloat, float: cast[float64](reg)) Preserves.SignedInteger <- Preserves.SignedInteger: var @@ -239,21 +229,13 @@ proc parsePreservesAtom*(text: string): Atom = else: discard Preserves.Float <- Preserves.Float: - a = Atom(kind: pkFloat, float: parseFloat($1)) - - Preserves.Double <- Preserves.Double: - a = Atom(kind: pkDouble) - discard parseBiggestFloat($0, a.double) + a = Atom(kind: pkFloat) + validate(parseBiggestFloat($0, a.float) == len($0)) Preserves.FloatRaw <- Preserves.FloatRaw: - var reg: uint32 - for c in $1: pushHexNibble(reg, c) - a = Atom(kind: pkFloat, float: cast[float32](reg)) - - Preserves.DoubleRaw <- Preserves.DoubleRaw: var reg: uint64 for c in $1: pushHexNibble(reg, c) - a = Atom(kind: pkDouble, double: cast[float64](reg)) + a = Atom(kind: pkFloat, float: cast[float64](reg)) Preserves.SignedInteger <- Preserves.SignedInteger: var diff --git a/src/preserves/private/texts.nim b/src/preserves/private/texts.nim index ca97078..f7fd678 100644 --- a/src/preserves/private/texts.nim +++ b/src/preserves/private/texts.nim @@ -54,22 +54,9 @@ proc writeText*(stream: Stream; pr: Value; mode = textPreserves) = case pr.float.classify: of fcNormal, fcZero, fcNegZero: write(stream, $pr.float) - write(stream, 'f') - else: - var buf: array[4, byte] - bigEndian32(addr buf[0], addr pr.float) - write(stream, "#xf\"") - for b in buf: - write(stream, hexAlphabet[b shr 4]) - write(stream, hexAlphabet[b and 0xf]) - write(stream, '"') - of pkDouble: - case pr.double.classify: - of fcNormal, fcZero, fcNegZero: - write(stream, $pr.double) else: var buf: array[8, byte] - bigEndian64(addr buf[0], addr pr.double) + bigEndian64(addr buf[0], addr pr.float) write(stream, "#xd\"") for b in buf: write(stream, hexAlphabet[b shr 4]) diff --git a/src/preserves/private/values.nim b/src/preserves/private/values.nim index 1dce998..87feeb2 100644 --- a/src/preserves/private/values.nim +++ b/src/preserves/private/values.nim @@ -7,11 +7,11 @@ import bigints type PreserveKind* = enum - pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol, + pkBoolean, pkFloat, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol, pkRecord, pkSequence, pkSet, pkDictionary, pkEmbedded const - atomKinds* = {pkBoolean, pkFloat, pkDouble, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol} + atomKinds* = {pkBoolean, pkFloat, pkRegister, pkBigInt, pkString, pkByteString, pkSymbol} compoundKinds* = {pkRecord, pkSequence, pkSet, pkDictionary} type Symbol* = distinct string @@ -28,9 +28,7 @@ type of pkBoolean: bool*: bool of pkFloat: - float*: float32 - of pkDouble: - double*: float64 + float*: float of pkRegister: register*: int of pkBigInt: @@ -49,9 +47,7 @@ type of pkBoolean: bool*: bool of pkFloat: - float*: float32 - of pkDouble: - double*: float64 + float*: float of pkRegister: register*: int of pkBigInt: @@ -97,8 +93,6 @@ func `==`*(x, y: Value): bool = result = x.bool == y.bool of pkFloat: result = x.float === y.float - of pkDouble: - result = x.double === y.double of pkRegister: result = x.register == y.register of pkBigInt: @@ -151,8 +145,6 @@ proc `<`*(x, y: Value): bool = result = (not x.bool) and y.bool of pkFloat: result = x.float < y.float - of pkDouble: - result = x.double < y.double of pkRegister: result = x.register < y.register of pkBigInt: @@ -206,8 +198,6 @@ proc hash*(pr: Value): Hash = h = h !& hash(pr.bool) of pkFloat: h = h !& hash(pr.float) - of pkDouble: - h = h !& hash(pr.double) of pkRegister: h = h !& hash(pr.register) of pkBigInt: diff --git a/src/preserves/schema.nim b/src/preserves/schema.nim index 14227d5..fbb653a 100644 --- a/src/preserves/schema.nim +++ b/src/preserves/schema.nim @@ -54,10 +54,9 @@ type `ref`*: Ref - Definitions* = Table[Symbol, Definition] `AtomKind`* {.preservesOr, pure.} = enum - `Boolean`, `Float`, `Double`, `SignedInteger`, `String`, `ByteString`, - `Symbol` + `Boolean`, `Double`, `SignedInteger`, `String`, `ByteString`, `Symbol` + Definitions* = Table[Symbol, Definition] DictionaryEntries* = Table[Value, NamedSimplePattern] NamedPatternKind* {.pure.} = enum `named`, `anonymous` diff --git a/src/preserves/schemaparse.nim b/src/preserves/schemaparse.nim index 20223a1..39b68f7 100644 --- a/src/preserves/schemaparse.nim +++ b/src/preserves/schemaparse.nim @@ -128,7 +128,6 @@ const parser = peg("Schema", p: ParseState): AltLiteralPattern <- >Preserves.Boolean | - >Preserves.Float | >Preserves.Double | >Preserves.SignedInteger | >Preserves.String | @@ -161,14 +160,11 @@ const parser = peg("Schema", p: ParseState): AnyPattern <- "any": pushStack toSymbol"any" - AtomKindPattern <- Boolean | Float | Double | SignedInteger | String | ByteString | Symbol + AtomKindPattern <- Boolean | Double | SignedInteger | String | ByteString | Symbol Boolean <- "bool": pushStack initRecord(toSymbol"atom", toSymbol"Boolean") - Float <- "float": - pushStack initRecord(toSymbol"atom", toSymbol"Float") - Double <- "double": pushStack initRecord(toSymbol"atom", toSymbol"Double") @@ -283,7 +279,6 @@ const parser = peg("Schema", p: ParseState): nonSymbolAtom <- Preserves.Boolean | - Preserves.Float | Preserves.Double | Preserves.SignedInteger | Preserves.String | diff --git a/src/preserves/xmlhooks.nim b/src/preserves/xmlhooks.nim index c2f000b..b8ac350 100644 --- a/src/preserves/xmlhooks.nim +++ b/src/preserves/xmlhooks.nim @@ -14,7 +14,7 @@ proc toPreservesFromString*(s: string): Value = else: var n: BiggestInt - f: BiggestFloat + f: float if parseBiggestInt(s, n) == s.len: result = toPreserves(n) elif parseHex(s, n) == s.len: diff --git a/tests/test_parser.nim b/tests/test_parser.nim index f628862..5b0374e 100644 --- a/tests/test_parser.nim +++ b/tests/test_parser.nim @@ -16,7 +16,6 @@ const examples = [ ("""0""", "\xB0\x00"), ("""1""", "\xB0\x01\x01"), ("""255""", "\xB0\x02\x00\xFF"), -("""1.0f""", "\x87\x04\x3F\x80\x00\x00"), ("""1.0""", "\x87\x08\x3F\xF0\x00\x00\x00\x00\x00\x00"), ("""-1.202e300""", "\x87\x08\xFE\x3C\xB7\xB7\x59\xBF\x04\x26"), ("""#=#x"B4B30763617074757265B4B307646973636172648484"""", "\xB4\xB3\x07capture\xB4\xB3\x07discard\x84\x84"),