private void scanNumber() throws IOException {
  boolean seenNonOctal=false;
  boolean overflow=false;
  boolean seenDigit=false;
  radix=(ch == '0' ? 8 : 10);
  long value=ch - '0';
  count=0;
  putc(ch);
  numberLoop:   for (; ; ) {
switch (ch=in.read()) {
case '.':
      if (radix == 16)       break numberLoop;
    scanReal();
  return;
case '8':
case '9':
seenNonOctal=true;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
seenDigit=true;
putc(ch);
if (radix == 10) {
overflow=overflow || (value * 10) / 10 != value;
value=(value * 10) + (ch - '0');
overflow=overflow || (value - 1 < -1);
}
 else if (radix == 8) {
overflow=overflow || (value >>> 61) != 0;
value=(value << 3) + (ch - '0');
}
 else {
overflow=overflow || (value >>> 60) != 0;
value=(value << 4) + (ch - '0');
}
break;
case 'd':
case 'D':
case 'e':
case 'E':
case 'f':
case 'F':
if (radix != 16) {
scanReal();
return;
}
case 'a':
case 'A':
case 'b':
case 'B':
case 'c':
case 'C':
seenDigit=true;
putc(ch);
if (radix != 16) break numberLoop;
overflow=overflow || (value >>> 60) != 0;
value=(value << 4) + 10 + Character.toLowerCase((char)ch) - 'a';
break;
case 'l':
case 'L':
ch=in.read();
longValue=value;
token=LONGVAL;
break numberLoop;
case 'x':
case 'X':
if (count == 1 && radix == 8) {
radix=16;
seenDigit=false;
break;
}
 else {
break numberLoop;
}
default :
intValue=(int)value;
token=INTVAL;
break numberLoop;
}
}
if (Character.isJavaLetterOrDigit((char)ch) || ch == '.') {
env.error(in.pos,"invalid.number");
do {
ch=in.read();
}
 while (Character.isJavaLetterOrDigit((char)ch) || ch == '.');
intValue=0;
token=INTVAL;
}
 else if (radix == 8 && seenNonOctal) {
intValue=0;
token=INTVAL;
env.error(pos,"invalid.octal.number");
}
 else if (radix == 16 && seenDigit == false) {
intValue=0;
token=INTVAL;
env.error(pos,"invalid.hex.number");
}
 else {
if (token == INTVAL) {
overflow=overflow || (value & 0xFFFFFFFF00000000L) != 0 || (radix == 10 && value > 2147483648L);
if (overflow) {
intValue=0;
switch (radix) {
case 8:
env.error(pos,"overflow.int.oct");
break;
case 10:
env.error(pos,"overflow.int.dec");
break;
case 16:
env.error(pos,"overflow.int.hex");
break;
default :
throw new CompilerError("invalid radix");
}
}
}
 else {
if (overflow) {
longValue=0;
switch (radix) {
case 8:
env.error(pos,"overflow.long.oct");
break;
case 10:
env.error(pos,"overflow.long.dec");
break;
case 16:
env.error(pos,"overflow.long.hex");
break;
default :
throw new CompilerError("invalid radix");
}
}
}
}
}

private void scanNumber ( ) throws IOException { boolean seenNonOctal = false ; boolean overflow = false ; boolean seenDigit = false ; radix = ( ch == '0' ? 8 : 10 ) ; long value = ch - '0' ; count = 0 ; putc ( ch ) ; numberLoop : for ( ; ; ) { switch ( ch = in . read ( ) ) { case '.' : if ( radix == 16 ) break numberLoop ; scanReal ( ) ; return ; case '8' : case '9' : seenNonOctal = true ; case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : seenDigit = true ; putc ( ch ) ; if ( radix == 10 ) { overflow = overflow || ( value * 10 ) / 10 != value ; value = ( value * 10 ) + ( ch - '0' ) ; overflow = overflow || ( value - 1 < - 1 ) ; } else if ( radix == 8 ) { overflow = overflow || ( value > > > 61 ) != 0 ; value = ( value << 3 ) + ( ch - '0' ) ; } else { overflow = overflow || ( value > > > 60 ) != 0 ; value = ( value << 4 ) + ( ch - '0' ) ; } break ; case 'd' : case 'D' : case 'e' : case 'E' : case 'f' : case 'F' : if ( radix != 16 ) { scanReal ( ) ; return ; } case 'a' : case 'A' : case 'b' : case 'B' : case 'c' : case 'C' : seenDigit = true ; putc ( ch ) ; if ( radix != 16 ) break numberLoop ; overflow = overflow || ( value > > > 60 ) != 0 ; value = ( value << 4 ) + 10 + Character . toLowerCase ( ( char ) ch ) - 'a' ; break ; case 'l' : case 'L' : ch = in . read ( ) ; longValue = value ; token = LONGVAL ; break numberLoop ; case 'x' : case 'X' : if ( count == 1 && radix == 8 ) { radix = 16 ; seenDigit = false ; break ; } else { break numberLoop ; } default : intValue = ( int ) value ; token = INTVAL ; break numberLoop ; } } if ( Character . isJavaLetterOrDigit ( ( char ) ch ) || ch == '.' ) { env . error ( in . pos , "invalid.number" ) ; do { ch = in . read ( ) ; } while ( Character . isJavaLetterOrDigit ( ( char ) ch ) || ch == '.' ) ; intValue = 0 ; token = INTVAL ; } else if ( radix == 8 && seenNonOctal ) { intValue = 0 ; token = INTVAL ; env . error ( pos , "invalid.octal.number" ) ; } else if ( radix == 16 && seenDigit == false ) { intValue = 0 ; token = INTVAL ; env . error ( pos , "invalid.hex.number" ) ; } else { if ( token == INTVAL ) { overflow = overflow || ( value & 0xFFFFFFFF00000000L ) != 0 || ( radix == 10 && value > 2147483648L ) ; if ( overflow ) { intValue = 0 ; switch ( radix ) { case 8 : env . error ( pos , "overflow.int.oct" ) ; break ; case 10 : env . error ( pos , "overflow.int.dec" ) ; break ; case 16 : env . error ( pos , "overflow.int.hex" ) ; break ; default : throw new CompilerError ( "invalid radix" ) ; } } } else { if ( overflow ) { longValue = 0 ; switch ( radix ) { case 8 : env . error ( pos , "overflow.long.oct" ) ; break ; case 10 : env . error ( pos , "overflow.long.dec" ) ; break ; case 16 : env . error ( pos , "overflow.long.hex" ) ; break ; default : throw new CompilerError ( "invalid radix" ) ; } } } } }
scan a number . the first digit of the number should be the current character . we may be scanning hex , decimal , or octal at this point
