scripts: Added CsvFfrac type

A simple float variant of the CsvFrac type:

- frac(1.5,2)  => 1/2 (50.0%)
- ffrac(1.5,2) => 1.5/2.0 (75.0%)

Useful for `make bench-widths` (previously make bench-bus), where we
want to find the average buffer utilization:

  probe            readed              progged                 erased
  b_rbyd+create   1.0/1.0 (100.0%)  13.8/256.0 (5.4%)        ∞/4096.0 (∞%)
  b_rbyd+delete     ∞/1.0 (∞%)         ∞/256.0 (∞%)          ∞/4096.0 (∞%)
  b_rbyd+fetch    1.0/1.0 (100.0%)     ∞/256.0 (∞%)          ∞/4096.0 (∞%)
  b_rbyd+lookup   1.0/1.0 (100.0%)     ∞/256.0 (∞%)          ∞/4096.0 (∞%)
  b_rbyd+usage      ∞/1.0 (∞%)         ∞/256.0 (∞%)          ∞/4096.0 (∞%)
  b_wt_seq+w      1.0/1.0 (100.0%)  31.7/256.0 (12.4%)  4096.0/4096.0 (100.0%)
  b_wt_random+w   1.0/1.0 (100.0%)  15.3/256.0 (6.0%)   4096.0/4096.0 (100.0%)
  b_wt_logging+w  1.0/1.0 (100.0%)  15.4/256.0 (6.0%)   4096.0/4096.0 (100.0%)
  b_wt_many+w     1.0/1.0 (100.0%)  16.1/256.0 (6.3%)   4096.0/4096.0 (100.0%)
  TOTAL             ∞/1.0 (∞%)         ∞/256.0 (∞%)          ∞/4096.0 (∞%)

Now that we have 4 types, the cast matrix gets a bit complicated, but
this is side-stepped a bit by a custom __frac__ hook.

---

Some other tweaks to csv.py:

- Added CsvFold.type to typecheck folds _after_ we know the expr's final
  type.

- Adopted CsvFfrac as an output for most of the math functions/folds

- Stopped early termination of typechecking if we change type!

  This was broken: int(float(1.5) + int(1))
This commit is contained in:
Christopher Haster
2026-02-05 14:08:51 -06:00
parent 73e06612bf
commit b751981574
10 changed files with 365 additions and 76 deletions
+8 -3
View File
@@ -42,7 +42,7 @@ class CsvInt(co.namedtuple('CsvInt', 'a')):
def __new__(cls, a=0):
if isinstance(a, CsvInt):
return a
if isinstance(a, str):
elif isinstance(a, str):
try:
a = int(a, 0)
except ValueError:
@@ -150,9 +150,11 @@ class CsvFrac(co.namedtuple('CsvFrac', 'a,b')):
def __new__(cls, a=0, b=None):
if isinstance(a, CsvFrac) and b is None:
return a
if isinstance(a, str) and b is None:
elif hasattr(a, '__frac__') and b is None:
a, b = a.__frac__()
elif isinstance(a, str) and b is None:
a, b = a.split('/', 1)
if b is None:
elif b is None:
b = a
return super().__new__(cls, CsvInt(a), CsvInt(b))
@@ -174,6 +176,9 @@ class CsvFrac(co.namedtuple('CsvFrac', 'a,b')):
def __float__(self):
return float(self.a)
def __frac__(self):
return self.a, self.b
none = '%11s' % '-'
def table(self):
return '%11s' % (self,)