From fea7cb867ec193f2af3a8f61fc8d14c97b85ba83 Mon Sep 17 00:00:00 2001
From: Leo Tenenbaum <pommicket@gmail.com>
Date: Wed, 8 Jan 2020 11:01:34 -0500
Subject: finished read_ functions

---
 binfile.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 types.h   |  2 +-
 2 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/binfile.c b/binfile.c
index 6aaf007..04c81e9 100644
--- a/binfile.c
+++ b/binfile.c
@@ -171,14 +171,14 @@ static void write_f32(FILE *fp, F32 f32) {
 }
 
 static F32 read_f32(FILE *fp) {
-#ifdef TOC_PORTABLE
+#if BINFILE_PORTABLE
 	/* TODO: infinity, NaN */
 	U32 u32 = read_u32(fp);
 	U32 sign =     (u32 & 0x80000000);
 	U32 exponent = (u32 & 0x7f800000) >> 23;
 	U32 fraction = (u32 & 0x007fffff);
-	F32 flt = (float)fraction;
-	I32 signed_exponent = (I32)exponent - 127;
+	F32 flt = (F32)1 + (F32)fraction / (F32)0x0800000;
+	int signed_exponent = (int)exponent - 127;
 	while (signed_exponent < 0) {
 		++signed_exponent;
 		flt /= (F32)2;
@@ -188,6 +188,7 @@ static F32 read_f32(FILE *fp) {
 		flt *= (F32)2;
 	}
 	if (sign) flt = -flt;
+	return flt;
 #else
 	F32 f32;
 	fread(&f32, sizeof f32, 1, fp);
@@ -227,10 +228,40 @@ static void write_f64(FILE *fp, F64 f64) {
 #endif
 }
 
+static F64 read_f64(FILE *fp) {
+#if BINFILE_PORTABLE
+	/* TODO: infinity, NaN */
+	U64 u64 = read_u64(fp);
+	U64 sign =     (u64 & 0x8000000000000000);
+	U64 exponent = (u64 & 0x7ff0000000000000) >> 52;
+	U64 fraction = (u64 & 0x000fffffffffffff);
+	F64 flt = (F64)fraction / (F64)0x10000000000000 + (F64)1;
+	int signed_exponent = (int)exponent - 1023;
+	while (signed_exponent < 0) {
+		++signed_exponent;
+		flt /= (F64)2;
+	}
+	while (signed_exponent > 0) {
+		--signed_exponent;
+		flt *= (F64)2;
+	}
+	if (sign) flt = -flt;
+	return flt;
+#else
+	F64 f64;
+	fread(&f64, sizeof f64, 1, fp);
+	return f64;
+#endif
+}
+
 static void write_bool(FILE *fp, bool b) {
 	write_u8(fp, b);
 }
 
+static bool read_bool(FILE *fp) {
+	return read_u8(fp);
+}
+
 /* 
    toc's vlq format:
    a byte whose first (most significant) bit is 0 indicates the number is done.
@@ -245,23 +276,48 @@ static void write_vlq(FILE *fp, U64 x) {
 	write_u8(fp, (U8)x);
 }
 
+static U64 read_vlq(FILE *fp) {
+    U8 byte = read_u8(fp);
+	if (byte & 0x80) {
+		return (read_vlq(fp) << 7) + (byte & 0x7F);
+	} else {
+		return byte;
+	}
+}
+
 #ifdef TOC_DEBUG
 static void binfile_test(void) {
 	binfile_printing_enabled = false;
 	FILE *fp = tmpfile();
-	/* U64 a = 12387217312; */
-	/* write_vlq(fp, a); */
+	U64 a = 234873485734;
+	write_vlq(fp, a);
 	I64 b = -123981232131;
 	write_i64(fp, b);
 	U8 c = 12;
 	write_u8(fp, c);
-	float d = -2.323198123f;
+	F32 d = (F32)-2.323198123;
 	write_f32(fp, d);
+	bool e = true;
+	write_bool(fp, e);
+	F64 f = (F64)-34.69459324823;
+	write_f64(fp, f);
 	fseek(fp, 0L, SEEK_SET);
-	/* assert(read_vlq(fp) == a); */
-	assert(read_i64(fp) == b);
-	assert(read_u8(fp) == c);
-	assert(read_f32(fp) == d);
+
+#define expect(type, fmt, expr, to_be) {								\
+		type exp = to_be;												\
+		type got = expr;												\
+		if (exp != got) {												\
+			fprintf(stderr, "Expected " #expr " to be " fmt " but got " fmt "\n", exp, got); \
+		    abort();													\
+		}																\
+	}
+
+	expect(U64, U64_FMT, read_vlq(fp), a);
+	expect(I64, I64_FMT, read_i64(fp), b);
+	expect(U8, U8_FMT, read_u8(fp), c);
+	expect(F32, F32_FMT, read_f32(fp), d);
+	expect(bool, "%d", read_bool(fp), e);
+    expect(F64, F64_FMT, read_f64(fp), f);
 	fclose(fp);
 	binfile_printing_enabled = true;
 }
diff --git a/types.h b/types.h
index d83e0c7..478df17 100644
--- a/types.h
+++ b/types.h
@@ -3,7 +3,7 @@
   This file is part of toc. toc is distributed under version 3 of the GNU General Public License, without any warranty whatsoever.
   You should have received a copy of the GNU General Public License along with toc. If not, see <https://www.gnu.org/licenses/>.
 */
-/* NOTE: make sure you edit copy.c and package.c and cgen_recurse_subexprs when you make a change to expression-related types or type-related types in this file! */
+/* NOTE: make sure you edit copy.c and package.c and cgen_recurse_subexprs/types when you make a change to expression-related types or type-related types in this file! */
 
 typedef long double Floating; /* OPTIM: Switch to double, but make sure floating-point literals are right */
 
-- 
cgit v1.2.3