Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions src/fsharp/FSharp.Core/prim-types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2504,10 +2504,15 @@ namespace Microsoft.FSharp.Core
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
| s -> s.Replace("_", "")

let ParseUInt32 (s:string) =
if System.Object.ReferenceEquals(s,null) then
raise( new System.ArgumentNullException("s") )
let s = s.Trim()
let s = removeUnderscores (s.Trim())
let l = s.Length
let mutable p = 0
let specifier = get0OXB s &p l
Expand All @@ -2524,7 +2529,7 @@ namespace Microsoft.FSharp.Core
let ParseInt32 (s:string) =
if System.Object.ReferenceEquals(s,null) then
raise( new System.ArgumentNullException("s") )
let s = s.Trim()
let s = removeUnderscores (s.Trim())
let l = s.Length
let mutable p = 0
let sign = getSign32 s &p l
Expand All @@ -2543,7 +2548,7 @@ namespace Microsoft.FSharp.Core
let ParseInt64 (s:string) =
if System.Object.ReferenceEquals(s,null) then
raise( new System.ArgumentNullException("s") )
let s = s.Trim()
let s = removeUnderscores (s.Trim())
let l = s.Length
let mutable p = 0
let sign = getSign64 s &p l
Expand All @@ -2562,7 +2567,7 @@ namespace Microsoft.FSharp.Core
let ParseUInt64 (s:string) : uint64 =
if System.Object.ReferenceEquals(s,null) then
raise( new System.ArgumentNullException("s") )
let s = s.Trim()
let s = removeUnderscores (s.Trim())
let l = s.Length
let mutable p = 0
let specifier = get0OXB s &p l
Expand Down Expand Up @@ -4144,8 +4149,8 @@ namespace Microsoft.FSharp.Core
let inline ParseUInt16 (s:string) = (# "conv.ovf.u2" (ParseUInt32 s) : uint16 #)
let inline ParseIntPtr (s:string) = (# "conv.ovf.i" (ParseInt64 s) : nativeint #)
let inline ParseUIntPtr (s:string) = (# "conv.ovf.u" (ParseInt64 s) : unativeint #)
let inline ParseDouble (s:string) = Double.Parse(s,NumberStyles.Float, CultureInfo.InvariantCulture)
let inline ParseSingle (s:string) = Single.Parse(s,NumberStyles.Float, CultureInfo.InvariantCulture)
let inline ParseDouble (s:string) = Double.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)
let inline ParseSingle (s:string) = Single.Parse(removeUnderscores s,NumberStyles.Float, CultureInfo.InvariantCulture)


[<NoDynamicInvocation>]
Expand Down
19 changes: 13 additions & 6 deletions src/fsharp/lex.fsl
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,13 @@ 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
| s -> s.Replace("_", "")

let parseInt32 (s:string) =
let s = removeUnderscores s
let l = s.Length
let mutable p = 0
let sign = getSign32 s &p l
Expand Down Expand Up @@ -175,11 +181,12 @@ let anychar = [^'\n''\r']
let anystring = anychar*
let op_char = '!'|'$'|'%'|'&'|'*'|'+'|'-'|'.'|'/'|'<'|'='|'>'|'?'|'@'|'^'|'|'|'~'|':'
let ignored_op_char = '.' | '$' | '?'
let separator = '_'
let xinteger =
( '0' ('x'| 'X') hex +
| '0' ('o'| 'O') (['0'-'7']) +
| '0' ('b'| 'B') (['0'-'1']) + )
let integer = digit+
( '0' ('x'| 'X') hex ((hex | separator)* hex)?
| '0' ('o'| 'O') (['0'-'7']) (((['0'-'7']) | separator)* (['0'-'7']))?
| '0' ('b'| 'B') (['0'-'1']) (((['0'-'1']) | separator)* (['0'-'1']))?)
let integer = digit ((digit | separator)* digit)?
let int8 = integer 'y'
let uint8 = (xinteger | integer) 'u' 'y'
let int16 = integer 's'
Expand All @@ -196,8 +203,8 @@ let xint8 = xinteger 'y'
let xint16 = xinteger 's'
let xint = xinteger
let xint32 = xinteger 'l'
let floatp = digit+ '.' digit*
let floate = digit+ ('.' digit* )? ('e'| 'E') ['+' '-']? digit+
let floatp = digit ((digit | separator)* digit)? '.' (digit (digit | separator)*)?
let floate = digit ((digit | separator)* digit)? ('.' (digit (digit | separator)*)? )? ('e'| 'E') ['+' '-']? digit (digit | separator)*
let float = floatp | floate
let bignum = integer ('I' | 'N' | 'Z' | 'Q' | 'R' | 'G')
let ieee64 = float
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,60 @@ let boolConst2 = false

let unitConst = ()

let creditCardNumber = 1234_5678_9012_3456L
if creditCardNumber <> 1234567890123456L then
failwith "Wrong parsing"

let socialSecurityNumber = 999_99_9999L
if socialSecurityNumber <> 999999999L then
failwith "Wrong parsing"

let pi = 3.14_15F
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spacing is odd

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's by design to test more interesting cases.

if pi <> 3.1415F then
failwith "Wrong parsing"

let hexBytes = 0xFF_EC_DE_5E
if hexBytes <> 0xFFECDE5E then
failwith "Wrong parsing"

let hexWords = 0xCAFE_BABE
if hexWords <> 0xCAFEBABE then
failwith "Wrong parsing"

let maxLong = 0x7fff_ffff_ffff_ffffL
if maxLong <> 0x7fffffffffffffffL then
failwith "Wrong parsing"

let nybbles = 0b0010_0101
if nybbles <> 0b00100101 then
failwith "Wrong parsing"

let bytes = 0b11010010_01101001_10010100_10010010
if bytes <> 0b11010010011010011001010010010010 then
failwith "Wrong parsing"

let x2 = 5_2
if x2 <> 52 then
failwith "Wrong parsing"

let x4 = 5_______2
if x4 <> 52 then
failwith "Wrong parsing"

let x7 = 0x5_2
if x7 <> 0x52 then
failwith "Wrong parsing"

let x9 = 0_52
if x9 <> 052 then
failwith "Wrong parsing"

let x10 = 05_2
if x10 <> 052 then
failwith "Wrong parsing"

let x14 = 0o5_2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need tests that show that the values are actually the expected constants.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right sorry done

if x14 <> 0o52 then
failwith "Wrong parsing"

exit 0