2023-11-10 15:35:16 +01:00

309 lines
6.6 KiB
Python

import pytest
from phasm.type3.entry import Type3Exception
from ..constants import ALL_FLOAT_TYPES, COMPLETE_INT_TYPES, TYPE_MAP
from ..helpers import Suite
@pytest.mark.integration_test
def test_module_constant_def():
code_py = """
CONSTANT: (u8, u32, u64, ) = (250, 250000, 250000000, )
@exported
def testEntry() -> i32:
return 0
"""
result = Suite(code_py).run_code()
assert 0 == result.returned_value
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', ['u8', 'u32', 'u64', ])
def test_module_constant_1(type_):
code_py = f"""
CONSTANT: ({type_}, ) = (65, )
@exported
def testEntry() -> {type_}:
return CONSTANT[0]
"""
result = Suite(code_py).run_code()
assert 65 == result.returned_value
@pytest.mark.integration_test
def test_module_constant_6():
code_py = """
CONSTANT: (u8, u8, u32, u32, u64, u64, ) = (11, 22, 3333, 4444, 555555, 666666, )
@exported
def testEntry() -> u32:
return CONSTANT[2]
"""
result = Suite(code_py).run_code()
assert 3333 == result.returned_value
@pytest.mark.integration_test
def test_function_call_element_ok():
code_py = """
CONSTANT: (u8, u32, u64, ) = (250, 250000, 250000000, )
@exported
def testEntry() -> u64:
return helper(CONSTANT[2])
def helper(x: u64) -> u64:
return x
"""
result = Suite(code_py).run_code()
assert 250000000 == result.returned_value
@pytest.mark.integration_test
def test_tuple():
code_py = """
def l1(c: (u64, )) -> u64:
return c[0]
@exported
def testEntry() -> u64:
return l1((32, ))
"""
result = Suite(code_py).run_code()
assert 32 == result.returned_value
@pytest.mark.integration_test
def test_tuple_of_tuple():
code_py = """
def l1(c: (u64, )) -> u64:
return c[0]
def l2(c: ((u64, ), u64, )) -> u64:
return l1(c[0])
@exported
def testEntry() -> u64:
return l2(((64, ), 32, ))
"""
result = Suite(code_py).run_code()
assert 64 == result.returned_value
@pytest.mark.integration_test
def test_tuple_of_tuple_of_tuple():
code_py = """
def l1(c: (u64, )) -> u64:
return c[0]
def l2(c: ((u64, ), u64, )) -> u64:
return l1(c[0])
def l3(c: (((u64, ), u64, ), u64, )) -> u64:
return l2(c[0])
@exported
def testEntry() -> u64:
return l3((((128, ), 64, ), 32, ))
"""
result = Suite(code_py).run_code()
assert 128 == result.returned_value
@pytest.mark.integration_test
def test_constant_tuple_of_tuple_of_tuple():
code_py = """
CONSTANT: (((u64, ), u64, ), u64, ) = (((128, ), 64, ), 32, )
def l1(c: (u64, )) -> u64:
return c[0]
def l2(c: ((u64, ), u64, )) -> u64:
return l1(c[0])
def l3(c: (((u64, ), u64, ), u64, )) -> u64:
return l2(c[0])
@exported
def testEntry() -> u64:
return l3(CONSTANT)
"""
result = Suite(code_py).run_code()
assert 128 == result.returned_value
@pytest.mark.integration_test
def test_bytes_as_part_of_tuple():
code_py = """
CONSTANT: (bytes, u64, ) = (b'ABCDEF', 19, )
def l0(c: bytes) -> u8:
return c[0]
def l1(c: (bytes, u64, )) -> u8:
return l0(c[0])
@exported
def testEntry() -> u8:
return l1(CONSTANT)
"""
result = Suite(code_py).run_code()
assert 0x41 == result.returned_value
@pytest.mark.integration_test
def test_struct_as_part_of_tuple():
code_py = """
class ValueStruct:
value: i32
CONSTANT: (ValueStruct, u64, ) = (ValueStruct(234), 19, )
def l0(c: ValueStruct) -> i32:
return c.value
def l1(c: (ValueStruct, u64, )) -> i32:
return l0(c[0])
@exported
def testEntry() -> i32:
return l1(CONSTANT)
"""
result = Suite(code_py).run_code()
assert 234 == result.returned_value
@pytest.mark.integration_test
def test_function_call_element_type_mismatch():
code_py = """
CONSTANT: (u8, u32, u64, ) = (250, 250000, 250000000, )
@exported
def testEntry() -> u8:
return helper(CONSTANT[2])
def helper(x: u8) -> u8:
return x
"""
with pytest.raises(Type3Exception, match=r'u8 must be u64 instead'):
Suite(code_py).run_code()
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', COMPLETE_INT_TYPES)
def test_tuple_simple_constructor_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return helper((24, 57, 80, ))
def helper(vector: ({type_}, {type_}, {type_}, )) -> {type_}:
return vector[0] + vector[1] + vector[2]
"""
result = Suite(code_py).run_code()
assert 161 == result.returned_value
assert TYPE_MAP[type_] == type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', ALL_FLOAT_TYPES)
def test_tuple_simple_constructor_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return helper((1.0, 2.0, 3.0, ))
def helper(v: ({type_}, {type_}, {type_}, )) -> {type_}:
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2])
"""
result = Suite(code_py).run_code()
assert 3.74 < result.returned_value < 3.75
@pytest.mark.integration_test
@pytest.mark.skip('SIMD support is but a dream')
def test_tuple_i32x4():
code_py = """
@exported
def testEntry() -> i32x4:
return (51, 153, 204, 0, )
"""
result = Suite(code_py).run_code()
assert (1, 2, 3, 0) == result.returned_value
@pytest.mark.integration_test
def test_assign_to_tuple_with_tuple():
code_py = """
CONSTANT: (u32, ) = 0
"""
with pytest.raises(Type3Exception, match='Must be tuple'):
Suite(code_py).run_code()
@pytest.mark.integration_test
def test_tuple_constant_too_few_values():
code_py = """
CONSTANT: (u32, u8, u8, ) = (24, 57, )
"""
with pytest.raises(Type3Exception, match='Tuple element count mismatch'):
Suite(code_py).run_code()
@pytest.mark.integration_test
def test_tuple_constant_too_many_values():
code_py = """
CONSTANT: (u32, u8, u8, ) = (24, 57, 1, 1, )
"""
with pytest.raises(Type3Exception, match='Tuple element count mismatch'):
Suite(code_py).run_code()
@pytest.mark.integration_test
def test_tuple_constant_type_mismatch():
code_py = """
CONSTANT: (u32, u8, u8, ) = (24, 4000, 1, )
"""
with pytest.raises(Type3Exception, match=r'Must fit in 1 byte\(s\)'):
Suite(code_py).run_code()
@pytest.mark.integration_test
def test_tuple_must_use_literal_for_indexing():
code_py = """
CONSTANT: u32 = 0
@exported
def testEntry(x: (u8, u32, u64)) -> u64:
return x[CONSTANT]
"""
with pytest.raises(Type3Exception, match='Must index with literal'):
Suite(code_py).run_code()
@pytest.mark.integration_test
def test_tuple_must_use_integer_for_indexing():
code_py = """
@exported
def testEntry(x: (u8, u32, u64)) -> u64:
return x[0.0]
"""
with pytest.raises(Type3Exception, match='Must index with integer literal'):
Suite(code_py).run_code()