Dolda2000 GitWeb
/
coe.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
bin: Added coding and decoding of floats.
[coe.git]
/
coe
/
bin.py
diff --git
a/coe/bin.py
b/coe/bin.py
index
395a209
..
08e521e
100644
(file)
--- a/
coe/bin.py
+++ b/
coe/bin.py
@@
-1,3
+1,4
@@
+import io, math
from . import data
T_END = 0
from . import data
T_END = 0
@@
-70,6
+71,30
@@
class encoder(object):
dst.write(text.encode("utf-8"))
dst.write(b'\0')
dst.write(text.encode("utf-8"))
dst.write(b'\0')
+ @staticmethod
+ def writefloat(dst, x):
+ if x == 0.0:
+ mnt, exp = (0, 0)
+ elif math.isinf(x):
+ if x > 0:
+ mnt, exp = (0, 2)
+ else:
+ mnt, exp = (0, 3)
+ elif math.isnan(x):
+ mnt, exp = (0, 4)
+ else:
+ mnt, exp = math.frexp(x)
+ mnt *= 2
+ exp -= 1
+ while mnt != int(mnt):
+ mnt *= 2
+ mnt = int(mnt)
+ buf = bytearray()
+ buf.extend(encoder.encint(mnt))
+ buf.extend(encoder.encint(exp))
+ dst.write(encoder.encint(len(buf)))
+ dst.write(buf)
+
def dumpseq(self, dst, seq):
for v in seq:
self.dump(dst, v)
def dumpseq(self, dst, seq):
for v in seq:
self.dump(dst, v)
@@
-89,9
+114,9
@@
class encoder(object):
return
if datum == None:
self.writetag(dst, T_NIL, 0, None)
return
if datum == None:
self.writetag(dst, T_NIL, 0, None)
- elif datum
==
False:
+ elif datum
is
False:
self.writetag(dst, T_NIL, NIL_FALSE, None)
self.writetag(dst, T_NIL, NIL_FALSE, None)
- elif datum
==
True:
+ elif datum
is
True:
self.writetag(dst, T_NIL, NIL_TRUE, None)
elif isinstance(datum, int):
self.writetag(dst, T_INT, 0, None)
self.writetag(dst, T_NIL, NIL_TRUE, None)
elif isinstance(datum, int):
self.writetag(dst, T_INT, 0, None)
@@
-103,6
+128,9
@@
class encoder(object):
self.writetag(dst, T_BIT, 0, datum)
dst.write(self.encint(len(datum)))
dst.write(datum)
self.writetag(dst, T_BIT, 0, datum)
dst.write(self.encint(len(datum)))
dst.write(datum)
+ elif isinstance(datum, float):
+ self.writetag(dst, T_BIT, BIT_BFLOAT, datum)
+ self.writefloat(dst, datum)
elif isinstance(datum, data.symbol):
if datum.ns == "":
self.writetag(dst, T_STR, STR_SYM, datum)
elif isinstance(datum, data.symbol):
if datum.ns == "":
self.writetag(dst, T_STR, STR_SYM, datum)
@@
-152,12
+180,6
@@
class referror(fmterror):
def __init__(self):
super().__init__("bad backref")
def __init__(self):
super().__init__("bad backref")
-class namedtype(type):
- def __new__(cls, *args, typename=None, **kwargs):
- self = super().__new__(cls, *args, **kwargs)
- self.typename = typename
- return self
-
class decoder(object):
def __init__(self):
self.reftab = []
class decoder(object):
def __init__(self):
self.reftab = []
@@
-229,7
+251,7
@@
class decoder(object):
buf[key] = self.loadtagged(fp, tag)
def makeobjtype(self, nm):
buf[key] = self.loadtagged(fp, tag)
def makeobjtype(self, nm):
- return
namedtyp
e(str(nm), (data.obj, object), {}, typename=nm)
+ return
data.namedtype.mak
e(str(nm), (data.obj, object), {}, typename=nm)
def loadobj(self, fp, ref=False):
if ref:
def loadobj(self, fp, ref=False):
if ref:
@@
-265,16
+287,34
@@
class decoder(object):
return self.reftab[idx]
return self.addref(self.loadint(fp))
elif pri == T_STR:
return self.reftab[idx]
return self.addref(self.loadint(fp))
elif pri == T_STR:
- ret = self.
addref(self.loadstr(fp)
)
+ ret = self.
loadstr(fp
)
if sec == STR_SYM:
if sec == STR_SYM:
- return
data.symbol.get("", ret
)
- return
ret
+ return
self.addref(data.symbol.get("", ret)
)
+ return
self.addref(ret)
elif pri == T_BIT:
ln = self.loadint(fp)
elif pri == T_BIT:
ln = self.loadint(fp)
- ret =
self.addref(fp.read(ln)
)
+ ret =
fp.read(ln
)
if len(ret) < ln:
raise eoferror()
if len(ret) < ln:
raise eoferror()
- return ret
+ if sec == BIT_BFLOAT:
+ buf = io.BytesIO(ret)
+ mnt = self.loadint(buf)
+ exp = self.loadint(buf)
+ if mnt == 0:
+ if exp == 0:
+ return 0.0
+ elif exp == 1:
+ return -0.0
+ elif exp == 2:
+ return float("inf")
+ elif exp == 3:
+ return -float("inf")
+ else:
+ return float("nan")
+ else:
+ ret = math.ldexp(mnt, exp - (mnt.bit_length() - 1))
+ return self.addref(ret)
+ return self.addref(ret)
elif pri == T_NIL:
if sec == NIL_TRUE:
return self.addref(True)
elif pri == T_NIL:
if sec == NIL_TRUE:
return self.addref(True)
@@
-298,4
+338,4
@@
class decoder(object):
return self.loadtagged(fp, tag)
def load(fp):
return self.loadtagged(fp, tag)
def load(fp):
- decoder().load(fp)
+
return
decoder().load(fp)