Skip to content

Commit

Permalink
Fix #5729 and add first batch of tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
gdziadkiewicz committed Mar 21, 2019
1 parent d5f5bd0 commit 14dc98d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 26 deletions.
24 changes: 8 additions & 16 deletions src/fsharp/FSharp.Core/prim-types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2360,14 +2360,6 @@ namespace Microsoft.FSharp.Core
then p <- p + 1; -1L
else 1L

let parseOctalUInt64 (s:string) p l =
let rec parse n acc = if n < l then parse (n+1) (acc *.. 8UL +.. (let c = s.Chars(n) in if c >=... '0' && c <=... '7' then Convert.ToUInt64(c) -.. Convert.ToUInt64('0') else formatError())) else acc in
parse p 0UL

let parseBinaryUInt64 (s:string) p l =
let rec parse n acc = if n < l then parse (n+1) (acc *.. 2UL +.. (match s.Chars(n) with '0' -> 0UL | '1' -> 1UL | _ -> formatError())) else acc in
parse p 0UL

let inline removeUnderscores (s:string) =
match s with
| null -> null
Expand All @@ -2383,8 +2375,8 @@ namespace Microsoft.FSharp.Core
if p >= l then formatError() else
match specifier with
| 'x' -> UInt32.Parse( s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture)
| 'b' -> Convert.ToUInt32(parseBinaryUInt64 s p l)
| 'o' -> Convert.ToUInt32(parseOctalUInt64 s p l)
| 'b' -> Convert.ToUInt32(s.Substring(p), 2)
| 'o' -> Convert.ToUInt32(s.Substring(p), 8)
| _ -> UInt32.Parse(s.Substring(p), NumberStyles.Integer, CultureInfo.InvariantCulture) in

let inline int32OfUInt32 (x:uint32) = (# "" x : int32 #)
Expand All @@ -2401,8 +2393,8 @@ namespace Microsoft.FSharp.Core
if p >= l then formatError() else
match Char.ToLowerInvariant(specifier) with
| 'x' -> sign * (int32OfUInt32 (Convert.ToUInt32(UInt64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture))))
| 'b' -> sign * (int32OfUInt32 (Convert.ToUInt32(parseBinaryUInt64 s p l)))
| 'o' -> sign * (int32OfUInt32 (Convert.ToUInt32(parseOctalUInt64 s p l)))
| 'b' -> sign * (int32OfUInt32 (Convert.ToUInt32(s.Substring(p), 2)))
| 'o' -> sign * (int32OfUInt32 (Convert.ToUInt32(s.Substring(p), 8)))
| _ -> Int32.Parse(s, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)

let ParseInt64 (s:string) =
Expand All @@ -2416,8 +2408,8 @@ namespace Microsoft.FSharp.Core
if p >= l then formatError() else
match Char.ToLowerInvariant(specifier) with
| 'x' -> sign *. Int64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture)
| 'b' -> sign *. (int64OfUInt64 (parseBinaryUInt64 s p l))
| 'o' -> sign *. (int64OfUInt64 (parseOctalUInt64 s p l))
| 'b' -> sign *. (int64OfUInt64 (Convert.ToUInt64(s.Substring(p), 2)))
| 'o' -> sign *. (int64OfUInt64 (Convert.ToUInt64(s.Substring(p), 8)))
| _ -> Int64.Parse(s, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)

let ParseUInt64 (s:string) : uint64 =
Expand All @@ -2430,8 +2422,8 @@ namespace Microsoft.FSharp.Core
if p >= l then formatError() else
match specifier with
| 'x' -> UInt64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture)
| 'b' -> parseBinaryUInt64 s p l
| 'o' -> parseOctalUInt64 s p l
| 'b' -> Convert.ToUInt64(s.Substring(p), 2)
| 'o' -> Convert.ToUInt64(s.Substring(p), 8)
| _ -> UInt64.Parse(s.Substring(p), NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)


Expand Down
12 changes: 2 additions & 10 deletions src/fsharp/lex.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,6 @@ let get0OXB (s:string) (p:byref<int>) l =

let formatError() = raise (new System.FormatException(SR.GetString("bad format string")))

let parseBinaryUInt64 (s:string) p l =
let rec parse n acc = if n < l then parse (n+1) (acc * 2UL + (match s.[n] with '0' -> 0UL | '1' -> 1UL | _ -> formatError())) else acc
parse p 0UL

let parseOctalUInt64 (s:string) p l =
let rec parse n acc = if n < l then parse (n+1) (acc * 8UL + (let c = s.[n] in if c >= '0' && c <= '7' then Convert.ToUInt64 c - Convert.ToUInt64 '0' else formatError())) else acc
parse p 0UL

