phasm/tests/integration/test_lang/test_natnum.py
Johan B.W. de Vries a2e1dfd799 Reworks type class instantiation
Before, a type class was a property of a type.
But that doesn't make any sense for multi parameter
type classes.

Had to make a hacky way for type classes with
type constructors.
2025-04-27 17:45:13 +02:00

230 lines
5.2 KiB
Python

import pytest
from phasm.type3.entry import Type3Exception
from ..helpers import Suite
INT_TYPES = ['u32', 'u64', 'i32', 'i64']
FLOAT_TYPES = ['f32', 'f64']
TYPE_MAP = {
'u32': int,
'u64': int,
'i32': int,
'i64': int,
'f32': float,
'f64': float,
}
@pytest.mark.integration_test
def test_addition_not_implemented():
code_py = """
class Foo:
val: i32
@exported
def testEntry(x: Foo, y: Foo) -> Foo:
return x + y
"""
with pytest.raises(Type3Exception, match='Missing type class instantation: NatNum Foo'):
Suite(code_py).run_code()
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', INT_TYPES)
def test_addition_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 10 + 3
"""
result = Suite(code_py).run_code()
assert 13 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', FLOAT_TYPES)
def test_addition_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 32.0 + 0.125
"""
result = Suite(code_py).run_code()
assert 32.125 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', INT_TYPES)
def test_subtraction_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 10 - 3
"""
result = Suite(code_py).run_code()
assert 7 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', FLOAT_TYPES)
def test_subtraction_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 100.0 - 67.875
"""
result = Suite(code_py).run_code()
assert 32.125 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
def test_subtraction_negative_result():
code_py = """
@exported
def testEntry() -> i32:
return 10 - 11
"""
result = Suite(code_py).run_code()
assert -1 == result.returned_value
@pytest.mark.integration_test
def test_subtraction_underflow():
code_py = """
@exported
def testEntry() -> u32:
return 10 - 11
"""
result = Suite(code_py).run_code()
assert 4294967295 == result.returned_value
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', INT_TYPES)
def test_multiplication_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 10 * 3
"""
result = Suite(code_py).run_code()
assert 30 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', FLOAT_TYPES)
def test_multiplication_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 32.0 * 0.125
"""
result = Suite(code_py).run_code()
assert 4.0 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', INT_TYPES)
def test_arithmic_shift_right_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 100 >> 3
"""
result = Suite(code_py).run_code()
assert 12 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', FLOAT_TYPES)
def test_arithmic_shift_right_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 100.0 >> 3
"""
result = Suite(code_py).run_code()
assert 12.5 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', INT_TYPES)
def test_arithmic_shift_left_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 3 << 3
"""
result = Suite(code_py).run_code()
assert 24 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', FLOAT_TYPES)
def test_arithmic_shift_left_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return 3.5 << 3
"""
result = Suite(code_py).run_code()
assert 28.0 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', INT_TYPES)
def test_call_with_expression_int(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return helper(10 + 20, 3 + 5)
def helper(left: {type_}, right: {type_}) -> {type_}:
return left - right
"""
result = Suite(code_py).run_code()
assert 22 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)
@pytest.mark.integration_test
@pytest.mark.parametrize('type_', FLOAT_TYPES)
def test_call_with_expression_float(type_):
code_py = f"""
@exported
def testEntry() -> {type_}:
return helper(10.078125 + 90.046875, 63.0 + 5.0)
def helper(left: {type_}, right: {type_}) -> {type_}:
return left - right
"""
result = Suite(code_py).run_code()
assert 32.125 == result.returned_value
assert TYPE_MAP[type_] is type(result.returned_value)