@@ -28,6 +28,7 @@ public static Expression Parse(ParserArguments arguments)
28
28
29
29
private const NumberStyles ParseLiteralNumberStyle = NumberStyles . AllowLeadingSign ;
30
30
private const NumberStyles ParseLiteralUnsignedNumberStyle = NumberStyles . AllowLeadingSign ;
31
+ private const NumberStyles ParseLiteralHexNumberStyle = NumberStyles . HexNumber ;
31
32
private const NumberStyles ParseLiteralDecimalNumberStyle = NumberStyles . AllowLeadingSign | NumberStyles . AllowDecimalPoint ;
32
33
private const NumberStyles ParseLiteralDoubleNumberStyle = NumberStyles . AllowLeadingSign | NumberStyles . AllowDecimalPoint | NumberStyles . AllowExponent ;
33
34
private static readonly CultureInfo ParseCulture = CultureInfo . InvariantCulture ;
@@ -877,12 +878,31 @@ private Expression ParseIntegerLiteral()
877
878
878
879
text = text . Substring ( 0 , numberEnd + 1 ) ;
879
880
880
- // No suffix find , verify if DefaultNumberType.Long is specified
881
+ // No suffix found , verify if DefaultNumberType.Long is specified
881
882
if ( _defaultNumberType == DefaultNumberType . Long ) isLong = true ;
882
883
883
884
if ( text [ 0 ] != '-' )
884
885
{
885
- if ( ! ulong . TryParse ( text , ParseLiteralUnsignedNumberStyle , ParseCulture , out ulong value ) )
886
+ ulong value ;
887
+ if ( text . StartsWith ( "0x" ) || text . StartsWith ( "0X" ) )
888
+ {
889
+ var hex = text . Substring ( 2 ) ;
890
+ if ( ! ulong . TryParse ( hex , ParseLiteralHexNumberStyle , ParseCulture , out value ) )
891
+ throw CreateParseException ( _token . pos , ErrorMessages . InvalidIntegerLiteral , text ) ;
892
+ }
893
+ else if ( text . StartsWith ( "0b" ) || text . StartsWith ( "0B" ) )
894
+ {
895
+ var binary = text . Substring ( 2 ) ;
896
+ try
897
+ {
898
+ value = Convert . ToUInt64 ( binary , 2 ) ;
899
+ }
900
+ catch ( FormatException ex )
901
+ {
902
+ throw WrapWithParseException ( _token . pos , ErrorMessages . InvalidIntegerLiteral , ex , text ) ;
903
+ }
904
+ }
905
+ else if ( ! ulong . TryParse ( text , ParseLiteralUnsignedNumberStyle , ParseCulture , out value ) )
886
906
throw CreateParseException ( _token . pos , ErrorMessages . InvalidIntegerLiteral , text ) ;
887
907
888
908
NextToken ( ) ;
@@ -3005,12 +3025,39 @@ private void NextToken()
3005
3025
t = TokenId . IntegerLiteral ;
3006
3026
}
3007
3027
3028
+ // binary and hexadecimal integer literals
3029
+ var canBeRealLiteral = true ;
3030
+ if ( _parseChar == '0' )
3031
+ {
3032
+ NextChar ( ) ;
3033
+ if ( _parseChar == 'x' || _parseChar == 'X' )
3034
+ {
3035
+ canBeRealLiteral = false ;
3036
+ do
3037
+ {
3038
+ NextChar ( ) ;
3039
+ } while ( char . IsDigit ( _parseChar ) || ( _parseChar >= 'a' && _parseChar <= 'f' ) || ( _parseChar >= 'A' && _parseChar <= 'F' ) ) ;
3040
+ }
3041
+ else if ( _parseChar == 'b' || _parseChar == 'B' )
3042
+ {
3043
+ canBeRealLiteral = false ;
3044
+ do
3045
+ {
3046
+ NextChar ( ) ;
3047
+ } while ( _parseChar == '0' || _parseChar == '1' ) ;
3048
+ }
3049
+ else
3050
+ {
3051
+ PreviousChar ( ) ;
3052
+ }
3053
+ }
3054
+
3008
3055
do
3009
3056
{
3010
3057
NextChar ( ) ;
3011
3058
} while ( char . IsDigit ( _parseChar ) ) ;
3012
3059
3013
- if ( _parseChar == '.' )
3060
+ if ( canBeRealLiteral && _parseChar == '.' )
3014
3061
{
3015
3062
NextChar ( ) ;
3016
3063
if ( char . IsDigit ( _parseChar ) )
@@ -3028,7 +3075,7 @@ private void NextToken()
3028
3075
}
3029
3076
}
3030
3077
3031
- if ( _parseChar == 'E' || _parseChar == 'e' )
3078
+ if ( canBeRealLiteral && ( _parseChar == 'E' || _parseChar == 'e' ) )
3032
3079
{
3033
3080
t = TokenId . RealLiteral ;
3034
3081
NextChar ( ) ;
@@ -3041,7 +3088,7 @@ private void NextToken()
3041
3088
} while ( char . IsDigit ( _parseChar ) ) ;
3042
3089
}
3043
3090
3044
- if ( _parseChar == 'D' || _parseChar == 'd' || _parseChar == 'F' || _parseChar == 'f' || _parseChar == 'M' || _parseChar == 'm' )
3091
+ if ( canBeRealLiteral && ( _parseChar == 'D' || _parseChar == 'd' || _parseChar == 'F' || _parseChar == 'f' || _parseChar == 'M' || _parseChar == 'm' ) )
3045
3092
{
3046
3093
t = TokenId . RealLiteral ;
3047
3094
NextChar ( ) ;
@@ -3050,12 +3097,14 @@ private void NextToken()
3050
3097
// 'U' | 'u' | 'L' | 'l' | 'UL' | 'Ul' | 'uL' | 'ul' | 'LU' | 'Lu' | 'lU' | 'lu'
3051
3098
if ( _parseChar == 'U' || _parseChar == 'u' )
3052
3099
{
3100
+ t = TokenId . IntegerLiteral ;
3053
3101
NextChar ( ) ;
3054
3102
if ( _parseChar == 'L' || _parseChar == 'l' )
3055
3103
NextChar ( ) ;
3056
3104
}
3057
3105
else if ( _parseChar == 'L' || _parseChar == 'l' )
3058
3106
{
3107
+ t = TokenId . IntegerLiteral ;
3059
3108
NextChar ( ) ;
3060
3109
if ( _parseChar == 'U' || _parseChar == 'u' )
3061
3110
NextChar ( ) ;
@@ -3104,9 +3153,9 @@ private void ValidateToken(TokenId t)
3104
3153
throw CreateParseException ( _token . pos , ErrorMessages . SyntaxError ) ;
3105
3154
}
3106
3155
3107
- private static Exception WrapWithParseException ( int pos , string msg , Exception ex )
3156
+ private static Exception WrapWithParseException ( int pos , string format , Exception ex , params object [ ] args )
3108
3157
{
3109
- return new ParseException ( msg , pos , ex ) ;
3158
+ return new ParseException ( string . Format ( format , args ) , pos , ex ) ;
3110
3159
}
3111
3160
3112
3161
private static Exception CreateParseException ( int pos , string format , params object [ ] args )
0 commit comments