let removeUnderscores (s:string) =
match s with
| null -> null
Expand All @@ -91,8 +83,8 @@ let parseInt32 (s:string) =
match Char.ToLower(specifier,CultureInfo.InvariantCulture) with
#endif
| 'x' -> sign * (int32 (Convert.ToUInt32(UInt64.Parse(s.Substring(p), NumberStyles.AllowHexSpecifier,CultureInfo.InvariantCulture))))
| 'b' -> sign * (int32 (Convert.ToUInt32(parseBinaryUInt64 s p l)))
| 'o' -> sign * (int32 (Convert.ToUInt32(parseOctalUInt64 s p l)))
| 'b' -> sign * (int32 (Convert.ToUInt32(s.Substring(p), 2)))
| 'o' -> sign * (int32 (Convert.ToUInt32(s.Substring(p), 8)))
| _ -> Int32.Parse(s, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture)

let lexemeTrimRightToInt32 args lexbuf n =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// #Regression #Conformance #LexicalAnalysis #Constants


// Verify compile error for signed literals which are MaxSize + 1, MaxSize - 1
// All of these should cause compiler errors

//<Expects id="FS1142" status="error">This number is outside the allowable range for 8-bit signed integers</Expects>
//<Expects id="FS1145" status="error">This number is outside the allowable range for 16-bit signed integers</Expects>
//<Expects id="FS1147" status="error">This number is outside the allowable range for 32-bit signed integers</Expects>
//<Expects id="FS1149" status="error">This number is outside the allowable range for 64-bit signed integers</Expects>

//<Expects id="FS1142" status="error">This number is outside the allowable range for 8-bit signed integers</Expects>
//<Expects id="FS1145" status="error">This number is outside the allowable range for 16-bit signed integers</Expects>
//<Expects id="FS1147" status="error">This number is outside the allowable range for 32-bit signed integers</Expects>
//<Expects id="FS1149" status="error">This number is outside the allowable range for 64-bit signed integers</Expects>


let minByteBin = -0b10000001y
let maxByteBin = 0b10000000y

let minInt16Bin = -0b1000_0000_0000_0001s
let maxInt16Bin = 0b1000_0000_0000_0000s

let minInt32Bin = -0b1000_0000_0000_0000_0000_0000_0000_0001
let maxInt32Bin = 0b1000_0000_0000_0000_0000_0000_0000_0000

let minInt64Bin = -0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0001L
let maxInt64Bin = 0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000L
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// #Regression #Conformance #LexicalAnalysis #Constants


// Verify compile error for signed literals which are MaxSize + 1, MaxSize - 1
// All of these should cause compiler errors

//<Expects id="FS1142" status="error">This number is outside the allowable range for 8-bit signed integers</Expects>
//<Expects id="FS1145" status="error">This number is outside the allowable range for 16-bit signed integers</Expects>
//<Expects id="FS1147" status="error">This number is outside the allowable range for 32-bit signed integers</Expects>
//<Expects id="FS1149" status="error">This number is outside the allowable range for 64-bit signed integers</Expects>

//<Expects id="FS1142" status="error">This number is outside the allowable range for 8-bit signed integers</Expects>
//<Expects id="FS1145" status="error">This number is outside the allowable range for 16-bit signed integers</Expects>
//<Expects id="FS1147" status="error">This number is outside the allowable range for 32-bit signed integers</Expects>
//<Expects id="FS1149" status="error">This number is outside the allowable range for 64-bit signed integers</Expects>


let minByteHex = -0x81y
let maxByteHex = 0x80y

let minInt16Hex = -0x8001s
let maxInt16Hex = 0x8000s

let minInt32Hex = -0x8000_0001
let maxInt32Hex = 0x8000_0000

let minInt64Hex = -0x8000_0000_0000_0001L
let maxInt64Hex = 0x8000_0000_0000_0000L
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// #Regression #Conformance #LexicalAnalysis #Constants


// Verify compile error for signed literals which are MaxSize + 1, MaxSize - 1
// All of these should cause compiler errors

//<Expects id="FS1142" status="error">This number is outside the allowable range for 8-bit signed integers</Expects>
//<Expects id="FS1145" status="error">This number is outside the allowable range for 16-bit signed integers</Expects>
//<Expects id="FS1147" status="error">This number is outside the allowable range for 32-bit signed integers</Expects>
//<Expects id="FS1149" status="error">This number is outside the allowable range for 64-bit signed integers</Expects>

//<Expects id="FS1142" status="error">This number is outside the allowable range for 8-bit signed integers</Expects>
//<Expects id="FS1145" status="error">This number is outside the allowable range for 16-bit signed integers</Expects>
//<Expects id="FS1147" status="error">This number is outside the allowable range for 32-bit signed integers</Expects>
//<Expects id="FS1149" status="error">This number is outside the allowable range for 64-bit signed integers</Expects>


let minByteOct = -0o201y
let maxByteOct = 0o200y

let minInt16Oct = -0o100_001s
let maxInt16Oct = 0o100_000s

let minInt32Oct = -0o20_000_000_001
let maxInt32Oct = 0o20_000_000_000

let minInt64Oct = -0o1_000_000_000_000_000_000_001L
let maxInt64Oct = 0o1_000_000_000_000_000_000_000L

0 comments on commit 14dc98d

Please sign in to comment.