I didn’t see any Scheme code to read Minecraft NBT data files, so I made one. And in doing so, I see why there weren’t any NBT readers in Scheme. (Haskell programmers can use Adam Foltzer’s much cleaner Haskell version.)
When I found out that there was a gzip egg called z3, I thought my troubles were over. Not quite, because although z3 made it ridiculously easy to read compressed data, the only real procedure I had to read data from the gzip stream was
read-byte. And not only did I have to read only one byte at a time, but they were all promoted to ints anyways, since there is no notion of different-width integers in Chicken (only fixnums).
To read a 32-bit int, I read in 4 bytes and reassembled them into a fixnum. To read floats, well…
(define (readFloat) (let ([c-read-float (foreign-lambda* float ((int i1) (int i2) (int i3) (int i4)) "uint8_t b1 = (uint8_t) i1; uint8_t b2 = (uint8_t) i2; uint8_t b3 = (uint8_t) i3; uint8_t b4 = (uint8_t) i4; uint32_t i = 0; i = b1; i = (i << 8) | b2; i = (i << 8) | b3; i = (i << 8) | b4; float f = *(float*)&i; C_return(f);")]) (let* ([i1 (read-byte)] [i2 (read-byte)] [i3 (read-byte)] [i4 (read-byte)]) (c-read-float i1 i2 i3 i4))))
Not only that, but Chicken seems to compile internal defines incorrectly, and I haven’t been able to figure out if that’s documented anywhere.
Anyways, the code works (for certain values of “works”) now and is on Github: chicken-nbt. Time permitting, I may package it into an egg.