Lichen

lib/__builtins__/int.py

932:c07b0dd14f85
2021-06-28 Paul Boddie Moved integer instantiation support to library functions.
     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__.str import basestring    23 from __builtins__.unicode import utf8string    24 from native import get_maxint, get_minint, is_int, \    25                    int_add, int_and, int_div, int_eq, int_ge, int_gt, \    26                    int_lshift, int_le, int_lt, int_mod, int_mul, int_ne, \    27                    int_neg, int_not, int_or, int_pow, int_rshift, int_str, \    28                    int_sub, int_xor    29     30 def new_int(number_or_string, base=10):    31     32     "Initialise the integer with the given 'number_or_string'."    33     34     if is_int(number_or_string):    35         return number_or_string    36     elif isinstance(number_or_string, basestring):    37         return str_to_int(number_or_string, base)    38     else:    39         raise TypeError    40     41 def str_to_int(value, base=10):    42     43     "Decode the string 'value' using the given 'base'."    44     45     # NOTE: Add support for lower and upper in the string classes.    46     47     #value = value.lower()    48     len_value = len(value)    49     digits = "0123456789abcdefghijklmnopqrstuvwxyz"    50     51     result = 0    52     i = 0    53     54     while i < len_value:    55         c = value[i]    56         d = digits.index(c)    57         result = result * base + d    58         i += 1    59     60     return result    61     62 class int:    63     64     "An integer abstraction."    65     66     def __init__(self, number_or_string=None, base=10):    67     68         "Initialise the integer with the given 'number_or_string'."    69     70         # Implemented by new_int above, invoked specially by the translator.    71     72         pass    73     74     def __hash__(self):    75     76         "Return a value for hashing purposes."    77     78         return self    79     80     def _binary_op(self, op, other):    81     82         "Perform 'op' on this int and 'other' if appropriate."    83     84         if is_int(other):    85             return op(self, other)    86         else:    87             return NotImplemented    88     89     def _binary_op_rev(self, op, other):    90     91         "Perform 'op' on 'other' and this int if appropriate."    92     93         if is_int(other):    94             return op(other, self)    95         else:    96             return NotImplemented    97     98     def __iadd__(self, other):    99    100         "Return a new int for the addition of this int and 'other'."   101    102         return self._binary_op(int_add, other)   103    104     def __isub__(self, other):   105    106         "Return a new int for the subtraction of this int and 'other'."   107    108         return self._binary_op(int_sub, other)   109    110     def __imul__(self, other):   111    112         "Return a new int for the multiplication of this int and 'other'."   113    114         return self._binary_op(int_mul, other)   115    116     def __idiv__(self, other):   117    118         "Return a new int for the division of this int and 'other'."   119    120         return self._binary_op(int_div, other)   121    122     def __imod__(self, other):   123    124         "Return a new int for the modulo of this int by 'other'."   125    126         return self._binary_op(int_mod, other)   127    128     def __ipow__(self, other):   129    130         "Return a new int for the exponentiation of this int by 'other'."   131    132         return self._binary_op(int_pow, other)   133    134     def __iand__(self, other):   135    136         "Return a new int for the binary-and of this int and 'other'."   137    138         return self._binary_op(int_and, other)   139    140     def __ior__(self, other):   141    142         "Return a new int for the binary-or of this int and 'other'."   143    144         return self._binary_op(int_or, other)   145    146     def __ixor__(self, other):   147    148         "Return a new int for the exclusive-or of this int and 'other'."   149    150         return self._binary_op(int_xor, other)   151    152     def __invert__(self):   153    154         "Return the inversion of this int."   155    156         return int_not(self)   157    158     __add__ = __radd__ = __iadd__   159     __sub__ = __isub__   160    161     def __rsub__(self, other):   162    163         "Return a new int for the subtraction of this int from 'other'."   164    165         return self._binary_op_rev(int_sub, other)   166    167     __mul__ = __rmul__ = __imul__   168     __div__ = __idiv__   169    170     def __rdiv__(self, other):   171    172         "Return a new int for the division of this int into 'other'."   173    174         return self._binary_op_rev(int_div, other)   175    176     # NOTE: To be implemented.   177    178     def __floordiv__(self, other): pass   179     def __rfloordiv__(self, other): pass   180     def __ifloordiv__(self, other): pass   181    182     __mod__ = __imod__   183    184     def __rmod__(self, other):   185    186         "Return a new int for the modulo of 'other' by this int."   187    188         return self._binary_op_rev(int_mod, other)   189    190     __pow__ = __ipow__   191    192     def __rpow__(self, other):   193    194         "Return a new int for the exponentiation of 'other' by this int."   195    196         return self._binary_op_rev(int_pow, other)   197    198     __and__ = __rand__ = __iand__   199     __or__ = __ror__ = __ior__   200     __xor__ = __rxor__ = __ixor__   201    202     def __lshift__(self, other):   203    204         "Return a new int left-shifted by 'other'."   205    206         return self._binary_op(int_lshift, other)   207    208     def __rlshift__(self, other):   209    210         "Return a new int left-shifted by 'other'."   211    212         return self._binary_op_rev(int_lshift, other)   213    214     def __rshift__(self, other):   215    216         "Return a new int right-shifted by 'other'."   217    218         return self._binary_op(int_rshift, other)   219    220     def __rrshift__(self, other):   221    222         "Return a new int right-shifted by 'other'."   223    224         return self._binary_op_rev(int_rshift, other)   225    226     __ilshift__ = __lshift__   227     __irshift__ = __rshift__   228    229     def __lt__(self, other):   230    231         "Return whether this int is less than 'other'."   232    233         return self._binary_op(int_lt, other)   234    235     def __gt__(self, other):   236    237         "Return whether this int is greater than 'other'."   238    239         return self._binary_op(int_gt, other)   240    241     def __le__(self, other):   242    243         "Return whether this int is less than or equal to 'other'."   244    245         return self._binary_op(int_le, other)   246    247     def __ge__(self, other):   248    249         "Return whether this int is greater than or equal to 'other'."   250    251         return self._binary_op(int_ge, other)   252    253     def __eq__(self, other):   254    255         "Return whether this int is equal to 'other'."   256    257         return self._binary_op(int_eq, other)   258    259     def __ne__(self, other):   260    261         "Return whether this int is not equal to 'other'."   262    263         return self._binary_op(int_ne, other)   264    265     def __neg__(self):   266    267         "Apply the unary negation operator."   268    269         return int_neg(self)   270    271     def __pos__(self):   272    273         "Apply the unary positive operator."   274    275         return self   276    277     def __str__(self):   278    279         "Return a string representation."   280    281         return utf8string(int_str(self))   282    283     __repr__ = __str__   284    285     def __bool__(self):   286    287         "Return whether this int is non-zero."   288    289         return int_ne(self, 0)   290    291 # Limits.   292    293 maxint = get_maxint()   294 minint = get_minint()   295    296 # vim: tabstop=4 expandtab shiftwidth=4