#!/usr/bin/python from os import environ from subprocess import Popen, PIPE from random import randint 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'} def fmt(gx, x): return gx['fmt'].decode('utf-8') % (x % gx['sz']) def testcase(p, sym, args, out, f): xs = [randint(0, a[1]['sz'] - 1) for a in args] p.stdin.write(sym) for i in range(0, len(args)): x = xs[i] g = args[i][1] p.stdin.write(b' ') p.stdin.write(g['fmt'] % x) p.stdin.write(b'\n') p.stdin.flush() got = p.stdout.readline().strip().decode('utf-8') z = f(*xs) expected = fmt(out, z) if got == expected: return None else: res = {'got': got, 'expected': expected} for (name, x) in args: res[name] = x return res def test(p, runs, sym, args, out, f): fails = 0 cases = [] maximum = (1 << 32) - 1 for i in range(0, runs): case = testcase(p, sym, args, out, f) if case is not None: fails += 1 cases.append(case) 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)) 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 def main(): runs = 100 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) 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) 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)) p.stdin.close() p.stdout.close() if __name__ == "__main__": main()