anchor.diff:              c = TAB;
               break;
             case CHAR_U:
  -            if (position + 5 > json.length) {
  +            if (position + 5 > length) {
                 _error('Invalid unicode esacape sequence');
               }
               final codeString = json.substring(position + 1, position + 5);
  
positive.code:   }
  
    num _parseNumber() {
      if (!_isToken(NUMBER_LITERAL)) _error("Expected number literal");
  
      final int startPos = position;
      if (_isChar(MINUS)) position++;
      if (_isChar(CHAR_0)) {
        position++;
      } else if (_isDigit()) {
        position++;
        while (_isDigit()) position++;
      } else {
        _error("Expected digit when parsing number");
      }
  
      bool isInt = true;
      if (_isChar(DOT)) {
        position++;
        if (_isDigit()) {
          isInt = false;
          while (_isDigit()) position++;
        } else {
          position--;  // No digit, backtrack.
        }
      }
  
      if (_isChar(CHAR_E) || _isChar(CHAR_CAPITAL_E)) {
        int backtrackTo = position;
        position++;
        if (_isChar(MINUS) || _isChar(PLUS)) position++;
        if (_isDigit()) {
          position++;
          isInt = false;
          while (_isDigit()) position++;
        } else {
          position = backtrackTo;  // No digit, backtrack.
        }
      }
  
  
negative.code:     return new _JsonParser._internal(json)._parseToplevel();
    }
  
    _JsonParser._internal(String json)
        : json = json,
          length = json.length {
      if (tokens !== null) return;
  
      // Use a list as jump-table, faster then switch and if.
  