Implements division
Division by zero is a trap on most runtimes, following the Let it Crash philosophy
This commit is contained in:
parent
977c449c3f
commit
bce3ed7ba1
@ -101,6 +101,7 @@ U32_OPERATOR_MAP = {
|
||||
'^': 'xor',
|
||||
'|': 'or',
|
||||
'&': 'and',
|
||||
'/': 'div_u' # Division by zero is a trap and the program will panic
|
||||
}
|
||||
|
||||
U64_OPERATOR_MAP = {
|
||||
@ -113,6 +114,7 @@ U64_OPERATOR_MAP = {
|
||||
'^': 'xor',
|
||||
'|': 'or',
|
||||
'&': 'and',
|
||||
'/': 'div_u' # Division by zero is a trap and the program will panic
|
||||
}
|
||||
|
||||
I32_OPERATOR_MAP = {
|
||||
@ -120,6 +122,7 @@ I32_OPERATOR_MAP = {
|
||||
'>': 'gt_s',
|
||||
'<=': 'le_s',
|
||||
'>=': 'ge_s',
|
||||
'/': 'div_s' # Division by zero is a trap and the program will panic
|
||||
}
|
||||
|
||||
I64_OPERATOR_MAP = {
|
||||
@ -127,6 +130,15 @@ I64_OPERATOR_MAP = {
|
||||
'>': 'gt_s',
|
||||
'<=': 'le_s',
|
||||
'>=': 'ge_s',
|
||||
'/': 'div_s' # Division by zero is a trap and the program will panic
|
||||
}
|
||||
|
||||
F32_OPERATOR_MAP = {
|
||||
'/': 'div' # Division by zero is a trap and the program will panic
|
||||
}
|
||||
|
||||
F64_OPERATOR_MAP = {
|
||||
'/': 'div' # Division by zero is a trap and the program will panic
|
||||
}
|
||||
|
||||
def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None:
|
||||
@ -251,10 +263,16 @@ def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None:
|
||||
if operator := OPERATOR_MAP.get(inp.operator, None):
|
||||
wgn.add_statement(f'f32.{operator}')
|
||||
return
|
||||
if operator := F32_OPERATOR_MAP.get(inp.operator, None):
|
||||
wgn.add_statement(f'f32.{operator}')
|
||||
return
|
||||
if mtyp == 'f64':
|
||||
if operator := OPERATOR_MAP.get(inp.operator, None):
|
||||
wgn.add_statement(f'f64.{operator}')
|
||||
return
|
||||
if operator := F64_OPERATOR_MAP.get(inp.operator, None):
|
||||
wgn.add_statement(f'f64.{operator}')
|
||||
return
|
||||
|
||||
raise NotImplementedError(expression, inp.type_var, inp.operator)
|
||||
|
||||
|
||||
@ -351,6 +351,8 @@ class OurVisitor:
|
||||
operator = '-'
|
||||
elif isinstance(node.op, ast.Mult):
|
||||
operator = '*'
|
||||
elif isinstance(node.op, ast.Div):
|
||||
operator = '/'
|
||||
elif isinstance(node.op, ast.LShift):
|
||||
operator = '<<'
|
||||
elif isinstance(node.op, ast.RShift):
|
||||
|
||||
@ -98,7 +98,7 @@ def expression(ctx: Context, inp: ourlang.Expression) -> 'TypeVar':
|
||||
return right
|
||||
|
||||
if isinstance(inp, ourlang.BinaryOp):
|
||||
if inp.operator in ('+', '-', '*', '|', '&', '^'):
|
||||
if inp.operator in ('+', '-', '*', '/', '|', '&', '^'):
|
||||
left = expression(ctx, inp.left)
|
||||
right = expression(ctx, inp.right)
|
||||
ctx.unify(left, right)
|
||||
|
||||
@ -226,7 +226,34 @@ def testEntry() -> {type_}:
|
||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||
|
||||
# TODO: Multiplication
|
||||
# TODO: Division
|
||||
|
||||
@pytest.mark.integration_test
|
||||
@pytest.mark.parametrize('type_', COMPLETE_INT_TYPES)
|
||||
def test_division_int(type_):
|
||||
code_py = f"""
|
||||
@exported
|
||||
def testEntry() -> {type_}:
|
||||
return 10 / 3
|
||||
"""
|
||||
|
||||
result = Suite(code_py).run_code()
|
||||
|
||||
assert 3 == result.returned_value
|
||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||
|
||||
@pytest.mark.integration_test
|
||||
@pytest.mark.parametrize('type_', ALL_FLOAT_TYPES)
|
||||
def test_division_float(type_):
|
||||
code_py = f"""
|
||||
@exported
|
||||
def testEntry() -> {type_}:
|
||||
return 10.0 / 8.0
|
||||
"""
|
||||
|
||||
result = Suite(code_py).run_code()
|
||||
|
||||
assert 1.25 == result.returned_value
|
||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||
|
||||
@pytest.mark.integration_test
|
||||
@pytest.mark.parametrize('type_', ['f32', 'f64'])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user