From 75916ea0ddd77f646339b16e17628cc75924ba44 Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Fri, 22 Dec 2023 22:16:26 +0200 Subject: [PATCH] Convert awkard floats to hex --- src/preserves/private/texts.nim | 35 ++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/preserves/private/texts.nim b/src/preserves/private/texts.nim index 862d674..247d659 100644 --- a/src/preserves/private/texts.nim +++ b/src/preserves/private/texts.nim @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense -import std/[base64, json, options, sets, sequtils, streams, strutils, tables, typetraits] +import std/[base64, endians, json, math, options, sets, sequtils, streams, strutils, tables, typetraits] import ./values proc `$`*(s: Symbol): string = @@ -33,6 +33,8 @@ proc `$`*(s: Symbol): string = result.add(c) result.add('|') +const hexAlphabet = "0123456789abcdef" + type TextMode* = enum textPreserves, textJson proc writeText*[E](stream: Stream; pr: Preserve[E]; mode = textPreserves) = @@ -44,10 +46,30 @@ proc writeText*[E](stream: Stream; pr: Preserve[E]; mode = textPreserves) = of false: write(stream, "#f") of true: write(stream, "#t") of pkFloat: - write(stream, $pr.float) - write(stream, 'f') + 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: - write(stream, $pr.double) + 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) + write(stream, "#xd\"") + for b in buf: + write(stream, hexAlphabet[b shr 4]) + write(stream, hexAlphabet[b and 0xf]) + write(stream, '"') of pkRegister: write(stream, $pr.register) of pkBigInt: @@ -65,11 +87,10 @@ proc writeText*[E](stream: Stream; pr: Preserve[E]; mode = textPreserves) = write(stream, base64.encode(pr.bytes)) write(stream, ']') else: - const alphabet = "0123456789abcdef" write(stream, "#x\"") for b in pr.bytes: - write(stream, alphabet[int(b shr 4)]) - write(stream, alphabet[int(b and 0xf)]) + write(stream, hexAlphabet[b.int shr 4]) + write(stream, hexAlphabet[b.int and 0xf]) write(stream, '"') of pkSymbol: let sym = pr.symbol.string