nac3-spec/toy-impl/test_expr.py
2020-12-21 15:08:55 +08:00

148 lines
4.3 KiB
Python

import ast
from type_def import *
from inference import *
from helper import *
from parse_expr import *
from top_level import *
types = {
'int32': PrimitiveType('int32'),
'int64': PrimitiveType('int64'),
'str': PrimitiveType('str'),
'bool': PrimitiveType('bool')
}
i32 = types['int32']
i64 = types['int64']
s = types['str']
b = types['bool']
variables = {
'X': TypeVariable('X', []),
'Y': TypeVariable('Y', []),
'I': TypeVariable('I', [i32, i64]),
'A': TypeVariable('A', [i32, i64, s]),
}
X = variables['X']
Y = variables['Y']
I = variables['I']
A = variables['A']
i32.methods['__init__'] = ([SelfType(), I], None, set())
i32.methods['__add__'] = ([SelfType(), i32], i32, set())
i32.methods['__sub__'] = ([SelfType(), i32], i32, set())
i32.methods['__lt__'] = ([SelfType(), i32], b, set())
i32.methods['__gt__'] = ([SelfType(), i32], b, set())
i32.methods['__eq__'] = ([SelfType(), i32], b, set())
i32.methods['__ne__'] = ([SelfType(), i32], b, set())
i32.methods['__le__'] = ([SelfType(), i32], b, set())
i32.methods['__ge__'] = ([SelfType(), i32], b, set())
i64.methods['__init__'] = ([SelfType(), I], None, set())
i64.methods['__add__'] = ([SelfType(), i64], i64, set())
i64.methods['__sub__'] = ([SelfType(), i64], i64, set())
i64.methods['__lt__'] = ([SelfType(), i64], b, set())
i64.methods['__gt__'] = ([SelfType(), i64], b, set())
i64.methods['__eq__'] = ([SelfType(), i64], b, set())
i64.methods['__ne__'] = ([SelfType(), i64], b, set())
i64.methods['__le__'] = ([SelfType(), i64], b, set())
i64.methods['__ge__'] = ([SelfType(), i64], b, set())
ctx = Context(variables, types)
def test_expr(expr, sym_table= {}):
print(f'Testing {expr} w.r.t. {stringify_subst(sym_table)}')
try:
tree = ast.parse(expr, mode='eval')
result = parse_expr(ctx, sym_table, tree)
print(result)
except CustomError as err:
print(f'error: {err.msg}')
test_expr('1 + 1')
test_expr('1 - 1')
test_expr('int64(1)')
test_expr('int64(1) - 1')
test_expr('a - a', {'a': I})
test_expr('a - a', {'a': A})
test_expr('[1, 2, 3][2]')
test_expr('[[1], [2], [3]][2]')
test_expr('[[1], [2], [3]][a]', {'a': i32})
test_expr('[][:]', {})
test_expr('[1,2,3][:]', {})
test_expr('[1,2,3][1:3]', {})
test_expr('[1,2,3][:a:2]', {'a': I})
test_expr('[1,2,3][:a:2]', {'a': i32})
test_expr('a == a == a', {'a': I})
test_expr('a == a and 1 == 2', {'a': I})
test_expr('1 if a == b else 0', {'a': I, 'b': I})
test_expr('a if a == b else 1', {'a': I, 'b': I})
test_expr('a if a == b else b', {'a': I, 'b': I})
test_expr('[x for x in [1, 2, 3]]', {})
test_expr('[1 for x in [1, 2, 3] if x > 2]', {})
test_expr('[a + a for x in [1, 2, 3] if x > 2]', {'a': I})
test_expr('[a for a, b in [(1, 2), (2, 3), (3, 4)] if b > 2]', {})
test_expr('[a for a, a in [(1, 2), (2, 3), (3, 4)] if b > 2]', {})
test_expr('[1 for _, _ in [(1, 2), (2, 3), (3, 4)]]', {})
test_expr('[b for a, b in [(1, (2, 3)), (2, (3, 4)), (3, (4, 5))] if b > 2]', {})
test_expr('[b for a, b in [(1, (2, 3)), (2, (3, 4)), (3, (4, 5))]]', {})
test_expr('[b for a, (b, c) in [(1, (2, 3)), (2, (3, 4)), (3, (4, 5))] if b > 2]', {})
test_classes = """
class Foo:
a: int32
def __init__(self, a: int32):
self.a = a
def __add__(self, other: Foo) -> Foo:
return Foo(self.a + other.a)
def __sub__(self, other: Foo) -> Foo:
return Foo(self.a - other.a)
def __lt__(self, other: Foo) -> bool:
pass
def __le__(self, other: Foo) -> bool:
pass
def __gt__(self, other: Foo) -> bool:
pass
def __ge__(self, other: Foo) -> bool:
pass
def foo(self) -> self:
pass
class Bar(Foo):
def foo(self) -> self:
pass
def find(ls: list[I], x: I) -> int32:
pass
def foobar(a: virtual[Foo]) -> virtual[Foo]:
pass
def bar(a: virtual[Bar]) -> virtual[Bar]:
pass
"""
ctx, _ = parse_top_level(ctx, ast.parse(test_classes))
test_expr('Foo(1) + Foo(1)', {})
test_expr('Foo(1) + Foo(1) < Foo(2) + Foo(3) < Foo(4)', {})
test_expr('find([1, 2, 3], 1)', {})
test_expr('find([], 1)', {})
test_expr('Foo(1).foo()', {})
test_expr('foobar(1)', {})
test_expr('foobar(Foo(1))', {})
test_expr('foobar(Bar())', {})
test_expr('foobar(foobar(Foo(1)))', {})
test_expr('bar(foobar(Foo(1)))', {})
test_expr('foobar(bar(Foo(1)))', {})
test_expr('foobar(bar(Bar()))', {})