Commit 2eda7087 authored by Damien's avatar Damien
Browse files

Add tests to test compiler and emitted byte code.

parent de690d12
This directory contains the framework and test files for testing the byte code
output of the Micro Python compiler.
You need to first build the 'cpy' executable in the directory micropython/unix-cpy/.
This executable is a minimal version of Micro Python which compiles a single source
file and outputs the corresponding byte code.
The output of Micro Python is checked against CPython 3.3.
To run the tests use:
./run-tests
import sys
name = sys.argv[1].split('/')[-1].split('.')[0]
with open(sys.argv[1]) as f:
lines_correct = [l.strip('\n') for l in f.readlines()]
lines_me = [l.strip('\n') for l in sys.stdin.readlines()]
if len(lines_me) != len(lines_correct):
if len(lines_me) == 0:
print('{:<20}: no output'.format(name))
elif lines_me[0].find('syntax error') >= 0:
print('{:<20}: syntax error'.format(name))
elif lines_me[0].find(' cannot be compiled') >= 0:
print('{:<20}: compile error: {}'.format(name, lines_me[0]))
else:
print('{:<20}: mismatch in number of lines'.format(name))
else:
total = len(lines_me)
same = 0
bad_num_fields = 0
bad_2 = 0
bad_3 = 0
jump_op = ['JUMP_FORWARD', 'JUMP_ABSOLUTE', 'POP_JUMP_IF_FALSE', 'POP_JUMP_IF_TRUE', 'SETUP_LOOP']
jump_abs_op = ['JUMP_FORWARD', 'JUMP_ABSOLUTE']
for i in range(total):
if lines_me[i] == lines_correct[i]:
same += 1
else:
# line is different
line_me = lines_me[i].strip().split(' ', 2)
line_correct = lines_correct[i].strip().split(' ', 2)
allow = False
if len(line_me) != len(line_correct):
bad_num_fields += 1
elif len(line_me) == 2:
if line_me[0] == line_correct[0] == 'stacksize':
allow = True
else:
bad_2 += 1
else:
assert(len(line_me) == 3)
if line_me[0] == line_correct[0] and line_me[1] in jump_abs_op and line_correct[1] in jump_abs_op:
allow = True
elif line_me[0] == line_correct[0] and line_me[1] == line_correct[1] in jump_op:
allow = True
else:
bad_3 += 1
#if not allow:
# print(line_me, 'vs', line_correct)
bad_str = ''
if bad_num_fields > 0:
bad_str += ', {} bad num fields'.format(bad_num_fields)
if bad_2 > 0:
bad_str += ', {} bad 2-field'.format(bad_2)
if bad_3 > 0:
bad_str += ', {} bad 3-field'.format(bad_3)
print('{:<20}: {:>6} lines, {:>5.1f}% correct{}'.format(name, total, 100 * same / total, bad_str))
assert x
assert x, 'test'
[] = ()
[] = []
a = b
(a) = b
a, b = c, d
a, b, c = d, e, f
a, b, c, d = e, f, g, h
#(a, b) = c, d
#a, b = (c, d)
#(a, b) = (c, d)
*a, = b
a, *b = c
a, *b, = c
a, *b, c = d
[*a] = b
[*a,] = b
[a, *b] = c
#[a, *b,] = c
#[a, *b, c] = d
[] = ()
x += 1
x.y += 1
x.f().y += 1
x[1] += 2
class A:
x = 1
y = x + z
A()
class A:
def f(x):
return x
def g(y):
def h(z):
return x + y + z
h(y)
A()
A.f(1)
A.g(2)(3)
class A:
def __init__(self, x):
self.x = x
self.y = 0
def get(self):
return self.x + self.y
A(1)
A(2).get()
class A(B):
pass
class A(object):
pass
class A(x.y()):
pass
class A(B, C):
pass
# basic closure
# to write!
# test closing over an argument
def f(x):
y = 2 * x
def g(z):
return x + y + z
return g
# test when different variables are closed over by different functions
def f():
l1 = 1
l2 = 2
l3 = 3
def g():
return l1 + l2
def h():
return l2 + l3
# test when a function has cell and free vars
def f():
f_local = 1
f_cell = 2
def g():
g_local = 3
g_cell = f_cell + 4
def h():
h1_local = 4
h2_local = f_cell + g_cell
if 1 <= x <= 5:
f()
if 1 <= x <= y <= 7:
f()
if a < b > c in l != c is not d:
f()
x = 1
#x = 1.2
#x = 1.2e5
#x = 1.2e+5
#x = 1.2e-5
x = ()
x = (1,)
x = (1,2)
x = ('a',None,3)
for a in b:
continue
for a in b:
try:
f()
except:
continue
g()
for a in b:
try:
f()
continue
except:
g()
for a in b:
try:
f()
except:
try:
g()
except:
continue
for a in b:
try:
f()
except:
try:
g()
continue
except:
h()
for a in b:
try:
f()
except:
pass
else:
continue
g()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment