Make division by zero raise an exception.

This commit is contained in:
whitequark 2015-07-23 01:26:50 +03:00
parent 4cfe4ea148
commit f8c2709943
3 changed files with 24 additions and 13 deletions

View File

@ -83,6 +83,10 @@ class TValueError(TException):
def __init__(self): def __init__(self):
super().__init__("ValueError") super().__init__("ValueError")
class TZeroDivisionError(TException):
def __init__(self):
super().__init__("ZeroDivisionError")
def fn_bool(): def fn_bool():
return types.TConstructor("bool") return types.TConstructor("bool")
@ -107,6 +111,9 @@ def fn_IndexError():
def fn_ValueError(): def fn_ValueError():
return types.TExceptionConstructor("ValueError") return types.TExceptionConstructor("ValueError")
def fn_ZeroDivisionError():
return types.TExceptionConstructor("ZeroDivisionError")
def fn_range(): def fn_range():
return types.TBuiltinFunction("range") return types.TBuiltinFunction("range")

View File

@ -15,6 +15,7 @@ def globals():
"Exception": builtins.fn_Exception(), "Exception": builtins.fn_Exception(),
"IndexError": builtins.fn_IndexError(), "IndexError": builtins.fn_IndexError(),
"ValueError": builtins.fn_ValueError(), "ValueError": builtins.fn_ValueError(),
"ZeroDivisionError": builtins.fn_ZeroDivisionError(),
"len": builtins.fn_len(), "len": builtins.fn_len(),
"round": builtins.fn_round(), "round": builtins.fn_round(),
"print": builtins.fn_print(), "print": builtins.fn_print(),

View File

@ -899,13 +899,16 @@ class ARTIQIRGenerator(algorithm.Visitor):
def visit_BinOpT(self, node): def visit_BinOpT(self, node):
if builtins.is_numeric(node.type): if builtins.is_numeric(node.type):
# TODO: check for division by zero
rhs = self.visit(node.right) rhs = self.visit(node.right)
if isinstance(node.op, (ast.LShift, ast.RShift)): if isinstance(node.op, (ast.LShift, ast.RShift)):
# Check for negative shift amount. # Check for negative shift amount.
self._make_check(self.append(ir.Compare(ast.GtE(loc=None), rhs, self._make_check(self.append(ir.Compare(ast.GtE(loc=None), rhs,
ir.Constant(0, rhs.type))), ir.Constant(0, rhs.type))),
lambda: self.append(ir.Alloc([], builtins.TValueError()))) lambda: self.append(ir.Alloc([], builtins.TValueError())))
elif isinstance(node.op, (ast.Div, ast.FloorDiv)):
self._make_check(self.append(ir.Compare(ast.NotEq(loc=None), rhs,
ir.Constant(0, rhs.type))),
lambda: self.append(ir.Alloc([], builtins.TZeroDivisionError())))
return self.append(ir.Arith(node.op, self.visit(node.left), rhs)) return self.append(ir.Arith(node.op, self.visit(node.left), rhs))
elif isinstance(node.op, ast.Add): # list + list, tuple + tuple elif isinstance(node.op, ast.Add): # list + list, tuple + tuple