2021-12-25 23:07:41 -05:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
from os import environ
|
|
|
|
from subprocess import Popen, PIPE
|
|
|
|
from random import randint
|
|
|
|
|
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
|
|
|
|
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 00:23:42 -05:00
|
|
|
def test(p, runs, sym, args, out, f):
|
2021-12-25 23:07:41 -05:00
|
|
|
fails = 0
|
|
|
|
cases = []
|
|
|
|
maximum = (1 << 32) - 1
|
|
|
|
for i in range(0, runs):
|
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:
|
|
|
|
print('%s passed %d runs' % (name, runs))
|
|
|
|
else:
|
|
|
|
print('%s failed %d/%d runs (%r)' % (name, fails, runs, cases))
|
2021-12-26 00:23:42 -05:00
|
|
|
|
|
|
|
def pipe():
|
|
|
|
cli = environ['HOME'] + '/w/uxn/bin/uxncli'
|
|
|
|
return Popen([cli, 'run.rom'], stdin=PIPE, stdout=PIPE)
|
|
|
|
|
|
|
|
def bitcount(x):
|
|
|
|
n = 0
|
|
|
|
while x > 0:
|
|
|
|
n += 1
|
|
|
|
x = x >> 1
|
|
|
|
return n
|
2021-12-25 23:07:41 -05:00
|
|
|
|
|
|
|
def main():
|
2021-12-26 01:56:43 -05:00
|
|
|
runs = 1000
|
2021-12-26 00:23:42 -05:00
|
|
|
p = pipe()
|
|
|
|
test(p, runs, b'+', [('x', u32), ('y', u32)], u32, lambda x, y: x + y)
|
|
|
|
test(p, runs, b'-', [('x', u32), ('y', u32)], u32, lambda x, y: x - y)
|
|
|
|
test(p, runs, b'*', [('x', u32), ('y', u32)], u32, lambda x, y: x * y)
|
|
|
|
test(p, runs, b'L', [('x', u32), ('y', u5)], u32, lambda x, y: x << y)
|
2021-12-26 01:56:43 -05:00
|
|
|
test(p, runs, b'R', [('x', u32), ('y', u5)], u32, lambda x, y: x >> y)
|
2021-12-26 00:23:42 -05:00
|
|
|
test(p, runs, b'B', [('x', u32)], u8, bitcount)
|
|
|
|
test(p, runs, b'&', [('x', u32), ('y', u32)], u32, lambda x, y: x & y)
|
|
|
|
test(p, runs, b'|', [('x', u32), ('y', u32)], u32, lambda x, y: x | y)
|
|
|
|
test(p, runs, b'^', [('x', u32), ('y', u32)], u32, lambda x, y: x ^ y)
|
|
|
|
test(p, runs, b'~', [('x', u32)], u32, lambda x: ~x)
|
|
|
|
test(p, runs, b'N', [('x', u32)], u32, lambda x: -x)
|
2021-12-26 00:47:13 -05:00
|
|
|
test(p, runs, b'=', [('x', u32), ('y', u32)], u8, lambda x, y: int(x == y))
|
|
|
|
test(p, runs, b'!', [('x', u32), ('y', u32)], u8, lambda x, y: int(x != y))
|
2021-12-25 23:07:41 -05:00
|
|
|
p.stdin.close()
|
|
|
|
p.stdout.close()
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|