// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Dart core library.

// VM implementation of int.

@patch class int {

  @patch const factory int.fromEnvironment(String name,
                                           {int defaultValue})
      native "Integer_fromEnvironment";


  static int _tryParseSmi(String str, int first, int last) {
    assert(first <= last);
    var ix = first;
    var sign = 1;
    var c = str.codeUnitAt(ix);
    // Check for leading '+' or '-'.
    if ((c == 0x2b) || (c == 0x2d)) {
      ix++;
      sign = 0x2c - c;  // -1 for '-', +1 for '+'.
      if (ix > last) {
        return null;  // Empty.
      }
    }
    var smiLimit = internal.is64Bit ? 18 : 9;
    if ((last - ix) >= smiLimit) {
      return null;  // May not fit into a Smi.
    }
    var result = 0;
    for (int i = ix; i <= last; i++) {
      var c = 0x30 ^ str.codeUnitAt(i);
      if (9 < c) {
        return null;
      }
      result = 10 * result + c;
    }
    return sign * result;
  }

  @patch static int parse(String source,
                          { int radix,
                            int onError(String str) }) {
    if (source == null) throw new ArgumentError("The source must not be null");
    if (source.isEmpty) return _throwFormatException(onError, source, 0, radix);
    if (radix == null || radix == 10) {
      // Try parsing immediately, without trimming whitespace.
      int result = _tryParseSmi(source, 0, source.length - 1);
      if (result != null) return result;
    } else if (radix < 2 || radix > 36) {
      throw new RangeError("Radix $radix not in range 2..36");
    }
    // Split here so improve odds of parse being inlined and the checks omitted.
    return _parse(source, radix, onError);
  }

  static int _parse(String source, int radix, onError) {
    int end = source._lastNonWhitespace() + 1;
    if (end == 0) {
      return _throwFormatException(onError, source, source.length, radix);
    }
    int start = source._firstNonWhitespace();

    int first = source.codeUnitAt(start);
    int sign = 1;
    if (first == 0x2b /* + */ || first == 0x2d /* - */) {
      sign = 0x2c - first;  // -1 if '-', +1 if '+'.
      start++;
      if (start == end) {
        return _throwFormatException(onError, source, end, radix);
      }
      first = source.codeUnitAt(start);
    }
    if (radix == null) {
      // check for 0x prefix.
      int index = start;
      if (first == 0x30 /* 0 */) {
        index++;
        if (index == end) return 0;
        first = source.codeUnitAt(index);
        if ((first | 0x20) == 0x78 /* x */) {
          index++;
          if (index == end) {
            return _throwFormatException(onError, source, index, null);
          }
          int result = _parseRadix(source, 16, index, end, sign);
          if (result == null) {
            return _throwFormatException(onError, source, null, null);
          }
          return result;
        }
      }
      radix = 10;
    }
    int result = _parseRadix(source, radix, start, end, sign);
    if (result == null) {
      return _throwFormatException(onError, source, null, radix);
    }
    return result;
  }

  static int _throwFormatException(onError, source, index, radix) {
    if (onError != null) return onError(source);
    if (radix == null) {
      throw new FormatException("Invalid number", source, index);
    }
    throw new FormatException("Invalid radix-$radix number", source, index);
  }

  static int _parseRadix(String source, int radix,
                         int start, int end, int sign) {
    int tableIndex = (radix - 2) * 4 + (internal.is64Bit ? 2 : 0);
    int blockSize = _PARSE_LIMITS[tableIndex];
    int length = end - start;
    if (length <= blockSize) {
      _Smi smi = _parseBlock(source, radix, start, end);
      if (smi != null) return sign * smi;
      return null;
    }

    // Often cheaper than: int smallBlockSize = length % blockSize;
    // because digit count generally tends towards smaller. rather
    // than larger.
    int smallBlockSize = length;
    while (smallBlockSize >= blockSize) smallBlockSize -= blockSize;
    int result = 0;
    if (smallBlockSize > 0) {
      int blockEnd = start + smallBlockSize;
      _Smi smi = _parseBlock(source, radix, start, blockEnd);
      if (smi == null) return null;
      result = sign * smi;
      start = blockEnd;
    }
    int multiplier = _PARSE_LIMITS[tableIndex + 1];
    int blockEnd = start + blockSize;
    do {
      _Smi smi = _parseBlock(source, radix, start, blockEnd);
      if (smi == null) return null;
      result = (result * multiplier) + (sign * smi);
      start = blockEnd;
      blockEnd = start + blockSize;
    } while (blockEnd <= end);
    return result;
  }

  // Parse block of digits into a Smi.
  static _Smi _parseBlock(String source, int radix, int start, int end) {
    _Smi result = 0;
    if (radix <= 10) {
      for (int i = start; i < end; i++) {
        int digit = source.codeUnitAt(i) ^ 0x30;
        if (digit >= radix) return null;
        result = radix * result + digit;
      }
    } else {
      for (int i = start; i < end; i++) {
        int char = source.codeUnitAt(i);
        int digit = char ^ 0x30;
        if (digit > 9) {
          digit = (char | 0x20) - (0x61 - 10);
          if (digit < 10 || digit >= radix) return null;
        }
        result = radix * result + digit;
      }
    }
    return result;
  }

  // For each radix, 2-36, how many digits are guaranteed to fit in a smi,
  // and magnitude of such a block (radix ** digit-count).
  // 32-bit limit/multiplier at (radix - 2)*4, 64-bit limit at (radix-2)*4+2
  static const _PARSE_LIMITS = const [
    30, 1073741824,  62, 4611686018427387904,  /* radix: 2 */
    18,  387420489,  39, 4052555153018976267,
    15, 1073741824,  30, 1152921504606846976,
    12,  244140625,  26, 1490116119384765625,  /* radix: 5 */
    11,  362797056,  23,  789730223053602816,
    10,  282475249,  22, 3909821048582988049,
    10, 1073741824,  20, 1152921504606846976,
     9,  387420489,  19, 1350851717672992089,
     9, 1000000000,  18, 1000000000000000000,  /* radix: 10 */
     8,  214358881,  17,  505447028499293771,
     8,  429981696,  17, 2218611106740436992,
     8,  815730721,  16,  665416609183179841,
     7,  105413504,  16, 2177953337809371136,
     7,  170859375,  15,  437893890380859375,   /* radix: 15 */
     7,  268435456,  15, 1152921504606846976,
     7,  410338673,  15, 2862423051509815793,
     7,  612220032,  14,  374813367582081024,
     7,  893871739,  14,  799006685782884121,
     6,   64000000,  14, 1638400000000000000,  /* radix: 20 */
     6,   85766121,  14, 3243919932521508681,
     6,  113379904,  13,  282810057883082752,
     6,  148035889,  13,  504036361936467383,
     6,  191102976,  13,  876488338465357824,
     6,  244140625,  13, 1490116119384765625,  /* radix: 25 */
     6,  308915776,  13, 2481152873203736576,
     6,  387420489,  13, 4052555153018976267,
     6,  481890304,  12,  232218265089212416,
     6,  594823321,  12,  353814783205469041,
     6,  729000000,  12,  531441000000000000,  /* radix: 30 */
     6,  887503681,  12,  787662783788549761,
     6, 1073741824,  12, 1152921504606846976,
     5,   39135393,  12, 1667889514952984961,
     5,   45435424,  12, 2386420683693101056,
     5,   52521875,  12, 3379220508056640625,  /* radix: 35 */
     5,   60466176,  11,  131621703842267136,
  ];
}
