Skip to content

Commit

Permalink
Merge pull request #1243 from AviAvni/underscore-literals
Browse files Browse the repository at this point in the history
RFC FS-1005 - Underscore literals


@AviAvni 
Thank you for taking care of this
  • Loading branch information
KevinRansom authored Jun 9, 2016
2 parents a58efbf + 57a2fe9 commit bfc92fb
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 12 deletions.
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
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
if x14 <> 0o52 then
failwith "Wrong parsing"

exit 0

0 comments on commit bfc92fb

Please sign in to comment.