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',
|
'^': 'xor',
|
||||||
'|': 'or',
|
'|': 'or',
|
||||||
'&': 'and',
|
'&': 'and',
|
||||||
|
'/': 'div_u' # Division by zero is a trap and the program will panic
|
||||||
}
|
}
|
||||||
|
|
||||||
U64_OPERATOR_MAP = {
|
U64_OPERATOR_MAP = {
|
||||||
@ -113,6 +114,7 @@ U64_OPERATOR_MAP = {
|
|||||||
'^': 'xor',
|
'^': 'xor',
|
||||||
'|': 'or',
|
'|': 'or',
|
||||||
'&': 'and',
|
'&': 'and',
|
||||||
|
'/': 'div_u' # Division by zero is a trap and the program will panic
|
||||||
}
|
}
|
||||||
|
|
||||||
I32_OPERATOR_MAP = {
|
I32_OPERATOR_MAP = {
|
||||||
@ -120,6 +122,7 @@ I32_OPERATOR_MAP = {
|
|||||||
'>': 'gt_s',
|
'>': 'gt_s',
|
||||||
'<=': 'le_s',
|
'<=': 'le_s',
|
||||||
'>=': 'ge_s',
|
'>=': 'ge_s',
|
||||||
|
'/': 'div_s' # Division by zero is a trap and the program will panic
|
||||||
}
|
}
|
||||||
|
|
||||||
I64_OPERATOR_MAP = {
|
I64_OPERATOR_MAP = {
|
||||||
@ -127,6 +130,15 @@ I64_OPERATOR_MAP = {
|
|||||||
'>': 'gt_s',
|
'>': 'gt_s',
|
||||||
'<=': 'le_s',
|
'<=': 'le_s',
|
||||||
'>=': 'ge_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:
|
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):
|
if operator := OPERATOR_MAP.get(inp.operator, None):
|
||||||
wgn.add_statement(f'f32.{operator}')
|
wgn.add_statement(f'f32.{operator}')
|
||||||
return
|
return
|
||||||
|
if operator := F32_OPERATOR_MAP.get(inp.operator, None):
|
||||||
|
wgn.add_statement(f'f32.{operator}')
|
||||||
|
return
|
||||||
if mtyp == 'f64':
|
if mtyp == 'f64':
|
||||||
if operator := OPERATOR_MAP.get(inp.operator, None):
|
if operator := OPERATOR_MAP.get(inp.operator, None):
|
||||||
wgn.add_statement(f'f64.{operator}')
|
wgn.add_statement(f'f64.{operator}')
|
||||||
return
|
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)
|
raise NotImplementedError(expression, inp.type_var, inp.operator)
|
||||||
|
|
||||||
|
|||||||
@ -351,6 +351,8 @@ class OurVisitor:
|
|||||||
operator = '-'
|
operator = '-'
|
||||||
elif isinstance(node.op, ast.Mult):
|
elif isinstance(node.op, ast.Mult):
|
||||||
operator = '*'
|
operator = '*'
|
||||||
|
elif isinstance(node.op, ast.Div):
|
||||||
|
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):
|
||||||
|
|||||||
@ -98,7 +98,7 @@ def expression(ctx: Context, inp: ourlang.Expression) -> 'TypeVar':
|
|||||||
return right
|
return right
|
||||||
|
|
||||||
if isinstance(inp, ourlang.BinaryOp):
|
if isinstance(inp, ourlang.BinaryOp):
|
||||||
if inp.operator in ('+', '-', '*', '|', '&', '^'):
|
if inp.operator in ('+', '-', '*', '/', '|', '&', '^'):
|
||||||
left = expression(ctx, inp.left)
|
left = expression(ctx, inp.left)
|
||||||
right = expression(ctx, inp.right)
|
right = expression(ctx, inp.right)
|
||||||
ctx.unify(left, right)
|
ctx.unify(left, right)
|
||||||
|
|||||||
@ -226,7 +226,34 @@ def testEntry() -> {type_}:
|
|||||||
assert TYPE_MAP[type_] == type(result.returned_value)
|
assert TYPE_MAP[type_] == type(result.returned_value)
|
||||||
|
|
||||||
# TODO: Multiplication
|
# 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.integration_test
|
||||||
@pytest.mark.parametrize('type_', ['f32', 'f64'])
|
@pytest.mark.parametrize('type_', ['f32', 'f64'])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user