@@ -27,29 +27,31 @@ open System.Text
27
27
// A string prefixed by four spaces will be replaced in the future with
28
28
// a ReadOnlySpan of characters.
29
29
30
+ [<CompiledName( " UnsignedIntRegex" ) >]
30
31
/// A `Regex` that recognizes a series of decimal digits.
31
32
/// Leading zeros are accepted.
32
33
// Seriously though, why not? Looking at you, JSON!
33
- let unsignedRegex = Number |> chars |> atLeast 1
34
+ let unsignedIntRegex = Number |> chars |> atLeast 1
34
35
35
- [<CompiledName( " FSharpOnlyGenericUnsigned" ); RequiresExplicitTypeArguments>]
36
+ [<CompiledName( " FSharpOnlyGenericUnsigned" ); RequiresExplicitTypeArguments; NoDynamicInvocation >]
36
37
/// Creates a designtimeFarkle that parses an unsigned decimal integer
37
38
/// into the desired number type. No bounds checking is performed.
38
39
/// Using this function from a language other than F# will throw an exception.
39
40
let inline genericUnsigned < ^TInt when ^TInt : ( static member Parse : string * NumberStyles * IFormatProvider -> ^TInt )> name =
40
41
terminal name
41
42
( T ( fun _ x ->
42
43
( ^TInt : ( static member Parse : string * NumberStyles * IFormatProvider -> ^TInt )
43
- ( x.ToString(), NumberStyles.Integer , NumberFormatInfo.InvariantInfo))))
44
- unsignedRegex
44
+ ( x.ToString(), NumberStyles.None , NumberFormatInfo.InvariantInfo))))
45
+ unsignedIntRegex
45
46
47
+ [<CompiledName( " SignedIntRegex" ) >]
46
48
/// A `Regex` that recognizes a series of decimal digits
47
49
/// that might be prefixed with a minus sign "-".
48
50
/// Leading zeros are accepted.
49
- let signedRegex = ( optional <| char '-' ) <&> unsignedRegex
51
+ let signedIntRegex = ( optional <| char '-' ) <&> unsignedIntRegex
50
52
51
- [<CompiledName( " FSharpOnlyGenericSigned" ); RequiresExplicitTypeArguments>]
52
- /// Creates a designtimeFarkle that parses a signed decimal integer
53
+ [<CompiledName( " FSharpOnlyGenericSigned" ); RequiresExplicitTypeArguments; NoDynamicInvocation >]
54
+ /// Creates a designtime Farkle that parses a signed decimal integer
53
55
/// into the desired number type. No bounds checking is performed.
54
56
/// The type parameter must support the unary negation operator.
55
57
/// Using this function from a language other than F# will throw an exception.
@@ -58,7 +60,7 @@ let inline genericSigned< ^TInt when ^TInt: (static member Parse: string * Nu
58
60
( T ( fun _ x ->
59
61
( ^TInt : ( static member Parse : string * NumberStyles * IFormatProvider -> ^TInt )
60
62
( x.ToString(), NumberStyles.Integer, NumberFormatInfo.InvariantInfo))))
61
- signedRegex
63
+ signedIntRegex
62
64
63
65
/// Creates a designtime Farkle that parses and returns a
64
66
/// signed 32-bit signed integer. No bounds checking is performed.
@@ -80,12 +82,17 @@ let uint32 name = genericUnsigned<uint32> name
80
82
/// signed 64-bit unsigned integer. No bounds checking is performed.
81
83
let uint64 name = genericUnsigned< uint64> name
82
84
83
- let private realRegex =
85
+ [<CompiledName( " UnsignedRealRegex" ) >]
86
+ /// A `Regex` that recognizes an unsigned real number.
87
+ /// The number is expected to be written in scientific
88
+ /// notation, with the decimal point symbol being the dot.
89
+ /// Numbers before or after the dot are optional, but they
90
+ /// must exist in at least one of the two places.
91
+ let unsignedRealRegex =
84
92
let numberStar = chars Number |> star
85
93
let atLeastOneNumber = chars Number <&> numberStar
86
94
let dotOptional = char '.' |> optional
87
95
concat [
88
- optional <| char '-'
89
96
choice [
90
97
// There has to be at least one digit
91
98
// either before or after the dot.
@@ -98,37 +105,49 @@ let private realRegex =
98
105
|> optional
99
106
]
100
107
101
- [<RequiresExplicitTypeArguments>]
102
- // We have exhausted all the cases, so let's make it private.
103
- let inline private genericReal < ^TReal when ^TReal : ( static member Parse : string * NumberStyles * IFormatProvider -> ^TReal )> name =
108
+ [<CompiledName( " SignedRealRegex" ) >]
109
+ /// Like `unsignedRealRegex`, but with an optional
110
+ /// sign in the beginning being allowed.
111
+ let signedRealRegex = ( optional <| char '-' ) <&> unsignedRealRegex
112
+
113
+ [<CompiledName( " FSharpOnlyGenericReal" ); RequiresExplicitTypeArguments; NoDynamicInvocation>]
114
+ /// Creates a designtime Farkle that parses a real number
115
+ /// into the desired number type. No bounds checking is performed.
116
+ /// Using this function from a language other than F# will throw an exception.
117
+ let inline genericReal < ^TReal when ^TReal : ( static member Parse : string * NumberStyles * IFormatProvider -> ^TReal )> allowSign name =
118
+ let regex =
119
+ if allowSign then
120
+ signedRealRegex
121
+ else
122
+ unsignedRealRegex
104
123
terminal name
105
124
( T ( fun _ x ->
106
125
( ^TReal : ( static member Parse : string * NumberStyles * IFormatProvider -> ^TReal )
107
- ( x.ToString(), NumberStyles.AllowExponent ||| NumberStyles. Float, NumberFormatInfo.InvariantInfo))))
108
- realRegex
126
+ ( x.ToString(), NumberStyles.Float, NumberFormatInfo.InvariantInfo))))
127
+ regex
109
128
110
129
[<CompiledName( " Single" ) >]
111
130
/// Creates a designtime Farkle that parses and returns
112
- /// a single-precision floating-point number. The number
131
+ /// a signed single-precision floating-point number. The number
113
132
/// is expected to be written in scientific notation, with
114
133
/// the decimal point symbol being the dot. Special values
115
134
/// such as NaN or infinity are not recognized.
116
- let float32 name = genericReal< float32> name
135
+ let float32 name = genericReal< float32> true name
117
136
118
137
[<CompiledName( " Double" ) >]
119
138
/// Creates a designtime Farkle that parses and returns
120
- /// a single -precision floating-point number. The number
139
+ /// a signed double -precision floating-point number. The number
121
140
/// is expected to be written in scientific notation, with
122
141
/// the decimal point symbol being the dot. Special values
123
142
/// such as NaN or infinity are not recognized.
124
- let float name = genericReal< float> name
143
+ let float name = genericReal< float> true name
125
144
126
145
[<CompiledName( " Decimal" ) >]
127
146
/// Creates a designtime Farkle that parses and returns
128
- /// a single-precision floating-point number. The number
147
+ /// a signed decimal floating-point number. The number
129
148
/// is expected to be written in scientific notation, with
130
149
/// the decimal point symbol being the dot.
131
- let decimal name = genericReal< decimal> name
150
+ let decimal name = genericReal< decimal> true name
132
151
133
152
let private stringTransformer = T ( fun _ span ->
134
153
let span = span.Slice( 1 , span.Length - 2 )
0 commit comments