1.1 --- a/generator.py Sat Dec 03 16:26:03 2016 +0100
1.2 +++ b/generator.py Sat Dec 03 16:44:55 2016 +0100
1.3 @@ -55,9 +55,11 @@
1.4 # NOTE: These must be synchronised with the library.
1.5
1.6 function_type = "__builtins__.core.function"
1.7 + memory_error_type = "__builtins__.core.MemoryError"
1.8 + overflow_error_type = "__builtins__.core.OverflowError"
1.9 type_error_type = "__builtins__.core.TypeError"
1.10 - memory_error_type = "__builtins__.core.MemoryError"
1.11 type_type = "__builtins__.core.type"
1.12 + zero_division_error_type = "__builtins__.core.ZeroDivisionError"
1.13
1.14 predefined_constant_members = (
1.15 ("__builtins__.boolean", "False"),
1.16 @@ -357,8 +359,10 @@
1.17
1.18 #define __FUNCTION_TYPE %s
1.19 #define __FUNCTION_INSTANCE_SIZE %s
1.20 +#define __MEMORY_ERROR_INSTANTIATOR %s
1.21 +#define __OVERFLOW_ERROR_INSTANTIATOR %s
1.22 #define __TYPE_ERROR_INSTANTIATOR %s
1.23 -#define __MEMORY_ERROR_INSTANTIATOR %s
1.24 +#define __ZERO_DIVISION_ERROR_INSTANTIATOR %s
1.25 #define __TYPE_CLASS_TYPE %s
1.26 #define __TYPE_CLASS_POS %s
1.27 #define __TYPE_CLASS_CODE %s
1.28 @@ -366,8 +370,10 @@
1.29 #endif /* __PROGTYPES_H__ */""" % (
1.30 encode_path(self.function_type),
1.31 encode_size("<instance>", self.function_type),
1.32 + encode_instantiator_pointer(self.memory_error_type),
1.33 + encode_instantiator_pointer(self.overflow_error_type),
1.34 encode_instantiator_pointer(self.type_error_type),
1.35 - encode_instantiator_pointer(self.memory_error_type),
1.36 + encode_instantiator_pointer(self.zero_division_error_type),
1.37 encode_path(self.type_type),
1.38 encode_symbol("pos", encode_type_attribute(self.type_type)),
1.39 encode_symbol("code", encode_type_attribute(self.type_type)),
2.1 --- a/lib/__builtins__/__init__.py Sat Dec 03 16:26:03 2016 +0100
2.2 +++ b/lib/__builtins__/__init__.py Sat Dec 03 16:44:55 2016 +0100
2.3 @@ -20,7 +20,8 @@
2.4 """
2.5
2.6 from __builtins__.core import function, get_using, module, object, type, \
2.7 - BaseException, Exception, MemoryError, TypeError, \
2.8 + BaseException, Exception, MemoryError, \
2.9 + OverflowError, TypeError, ZeroDivisionError, \
2.10 UnboundMethodInvocation, Warning
2.11
2.12 # Exceptions.
2.13 @@ -44,7 +45,6 @@
2.14 NameError,
2.15 NotImplementedError,
2.16 OSError,
2.17 - OverflowError,
2.18 PendingDeprecationWarning,
2.19 RuntimeError,
2.20 RuntimeWarning,
2.21 @@ -61,8 +61,7 @@
2.22 UnicodeTranslateError,
2.23 UnicodeWarning,
2.24 UserWarning,
2.25 - ValueError,
2.26 - ZeroDivisionError
2.27 + ValueError
2.28 )
2.29
2.30
3.1 --- a/lib/__builtins__/core.py Sat Dec 03 16:26:03 2016 +0100
3.2 +++ b/lib/__builtins__/core.py Sat Dec 03 16:44:55 2016 +0100
3.3 @@ -121,9 +121,11 @@
3.4
3.5 class Exception(BaseException): pass
3.6 class MemoryError(Exception): pass
3.7 +class OverflowError(Exception): pass
3.8 class TypeError(Exception): pass
3.9 class UnboundMethodInvocation(Exception): pass
3.10 -class Warning(object): pass
3.11 +class Warning: pass
3.12 +class ZeroDivisionError(Exception): pass
3.13
3.14 def get_using(callable, instance):
3.15
4.1 --- a/lib/__builtins__/exception/__init__.py Sat Dec 03 16:26:03 2016 +0100
4.2 +++ b/lib/__builtins__/exception/__init__.py Sat Dec 03 16:44:55 2016 +0100
4.3 @@ -47,9 +47,7 @@
4.4
4.5 from __builtins__.exception.numeric import (
4.6 ArithmeticError,
4.7 - FloatingPointError,
4.8 - OverflowError,
4.9 - ZeroDivisionError
4.10 + FloatingPointError
4.11 )
4.12
4.13 from __builtins__.exception.program import (
5.1 --- a/lib/__builtins__/exception/numeric.py Sat Dec 03 16:26:03 2016 +0100
5.2 +++ b/lib/__builtins__/exception/numeric.py Sat Dec 03 16:44:55 2016 +0100
5.3 @@ -3,7 +3,7 @@
5.4 """
5.5 Numeric exception objects.
5.6
5.7 -Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>
5.8 +Copyright (C) 2015, 2016 Paul Boddie <paul@boddie.org.uk>
5.9
5.10 This program is free software; you can redistribute it and/or modify it under
5.11 the terms of the GNU General Public License as published by the Free Software
5.12 @@ -21,7 +21,5 @@
5.13
5.14 class ArithmeticError(Exception): pass
5.15 class FloatingPointError(Exception): pass
5.16 -class OverflowError(Exception): pass
5.17 -class ZeroDivisionError(Exception): pass
5.18
5.19 # vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/templates/native.c Sat Dec 03 16:26:03 2016 +0100
6.2 +++ b/templates/native.c Sat Dec 03 16:44:55 2016 +0100
6.3 @@ -1,8 +1,10 @@
6.4 #include <stdlib.h> /* abs, exit */
6.5 #include <unistd.h> /* read, write */
6.6 +#include <limits.h> /* INT_MAX, INT_MIN */
6.7 #include <math.h> /* ceil, log10, pow */
6.8 #include <string.h> /* strcmp, strncpy, strlen */
6.9 #include <stdio.h> /* snprintf */
6.10 +#include <errno.h> /* errno */
6.11 #include "types.h"
6.12 #include "exceptions.h"
6.13 #include "ops.h"
6.14 @@ -109,8 +111,13 @@
6.15 int i = _data->intvalue;
6.16 int j = other->intvalue;
6.17
6.18 + /* Test for overflow. */
6.19 + if (((i > 0) && (j > 0) && (i > INT_MAX - j)) ||
6.20 + ((i < 0) && (j < 0) && (i < INT_MIN - j)))
6.21 +
6.22 + __raise_overflow_error();
6.23 +
6.24 /* Return the new integer. */
6.25 - /* NOTE: No overflow test applied. */
6.26 return __new_int(i + j);
6.27 }
6.28
6.29 @@ -122,8 +129,13 @@
6.30 int i = _data->intvalue;
6.31 int j = other->intvalue;
6.32
6.33 + /* Test for overflow. */
6.34 + if (((i < 0) && (j > 0) && (i < INT_MIN + j)) ||
6.35 + ((i > 0) && (j < 0) && (i > INT_MAX + j)))
6.36 +
6.37 + __raise_overflow_error();
6.38 +
6.39 /* Return the new integer. */
6.40 - /* NOTE: No overflow test applied. */
6.41 return __new_int(i - j);
6.42 }
6.43
6.44 @@ -135,8 +147,15 @@
6.45 int i = _data->intvalue;
6.46 int j = other->intvalue;
6.47
6.48 + /* Test for overflow. */
6.49 + if (((i > 0) && (j > 0) && (i > INT_MAX / j)) ||
6.50 + ((i < 0) && (j < 0) && (i > INT_MAX / j)) ||
6.51 + ((i < 0) && (j > 0) && (i < INT_MIN / j)) ||
6.52 + ((i > 0) && (j < 0) && (j < INT_MIN / i)))
6.53 +
6.54 + __raise_overflow_error();
6.55 +
6.56 /* Return the new integer. */
6.57 - /* NOTE: No overflow test applied. */
6.58 return __new_int(i * j);
6.59 }
6.60
6.61 @@ -148,8 +167,13 @@
6.62 int i = _data->intvalue;
6.63 int j = other->intvalue;
6.64
6.65 + /* Test for division by zero or overflow. */
6.66 + if (j == 0)
6.67 + __raise_zero_division_error();
6.68 + else if ((j == -1) && (i == INT_MIN))
6.69 + __raise_overflow_error();
6.70 +
6.71 /* Return the new integer. */
6.72 - /* NOTE: No overflow test applied. */
6.73 return __new_int(i / j);
6.74 }
6.75
6.76 @@ -161,8 +185,13 @@
6.77 int i = _data->intvalue;
6.78 int j = other->intvalue;
6.79
6.80 + /* Test for division by zero or overflow. */
6.81 + if (j == 0)
6.82 + __raise_zero_division_error();
6.83 + else if ((j == -1) && (i == INT_MIN))
6.84 + __raise_overflow_error();
6.85 +
6.86 /* Return the new integer. */
6.87 - /* NOTE: No overflow test applied. */
6.88 return __new_int(i % j);
6.89 }
6.90
6.91 @@ -172,6 +201,10 @@
6.92 /* _data interpreted as int */
6.93 int i = _data->intvalue;
6.94
6.95 + /* Test for overflow. */
6.96 + if (i == INT_MIN)
6.97 + __raise_overflow_error();
6.98 +
6.99 /* Return the new integer. */
6.100 return __new_int(-i);
6.101 }
6.102 @@ -183,10 +216,18 @@
6.103 /* _data and other interpreted as int */
6.104 int i = _data->intvalue;
6.105 int j = other->intvalue;
6.106 + int k;
6.107 +
6.108 + errno = 0;
6.109 + k = (int) pow(i, j);
6.110 +
6.111 + /* Test for overflow. */
6.112 +
6.113 + if (errno == ERANGE)
6.114 + __raise_overflow_error();
6.115
6.116 /* Return the new integer. */
6.117 - /* NOTE: No overflow test applied. */
6.118 - return __new_int((int) pow(i, j));
6.119 + return __new_int(k);
6.120 }
6.121
6.122 __attr __fn_native__int_and(__attr __args[])
7.1 --- a/templates/progops.c Sat Dec 03 16:26:03 2016 +0100
7.2 +++ b/templates/progops.c Sat Dec 03 16:44:55 2016 +0100
7.3 @@ -79,7 +79,21 @@
7.4
7.5 #endif /* __HAVE___builtins___dict_dict */
7.6
7.7 -/* A helper for raising type errors within common operations. */
7.8 +/* Helpers for raising errors within common operations. */
7.9 +
7.10 +void __raise_memory_error()
7.11 +{
7.12 + __attr args[1];
7.13 + __attr exc = __MEMORY_ERROR_INSTANTIATOR(args);
7.14 + __Raise(exc);
7.15 +}
7.16 +
7.17 +void __raise_overflow_error()
7.18 +{
7.19 + __attr args[1];
7.20 + __attr exc = __OVERFLOW_ERROR_INSTANTIATOR(args);
7.21 + __Raise(exc);
7.22 +}
7.23
7.24 void __raise_type_error()
7.25 {
7.26 @@ -88,12 +102,10 @@
7.27 __Raise(exc);
7.28 }
7.29
7.30 -/* A helper for raising memory errors within common operations. */
7.31 -
7.32 -void __raise_memory_error()
7.33 +void __raise_zero_division_error()
7.34 {
7.35 __attr args[1];
7.36 - __attr exc = __MEMORY_ERROR_INSTANTIATOR(args);
7.37 + __attr exc = __ZERO_DIVISION_ERROR_INSTANTIATOR(args);
7.38 __Raise(exc);
7.39 }
7.40
8.1 --- a/templates/progops.h Sat Dec 03 16:26:03 2016 +0100
8.2 +++ b/templates/progops.h Sat Dec 03 16:44:55 2016 +0100
8.3 @@ -13,8 +13,10 @@
8.4
8.5 void __newdata_mapping(__attr args[], unsigned int number);
8.6
8.7 +void __raise_memory_error();
8.8 +void __raise_overflow_error();
8.9 +void __raise_zero_division_error();
8.10 void __raise_type_error();
8.11 -void __raise_memory_error();
8.12
8.13 __attr __invoke(__attr callable, int always_callable,
8.14 unsigned int nkwargs, __param kwcodes[], __attr kwargs[],
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/tests/numbers.py Sat Dec 03 16:44:55 2016 +0100
9.3 @@ -0,0 +1,19 @@
9.4 +i = 2 ** 30
9.5 +print i
9.6 +
9.7 +j = -2 ** 30
9.8 +print j
9.9 +
9.10 +print i + j
9.11 +
9.12 +try:
9.13 + print i - j
9.14 +except OverflowError:
9.15 + print "i - j: overflow occurred"
9.16 +
9.17 +print i / j
9.18 +
9.19 +try:
9.20 + print i * j
9.21 +except OverflowError:
9.22 + print "i * j: overflow occurred"