utils/split-pieces (QfConvert): Split out a subclass.
authorMark Wooding <mdw@distorted.org.uk>
Mon, 21 May 2018 16:40:29 +0000 (17:40 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 11 Jun 2018 15:37:16 +0000 (16:37 +0100)
Subclasses must define a boolean `SIGNEDP', and implement `fmt(n)' to
format an individual piece for output.

The new subclass, `SignedQfConvert', is indeed signed, and formats using
`str'; so, again, nothing has actually changed.

utils/split-pieces

index 11ecd8a..a5b6294 100755 (executable)
@@ -47,15 +47,15 @@ class BaseQfConvert (object):
     print ";; piece widths = %r" % seq
     return cls(p, seq)
   def hack(me, n):
-    if 2*n >= me.p: n -= p
+    if me.SIGNEDP and 2*n >= me.p: n -= me.p
     nn = []
     wds = cycle(me.wdseq)
     while n:
       wd = wds.next()
       lim = 1 << wd; m = lim - 1
       d = n&m; n >>= wd
-      if d >= lim/2: d -= lim; n += 1
-      nn.append(str(d))
+      if me.SIGNEDP and d >= lim/2: d -= lim; n += 1
+      nn.append(me.fmt(d))
     return nn
   def unhack(me, nn):
     a = o = 0
@@ -65,13 +65,17 @@ class BaseQfConvert (object):
     if a < 0: a += me.p
     return a
 
+class SignedQfConvert (BaseQfConvert):
+  SIGNEDP = True
+  def fmt(me, n): return str(n)
+
 R_split = RX.compile(r',\s*|\s+')
 def spliteval(arg): return map(eval, R_split.split(arg.strip()))
 
 convmap = { 'scaf': ScafConvert,
             'unscaf': ScafConvert,
-            'qf': BaseQfConvert,
-            'unqf': BaseQfConvert }
+            'qf': SignedQfConvert,
+            'unqf': SignedQfConvert }
 op = getarg()
 cvt = convmap[op].parse()
 if op.startswith('un'): prepare, conv, format = spliteval, cvt.unhack, str