# HG changeset patch # User Paul Boddie # Date 1480779895 -3600 # Node ID 95b8056f3a79920c2676d863936c38506f6caa20 # Parent 92aaba8e1846402ec5a230a4aff33c0f44ffe25f Added overflow and zero division error tests to the integer operations. Moved OverflowError and ZeroDivisionError to the core built-ins. Added helper functions for raising these errors from native functions. diff -r 92aaba8e1846 -r 95b8056f3a79 generator.py --- a/generator.py Sat Dec 03 16:26:03 2016 +0100 +++ b/generator.py Sat Dec 03 16:44:55 2016 +0100 @@ -55,9 +55,11 @@ # NOTE: These must be synchronised with the library. function_type = "__builtins__.core.function" + memory_error_type = "__builtins__.core.MemoryError" + overflow_error_type = "__builtins__.core.OverflowError" type_error_type = "__builtins__.core.TypeError" - memory_error_type = "__builtins__.core.MemoryError" type_type = "__builtins__.core.type" + zero_division_error_type = "__builtins__.core.ZeroDivisionError" predefined_constant_members = ( ("__builtins__.boolean", "False"), @@ -357,8 +359,10 @@ #define __FUNCTION_TYPE %s #define __FUNCTION_INSTANCE_SIZE %s +#define __MEMORY_ERROR_INSTANTIATOR %s +#define __OVERFLOW_ERROR_INSTANTIATOR %s #define __TYPE_ERROR_INSTANTIATOR %s -#define __MEMORY_ERROR_INSTANTIATOR %s +#define __ZERO_DIVISION_ERROR_INSTANTIATOR %s #define __TYPE_CLASS_TYPE %s #define __TYPE_CLASS_POS %s #define __TYPE_CLASS_CODE %s @@ -366,8 +370,10 @@ #endif /* __PROGTYPES_H__ */""" % ( encode_path(self.function_type), encode_size("", self.function_type), + encode_instantiator_pointer(self.memory_error_type), + encode_instantiator_pointer(self.overflow_error_type), encode_instantiator_pointer(self.type_error_type), - encode_instantiator_pointer(self.memory_error_type), + encode_instantiator_pointer(self.zero_division_error_type), encode_path(self.type_type), encode_symbol("pos", encode_type_attribute(self.type_type)), encode_symbol("code", encode_type_attribute(self.type_type)), diff -r 92aaba8e1846 -r 95b8056f3a79 lib/__builtins__/__init__.py --- a/lib/__builtins__/__init__.py Sat Dec 03 16:26:03 2016 +0100 +++ b/lib/__builtins__/__init__.py Sat Dec 03 16:44:55 2016 +0100 @@ -20,7 +20,8 @@ """ from __builtins__.core import function, get_using, module, object, type, \ - BaseException, Exception, MemoryError, TypeError, \ + BaseException, Exception, MemoryError, \ + OverflowError, TypeError, ZeroDivisionError, \ UnboundMethodInvocation, Warning # Exceptions. @@ -44,7 +45,6 @@ NameError, NotImplementedError, OSError, - OverflowError, PendingDeprecationWarning, RuntimeError, RuntimeWarning, @@ -61,8 +61,7 @@ UnicodeTranslateError, UnicodeWarning, UserWarning, - ValueError, - ZeroDivisionError + ValueError ) diff -r 92aaba8e1846 -r 95b8056f3a79 lib/__builtins__/core.py --- a/lib/__builtins__/core.py Sat Dec 03 16:26:03 2016 +0100 +++ b/lib/__builtins__/core.py Sat Dec 03 16:44:55 2016 +0100 @@ -121,9 +121,11 @@ class Exception(BaseException): pass class MemoryError(Exception): pass +class OverflowError(Exception): pass class TypeError(Exception): pass class UnboundMethodInvocation(Exception): pass -class Warning(object): pass +class Warning: pass +class ZeroDivisionError(Exception): pass def get_using(callable, instance): diff -r 92aaba8e1846 -r 95b8056f3a79 lib/__builtins__/exception/__init__.py --- a/lib/__builtins__/exception/__init__.py Sat Dec 03 16:26:03 2016 +0100 +++ b/lib/__builtins__/exception/__init__.py Sat Dec 03 16:44:55 2016 +0100 @@ -47,9 +47,7 @@ from __builtins__.exception.numeric import ( ArithmeticError, - FloatingPointError, - OverflowError, - ZeroDivisionError + FloatingPointError ) from __builtins__.exception.program import ( diff -r 92aaba8e1846 -r 95b8056f3a79 lib/__builtins__/exception/numeric.py --- a/lib/__builtins__/exception/numeric.py Sat Dec 03 16:26:03 2016 +0100 +++ b/lib/__builtins__/exception/numeric.py Sat Dec 03 16:44:55 2016 +0100 @@ -3,7 +3,7 @@ """ Numeric exception objects. -Copyright (C) 2015 Paul Boddie +Copyright (C) 2015, 2016 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -21,7 +21,5 @@ class ArithmeticError(Exception): pass class FloatingPointError(Exception): pass -class OverflowError(Exception): pass -class ZeroDivisionError(Exception): pass # vim: tabstop=4 expandtab shiftwidth=4 diff -r 92aaba8e1846 -r 95b8056f3a79 templates/native.c --- a/templates/native.c Sat Dec 03 16:26:03 2016 +0100 +++ b/templates/native.c Sat Dec 03 16:44:55 2016 +0100 @@ -1,8 +1,10 @@ #include /* abs, exit */ #include /* read, write */ +#include /* INT_MAX, INT_MIN */ #include /* ceil, log10, pow */ #include /* strcmp, strncpy, strlen */ #include /* snprintf */ +#include /* errno */ #include "types.h" #include "exceptions.h" #include "ops.h" @@ -109,8 +111,13 @@ int i = _data->intvalue; int j = other->intvalue; + /* Test for overflow. */ + if (((i > 0) && (j > 0) && (i > INT_MAX - j)) || + ((i < 0) && (j < 0) && (i < INT_MIN - j))) + + __raise_overflow_error(); + /* Return the new integer. */ - /* NOTE: No overflow test applied. */ return __new_int(i + j); } @@ -122,8 +129,13 @@ int i = _data->intvalue; int j = other->intvalue; + /* Test for overflow. */ + if (((i < 0) && (j > 0) && (i < INT_MIN + j)) || + ((i > 0) && (j < 0) && (i > INT_MAX + j))) + + __raise_overflow_error(); + /* Return the new integer. */ - /* NOTE: No overflow test applied. */ return __new_int(i - j); } @@ -135,8 +147,15 @@ int i = _data->intvalue; int j = other->intvalue; + /* Test for overflow. */ + if (((i > 0) && (j > 0) && (i > INT_MAX / j)) || + ((i < 0) && (j < 0) && (i > INT_MAX / j)) || + ((i < 0) && (j > 0) && (i < INT_MIN / j)) || + ((i > 0) && (j < 0) && (j < INT_MIN / i))) + + __raise_overflow_error(); + /* Return the new integer. */ - /* NOTE: No overflow test applied. */ return __new_int(i * j); } @@ -148,8 +167,13 @@ int i = _data->intvalue; int j = other->intvalue; + /* Test for division by zero or overflow. */ + if (j == 0) + __raise_zero_division_error(); + else if ((j == -1) && (i == INT_MIN)) + __raise_overflow_error(); + /* Return the new integer. */ - /* NOTE: No overflow test applied. */ return __new_int(i / j); } @@ -161,8 +185,13 @@ int i = _data->intvalue; int j = other->intvalue; + /* Test for division by zero or overflow. */ + if (j == 0) + __raise_zero_division_error(); + else if ((j == -1) && (i == INT_MIN)) + __raise_overflow_error(); + /* Return the new integer. */ - /* NOTE: No overflow test applied. */ return __new_int(i % j); } @@ -172,6 +201,10 @@ /* _data interpreted as int */ int i = _data->intvalue; + /* Test for overflow. */ + if (i == INT_MIN) + __raise_overflow_error(); + /* Return the new integer. */ return __new_int(-i); } @@ -183,10 +216,18 @@ /* _data and other interpreted as int */ int i = _data->intvalue; int j = other->intvalue; + int k; + + errno = 0; + k = (int) pow(i, j); + + /* Test for overflow. */ + + if (errno == ERANGE) + __raise_overflow_error(); /* Return the new integer. */ - /* NOTE: No overflow test applied. */ - return __new_int((int) pow(i, j)); + return __new_int(k); } __attr __fn_native__int_and(__attr __args[]) diff -r 92aaba8e1846 -r 95b8056f3a79 templates/progops.c --- a/templates/progops.c Sat Dec 03 16:26:03 2016 +0100 +++ b/templates/progops.c Sat Dec 03 16:44:55 2016 +0100 @@ -79,7 +79,21 @@ #endif /* __HAVE___builtins___dict_dict */ -/* A helper for raising type errors within common operations. */ +/* Helpers for raising errors within common operations. */ + +void __raise_memory_error() +{ + __attr args[1]; + __attr exc = __MEMORY_ERROR_INSTANTIATOR(args); + __Raise(exc); +} + +void __raise_overflow_error() +{ + __attr args[1]; + __attr exc = __OVERFLOW_ERROR_INSTANTIATOR(args); + __Raise(exc); +} void __raise_type_error() { @@ -88,12 +102,10 @@ __Raise(exc); } -/* A helper for raising memory errors within common operations. */ - -void __raise_memory_error() +void __raise_zero_division_error() { __attr args[1]; - __attr exc = __MEMORY_ERROR_INSTANTIATOR(args); + __attr exc = __ZERO_DIVISION_ERROR_INSTANTIATOR(args); __Raise(exc); } diff -r 92aaba8e1846 -r 95b8056f3a79 templates/progops.h --- a/templates/progops.h Sat Dec 03 16:26:03 2016 +0100 +++ b/templates/progops.h Sat Dec 03 16:44:55 2016 +0100 @@ -13,8 +13,10 @@ void __newdata_mapping(__attr args[], unsigned int number); +void __raise_memory_error(); +void __raise_overflow_error(); +void __raise_zero_division_error(); void __raise_type_error(); -void __raise_memory_error(); __attr __invoke(__attr callable, int always_callable, unsigned int nkwargs, __param kwcodes[], __attr kwargs[], diff -r 92aaba8e1846 -r 95b8056f3a79 tests/numbers.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/numbers.py Sat Dec 03 16:44:55 2016 +0100 @@ -0,0 +1,19 @@ +i = 2 ** 30 +print i + +j = -2 ** 30 +print j + +print i + j + +try: + print i - j +except OverflowError: + print "i - j: overflow occurred" + +print i / j + +try: + print i * j +except OverflowError: + print "i * j: overflow occurred"