Lichen

Changeset

932:c07b0dd14f85
2021-06-28 Paul Boddie raw files shortlog changelog graph Moved integer instantiation support to library functions.
generator.py (file) lib/__builtins__/int.py (file) tests/int.py (file)
     1.1 --- a/generator.py	Sun Jun 27 22:39:01 2021 +0200
     1.2 +++ b/generator.py	Mon Jun 28 00:13:11 2021 +0200
     1.3 @@ -1202,14 +1202,14 @@
     1.4  
     1.5          # Special-case the integer type.
     1.6  
     1.7 +        # Here, the __builtins__.int.new_int function is called with the
     1.8 +        # initialiser's parameter.
     1.9 +
    1.10          if path == self.int_type:
    1.11              print >>f_code, """\
    1.12 -__attr %s(__attr __self, __attr number_or_string)
    1.13 +__attr %s(__attr __self, __attr number_or_string, __attr base)
    1.14  {
    1.15 -    if (!__BOOL(__fn_native_int_is_int(__NULL, number_or_string)))
    1.16 -        __raise_value_error(number_or_string);
    1.17 -
    1.18 -    return number_or_string;
    1.19 +    return __fn___builtins___int_new_int(__NULL, number_or_string, base);
    1.20  }
    1.21  """ % (
    1.22                  encode_instantiator_pointer(path),
     2.1 --- a/lib/__builtins__/int.py	Sun Jun 27 22:39:01 2021 +0200
     2.2 +++ b/lib/__builtins__/int.py	Mon Jun 28 00:13:11 2021 +0200
     2.3 @@ -19,6 +19,7 @@
     2.4  this program.  If not, see <http://www.gnu.org/licenses/>.
     2.5  """
     2.6  
     2.7 +from __builtins__.str import basestring
     2.8  from __builtins__.unicode import utf8string
     2.9  from native import get_maxint, get_minint, is_int, \
    2.10                     int_add, int_and, int_div, int_eq, int_ge, int_gt, \
    2.11 @@ -26,15 +27,47 @@
    2.12                     int_neg, int_not, int_or, int_pow, int_rshift, int_str, \
    2.13                     int_sub, int_xor
    2.14  
    2.15 +def new_int(number_or_string, base=10):
    2.16 +
    2.17 +    "Initialise the integer with the given 'number_or_string'."
    2.18 +
    2.19 +    if is_int(number_or_string):
    2.20 +        return number_or_string
    2.21 +    elif isinstance(number_or_string, basestring):
    2.22 +        return str_to_int(number_or_string, base)
    2.23 +    else:
    2.24 +        raise TypeError
    2.25 +
    2.26 +def str_to_int(value, base=10):
    2.27 +
    2.28 +    "Decode the string 'value' using the given 'base'."
    2.29 +
    2.30 +    # NOTE: Add support for lower and upper in the string classes.
    2.31 +
    2.32 +    #value = value.lower()
    2.33 +    len_value = len(value)
    2.34 +    digits = "0123456789abcdefghijklmnopqrstuvwxyz"
    2.35 +
    2.36 +    result = 0
    2.37 +    i = 0
    2.38 +
    2.39 +    while i < len_value:
    2.40 +        c = value[i]
    2.41 +        d = digits.index(c)
    2.42 +        result = result * base + d
    2.43 +        i += 1
    2.44 +
    2.45 +    return result
    2.46 +
    2.47  class int:
    2.48  
    2.49      "An integer abstraction."
    2.50  
    2.51 -    def __init__(self, number_or_string=None):
    2.52 +    def __init__(self, number_or_string=None, base=10):
    2.53  
    2.54          "Initialise the integer with the given 'number_or_string'."
    2.55  
    2.56 -        # Implemented in the translator.
    2.57 +        # Implemented by new_int above, invoked specially by the translator.
    2.58  
    2.59          pass
    2.60  
     3.1 --- a/tests/int.py	Sun Jun 27 22:39:01 2021 +0200
     3.2 +++ b/tests/int.py	Mon Jun 28 00:13:11 2021 +0200
     3.3 @@ -11,3 +11,20 @@
     3.4      a = int("a")        # should raise an exception
     3.5  except ValueError, exc:
     3.6      print 'int("a") failed:', exc.value
     3.7 +
     3.8 +try:
     3.9 +    a = int("!")        # should raise an exception
    3.10 +except ValueError, exc:
    3.11 +    print 'int("!") failed:', exc.value
    3.12 +
    3.13 +a = int("a", 16)
    3.14 +b = int("123")
    3.15 +print a                 # 10
    3.16 +print b, i, b == i      # 123, 123, True
    3.17 +print b, j, b == j      # 123, 123, True
    3.18 +
    3.19 +a_is_int = isinstance(a, int)
    3.20 +j_is_int = isinstance(j, int)
    3.21 +
    3.22 +print a_is_int          # True
    3.23 +print j_is_int          # True