1 #!/usr/bin/env python 2 3 """ 4 Integer objects. 5 6 Copyright (C) 2015, 2016, 2017, 2018, 2021 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 """ 21 22 from __builtins__.unicode import utf8string 23 from native import get_maxint, get_minint, is_int, \ 24 int_add, int_and, int_div, int_eq, int_ge, int_gt, \ 25 int_lshift, int_le, int_lt, int_mod, int_mul, int_ne, \ 26 int_neg, int_not, int_or, int_pow, int_rshift, int_str, \ 27 int_sub, int_xor 28 29 def int(number_or_string): 30 31 "Initialise the integer with the given 'number_or_string'." 32 33 if is_int(number_or_string): 34 return number_or_string 35 else: 36 raise TypeError 37 38 class integer: 39 40 "An integer abstraction." 41 42 def __hash__(self): 43 44 "Return a value for hashing purposes." 45 46 return self 47 48 def _binary_op(self, op, other): 49 50 "Perform 'op' on this int and 'other' if appropriate." 51 52 if is_int(other): 53 return op(self, other) 54 else: 55 return NotImplemented 56 57 def _binary_op_rev(self, op, other): 58 59 "Perform 'op' on 'other' and this int if appropriate." 60 61 if is_int(other): 62 return op(other, self) 63 else: 64 return NotImplemented 65 66 def __iadd__(self, other): 67 68 "Return a new int for the addition of this int and 'other'." 69 70 return self._binary_op(int_add, other) 71 72 def __isub__(self, other): 73 74 "Return a new int for the subtraction of this int and 'other'." 75 76 return self._binary_op(int_sub, other) 77 78 def __imul__(self, other): 79 80 "Return a new int for the multiplication of this int and 'other'." 81 82 return self._binary_op(int_mul, other) 83 84 def __idiv__(self, other): 85 86 "Return a new int for the division of this int and 'other'." 87 88 return self._binary_op(int_div, other) 89 90 def __imod__(self, other): 91 92 "Return a new int for the modulo of this int by 'other'." 93 94 return self._binary_op(int_mod, other) 95 96 def __ipow__(self, other): 97 98 "Return a new int for the exponentiation of this int by 'other'." 99 100 return self._binary_op(int_pow, other) 101 102 def __iand__(self, other): 103 104 "Return a new int for the binary-and of this int and 'other'." 105 106 return self._binary_op(int_and, other) 107 108 def __ior__(self, other): 109 110 "Return a new int for the binary-or of this int and 'other'." 111 112 return self._binary_op(int_or, other) 113 114 def __ixor__(self, other): 115 116 "Return a new int for the exclusive-or of this int and 'other'." 117 118 return self._binary_op(int_xor, other) 119 120 def __invert__(self): 121 122 "Return the inversion of this int." 123 124 return int_not(self) 125 126 __add__ = __radd__ = __iadd__ 127 __sub__ = __isub__ 128 129 def __rsub__(self, other): 130 131 "Return a new int for the subtraction of this int from 'other'." 132 133 return self._binary_op_rev(int_sub, other) 134 135 __mul__ = __rmul__ = __imul__ 136 __div__ = __idiv__ 137 138 def __rdiv__(self, other): 139 140 "Return a new int for the division of this int into 'other'." 141 142 return self._binary_op_rev(int_div, other) 143 144 # NOTE: To be implemented. 145 146 def __floordiv__(self, other): pass 147 def __rfloordiv__(self, other): pass 148 def __ifloordiv__(self, other): pass 149 150 __mod__ = __imod__ 151 152 def __rmod__(self, other): 153 154 "Return a new int for the modulo of 'other' by this int." 155 156 return self._binary_op_rev(int_mod, other) 157 158 __pow__ = __ipow__ 159 160 def __rpow__(self, other): 161 162 "Return a new int for the exponentiation of 'other' by this int." 163 164 return self._binary_op_rev(int_pow, other) 165 166 __and__ = __rand__ = __iand__ 167 __or__ = __ror__ = __ior__ 168 __xor__ = __rxor__ = __ixor__ 169 170 def __lshift__(self, other): 171 172 "Return a new int left-shifted by 'other'." 173 174 return self._binary_op(int_lshift, other) 175 176 def __rlshift__(self, other): 177 178 "Return a new int left-shifted by 'other'." 179 180 return self._binary_op_rev(int_lshift, other) 181 182 def __rshift__(self, other): 183 184 "Return a new int right-shifted by 'other'." 185 186 return self._binary_op(int_rshift, other) 187 188 def __rrshift__(self, other): 189 190 "Return a new int right-shifted by 'other'." 191 192 return self._binary_op_rev(int_rshift, other) 193 194 __ilshift__ = __lshift__ 195 __irshift__ = __rshift__ 196 197 def __lt__(self, other): 198 199 "Return whether this int is less than 'other'." 200 201 return self._binary_op(int_lt, other) 202 203 def __gt__(self, other): 204 205 "Return whether this int is greater than 'other'." 206 207 return self._binary_op(int_gt, other) 208 209 def __le__(self, other): 210 211 "Return whether this int is less than or equal to 'other'." 212 213 return self._binary_op(int_le, other) 214 215 def __ge__(self, other): 216 217 "Return whether this int is greater than or equal to 'other'." 218 219 return self._binary_op(int_ge, other) 220 221 def __eq__(self, other): 222 223 "Return whether this int is equal to 'other'." 224 225 return self._binary_op(int_eq, other) 226 227 def __ne__(self, other): 228 229 "Return whether this int is not equal to 'other'." 230 231 return self._binary_op(int_ne, other) 232 233 def __neg__(self): 234 235 "Apply the unary negation operator." 236 237 return int_neg(self) 238 239 def __pos__(self): 240 241 "Apply the unary positive operator." 242 243 return self 244 245 def __str__(self): 246 247 "Return a string representation." 248 249 return utf8string(int_str(self)) 250 251 __repr__ = __str__ 252 253 def __bool__(self): 254 255 "Return whether this int is non-zero." 256 257 return int_ne(self, 0) 258 259 # Limits. 260 261 maxint = get_maxint() 262 minint = get_minint() 263 264 # vim: tabstop=4 expandtab shiftwidth=4