docs: public Token next() throws IOException {
  
          // skip whitespace
          while (Character.isWhitespace((char)lastChar))
          {
              readChar();
          }
  
          // handle punctuation
          switch (lastChar)
          {
              case -1:  readChar(); return Token.TokenEOF;
              case '{': readChar(); return Token.TokenBraceL;
              case '}': readChar(); return Token.TokenBraceR;
              case '[': readChar(); return Token.TokenBrackL;
              case ']': readChar(); return Token.TokenBrackR;
              case ':': readChar(); return Token.TokenColon;
              case ',': readChar(); return Token.TokenComma;
  
              case '"':
              case '\'':
                  String stringValue = readString();
                  return new Token(stringValue);
  
              case '-':
              case '.':
              case '0':
              case '1':
              case '2':
              case '3':
              case '4':
              case '5':
              case '6':
              case '7':
              case '8':
              case '9':
                  Number numberValue = readNumber();
                  return new Token(numberValue);
  
              case 'n': 
              case 't':
              case 'f':
                  String ident = readIdentifier();
  
                  if (ident.equals("null"))  return Token.TokenNull;
                  if (ident.equals("true"))  return Token.TokenTrue;
                  if (ident.equals("false")) return Token.TokenFalse;
  
                  throw new IOException("Unexpected identifier '" + ident + "' " + onLineCol());
  
              default:
                  throw new IOException("Unexpected character '" + (char)lastChar + "' " + onLineCol());
  
          }
  
      }