Made Integral use Python's operators
Rather than Haskell's div and rem methods, we use the Python operators since these are often used. And we have as goal to make it 'look like Python'
This commit is contained in:
parent
94c8f9388c
commit
da381e4a48
@ -133,12 +133,18 @@ INSTANCES = {
|
|||||||
'a=f32': stdlib_types.f32_fractional_div,
|
'a=f32': stdlib_types.f32_fractional_div,
|
||||||
'a=f64': stdlib_types.f64_fractional_div,
|
'a=f64': stdlib_types.f64_fractional_div,
|
||||||
},
|
},
|
||||||
type3classes.Integral.methods['div']: {
|
type3classes.Integral.operators['//']: {
|
||||||
'a=u32': stdlib_types.u32_integral_div,
|
'a=u32': stdlib_types.u32_integral_div,
|
||||||
'a=u64': stdlib_types.u64_integral_div,
|
'a=u64': stdlib_types.u64_integral_div,
|
||||||
'a=i32': stdlib_types.i32_integral_div,
|
'a=i32': stdlib_types.i32_integral_div,
|
||||||
'a=i64': stdlib_types.i64_integral_div,
|
'a=i64': stdlib_types.i64_integral_div,
|
||||||
},
|
},
|
||||||
|
type3classes.Integral.operators['%']: {
|
||||||
|
'a=u32': stdlib_types.u32_integral_rem,
|
||||||
|
'a=u64': stdlib_types.u64_integral_rem,
|
||||||
|
'a=i32': stdlib_types.i32_integral_rem,
|
||||||
|
'a=i64': stdlib_types.i64_integral_rem,
|
||||||
|
},
|
||||||
type3classes.IntNum.methods['abs']: {
|
type3classes.IntNum.methods['abs']: {
|
||||||
'a=i32': stdlib_types.i32_intnum_abs,
|
'a=i32': stdlib_types.i32_intnum_abs,
|
||||||
'a=i64': stdlib_types.i64_intnum_abs,
|
'a=i64': stdlib_types.i64_intnum_abs,
|
||||||
|
|||||||
@ -366,6 +366,10 @@ class OurVisitor:
|
|||||||
operator = '*'
|
operator = '*'
|
||||||
elif isinstance(node.op, ast.Div):
|
elif isinstance(node.op, ast.Div):
|
||||||
operator = '/'
|
operator = '/'
|
||||||
|
elif isinstance(node.op, ast.FloorDiv):
|
||||||
|
operator = '//'
|
||||||
|
elif isinstance(node.op, ast.Mod):
|
||||||
|
operator = '%'
|
||||||
elif isinstance(node.op, ast.LShift):
|
elif isinstance(node.op, ast.LShift):
|
||||||
operator = '<<'
|
operator = '<<'
|
||||||
elif isinstance(node.op, ast.RShift):
|
elif isinstance(node.op, ast.RShift):
|
||||||
|
|||||||
@ -495,6 +495,18 @@ def i32_integral_div(g: Generator) -> None:
|
|||||||
def i64_integral_div(g: Generator) -> None:
|
def i64_integral_div(g: Generator) -> None:
|
||||||
g.add_statement('i64.div_s')
|
g.add_statement('i64.div_s')
|
||||||
|
|
||||||
|
def u32_integral_rem(g: Generator) -> None:
|
||||||
|
g.add_statement('i32.rem_u')
|
||||||
|
|
||||||
|
def u64_integral_rem(g: Generator) -> None:
|
||||||
|
g.add_statement('i64.rem_u')
|
||||||
|
|
||||||
|
def i32_integral_rem(g: Generator) -> None:
|
||||||
|
g.add_statement('i32.rem_s')
|
||||||
|
|
||||||
|
def i64_integral_rem(g: Generator) -> None:
|
||||||
|
g.add_statement('i64.rem_s')
|
||||||
|
|
||||||
## ###
|
## ###
|
||||||
## class NatNum
|
## class NatNum
|
||||||
|
|
||||||
|
|||||||
@ -120,8 +120,10 @@ IntNum = Type3Class('IntNum', ['a'], methods={
|
|||||||
}, operators={}, inherited_classes=[NatNum])
|
}, operators={}, inherited_classes=[NatNum])
|
||||||
|
|
||||||
Integral = Type3Class('Eq', ['a'], methods={
|
Integral = Type3Class('Eq', ['a'], methods={
|
||||||
'div': 'a -> a -> a',
|
}, operators={
|
||||||
}, operators={}, inherited_classes=[NatNum])
|
'//': 'a -> a -> a',
|
||||||
|
'%': 'a -> a -> a',
|
||||||
|
}, inherited_classes=[NatNum])
|
||||||
|
|
||||||
Fractional = Type3Class('Fractional', ['a'], methods={
|
Fractional = Type3Class('Fractional', ['a'], methods={
|
||||||
'ceil': 'a -> a',
|
'ceil': 'a -> a',
|
||||||
|
|||||||
@ -6,11 +6,11 @@ TYPE_LIST = ['u32', 'u64', 'i32', 'i64']
|
|||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', TYPE_LIST)
|
@pytest.mark.parametrize('type_', TYPE_LIST)
|
||||||
def test_division_int(type_):
|
def test_integral_div_ok(type_):
|
||||||
code_py = f"""
|
code_py = f"""
|
||||||
@exported
|
@exported
|
||||||
def testEntry() -> {type_}:
|
def testEntry() -> {type_}:
|
||||||
return div(10, 3)
|
return 10 // 3
|
||||||
"""
|
"""
|
||||||
|
|
||||||
result = Suite(code_py).run_code()
|
result = Suite(code_py).run_code()
|
||||||
@ -20,11 +20,39 @@ def testEntry() -> {type_}:
|
|||||||
|
|
||||||
@pytest.mark.integration_test
|
@pytest.mark.integration_test
|
||||||
@pytest.mark.parametrize('type_', TYPE_LIST)
|
@pytest.mark.parametrize('type_', TYPE_LIST)
|
||||||
def test_division_zero_let_it_crash_int(type_):
|
def test_integral_div_zero_let_it_crash_int(type_):
|
||||||
code_py = f"""
|
code_py = f"""
|
||||||
@exported
|
@exported
|
||||||
def testEntry() -> {type_}:
|
def testEntry() -> {type_}:
|
||||||
return div(10, 0)
|
return 10 // 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
# WebAssembly dictates that integer division is a partial operator (e.g. unreachable for 0)
|
||||||
|
# https://www.w3.org/TR/wasm-core-1/#-hrefop-idiv-umathrmidiv_u_n-i_1-i_2
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
Suite(code_py).run_code()
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
@pytest.mark.parametrize('type_', TYPE_LIST)
|
||||||
|
def test_integral_rem_ok(type_):
|
||||||
|
code_py = f"""
|
||||||
|
@exported
|
||||||
|
def testEntry() -> {type_}:
|
||||||
|
return 10 % 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
result = Suite(code_py).run_code()
|
||||||
|
|
||||||
|
assert 1 == result.returned_value
|
||||||
|
assert isinstance(result.returned_value, int)
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
@pytest.mark.parametrize('type_', TYPE_LIST)
|
||||||
|
def test_integral_rem_zero_let_it_crash_int(type_):
|
||||||
|
code_py = f"""
|
||||||
|
@exported
|
||||||
|
def testEntry() -> {type_}:
|
||||||
|
return 10 % 0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# WebAssembly dictates that integer division is a partial operator (e.g. unreachable for 0)
|
# WebAssembly dictates that integer division is a partial operator (e.g. unreachable for 0)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user