"An arithmetic shift is usually equivalent to multiplying the number by a positive or a negative integral power of the radix." -- Federal Standard 1037C "This is the same as multiplying x by 2**y." "A right shift by n bits is defined as floor division by pow(2,n). A left shift by n bits is defined as multiplication with pow(2,n)."
230 lines
5.2 KiB
Python
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='Foo does not implement the NatNum type class'):
|
|
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)
|