nxu/test-math32.py

96 lines
3.4 KiB
Python
Raw Permalink Normal View History

2021-12-25 23:07:41 -05:00
#!/usr/bin/python
2021-12-26 21:01:22 -05:00
from math import floor, log
2021-12-25 23:07:41 -05:00
from os import environ
from random import randint
2021-12-27 15:09:49 -05:00
from subprocess import Popen, PIPE, run
2021-12-25 23:07:41 -05:00
2022-09-10 13:38:22 -04:00
u1 = {'sz': 1, 'fmt': b'%02x'}
2021-12-26 01:56:43 -05:00
u3 = {'sz': 1 << 3, 'fmt': b'%02x'}
2021-12-26 00:23:42 -05:00
u5 = {'sz': 1 << 5, 'fmt': b'%02x'}
u8 = {'sz': 1 << 8, 'fmt': b'%02x'}
u16 = {'sz': 1 << 16, 'fmt': b'%04x'}
u32 = {'sz': 1 << 32, 'fmt': b'%08x'}
2021-12-25 23:07:41 -05:00
2021-12-26 00:23:42 -05:00
def fmt(gx, x):
return gx['fmt'].decode('utf-8') % (x % gx['sz'])
2021-12-25 23:07:41 -05:00
2021-12-26 00:23:42 -05:00
def testcase(p, sym, args, out, f):
2021-12-26 01:56:43 -05:00
vals = [(name, g, randint(0, g['sz'] - 1)) for (name, g) in args]
2021-12-26 00:23:42 -05:00
p.stdin.write(sym)
2021-12-26 01:56:43 -05:00
for _, g, x in vals:
2021-12-26 00:23:42 -05:00
p.stdin.write(b' ')
p.stdin.write(g['fmt'] % x)
p.stdin.write(b'\n')
2021-12-25 23:07:41 -05:00
p.stdin.flush()
got = p.stdout.readline().strip().decode('utf-8')
2021-12-26 01:56:43 -05:00
xs = [x for _, _, x in vals]
2021-12-26 00:23:42 -05:00
z = f(*xs)
expected = fmt(out, z)
if got == expected:
return None
2022-09-10 13:38:22 -04:00
elif out == u1 and bool(got) == bool(expected):
return None
2021-12-26 00:23:42 -05:00
else:
res = {'got': got, 'expected': expected}
2021-12-26 01:56:43 -05:00
for name, _, x in vals:
res[name] = x
2021-12-26 00:23:42 -05:00
return res
2021-12-25 23:07:41 -05:00
2021-12-26 21:01:22 -05:00
def test(p, trials, sym, args, out, f):
2021-12-25 23:07:41 -05:00
fails = 0
cases = []
maximum = (1 << 32) - 1
2021-12-26 21:01:22 -05:00
for i in range(0, trials):
2021-12-26 00:23:42 -05:00
case = testcase(p, sym, args, out, f)
if case is not None:
2021-12-25 23:07:41 -05:00
fails += 1
2021-12-26 00:23:42 -05:00
cases.append(case)
2021-12-25 23:07:41 -05:00
name = sym.decode('utf-8')
if fails == 0:
2021-12-26 21:01:22 -05:00
print('%s passed %d trials' % (name, trials))
2021-12-25 23:07:41 -05:00
else:
2021-12-26 21:01:22 -05:00
print('%s failed %d/%d trials (%r)' % (name, fails, trials, cases))
2021-12-26 00:23:42 -05:00
def pipe():
2021-12-27 15:09:49 -05:00
return Popen(['uxncli', 'run.rom'], stdin=PIPE, stdout=PIPE)
2021-12-26 00:23:42 -05:00
def bitcount(x):
2021-12-26 21:01:22 -05:00
return floor(log(x, 2)) + 1
2021-12-29 17:34:07 -05:00
def gcd(a, b):
return a if b == 0 else gcd(b, a % b)
2022-11-06 21:49:02 -05:00
2021-12-25 23:07:41 -05:00
def main():
2021-12-27 15:51:59 -05:00
trials = 100
2021-12-27 15:09:49 -05:00
run(['uxnasm', 'test-math32.tal', 'run.rom'])
2021-12-26 00:23:42 -05:00
p = pipe()
2021-12-26 21:01:22 -05:00
test(p, trials, b'+', [('x', u32), ('y', u32)], u32, lambda x, y: x + y)
test(p, trials, b'-', [('x', u32), ('y', u32)], u32, lambda x, y: x - y)
test(p, trials, b'*', [('x', u32), ('y', u32)], u32, lambda x, y: x * y)
2021-12-27 01:20:24 -05:00
test(p, trials, b'/', [('x', u32), ('y', u32)], u32, lambda x, y: x // y)
2021-12-29 16:17:01 -05:00
test(p, trials, b'%', [('x', u32), ('y', u32)], u32, lambda x, y: x % y)
2021-12-29 17:34:07 -05:00
test(p, trials, b'G', [('x', u32), ('y', u32)], u32, gcd)
2021-12-26 21:01:22 -05:00
test(p, trials, b'L', [('x', u32), ('y', u5)], u32, lambda x, y: x << y)
test(p, trials, b'R', [('x', u32), ('y', u5)], u32, lambda x, y: x >> y)
test(p, trials, b'B', [('x', u32)], u8, bitcount)
test(p, trials, b'&', [('x', u32), ('y', u32)], u32, lambda x, y: x & y)
test(p, trials, b'|', [('x', u32), ('y', u32)], u32, lambda x, y: x | y)
test(p, trials, b'^', [('x', u32), ('y', u32)], u32, lambda x, y: x ^ y)
test(p, trials, b'~', [('x', u32)], u32, lambda x: ~x)
test(p, trials, b'N', [('x', u32)], u32, lambda x: -x)
2022-09-10 13:38:22 -04:00
test(p, trials, b'=', [('x', u32), ('y', u32)], u1, lambda x, y: int(x == y))
test(p, trials, b'!', [('x', u32), ('y', u32)], u1, lambda x, y: int(x != y))
test(p, trials, b'0', [('x', u32)], u1, lambda x: int(x == 0))
test(p, trials, b'Z', [('x', u32)], u1, lambda x: int(x != 0))
test(p, trials, b'<', [('x', u32), ('y', u32)], u1, lambda x, y: int(x < y))
test(p, trials, b'>', [('x', u32), ('y', u32)], u1, lambda x, y: int(x > y))
test(p, trials, b'{', [('x', u32), ('y', u32)], u1, lambda x, y: int(x <= y))
test(p, trials, b'}', [('x', u32), ('y', u32)], u1, lambda x, y: int(x >= y))
2021-12-25 23:07:41 -05:00
p.stdin.close()
p.stdout.close()
2022-02-11 00:02:45 -05:00
p.kill()
2021-12-25 23:07:41 -05:00
if __name__ == "__main__":
main()