Skip to content

Commit

Permalink
Parse any BinaryFloatingPoint type (#177)
Browse files Browse the repository at this point in the history
* Parse any `BinaryFloatingPoint` type

* wip

* wip

* wip

* docs
  • Loading branch information
stephencelis authored Mar 7, 2022
1 parent 90d72eb commit 5189e0e
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 441 deletions.
63 changes: 0 additions & 63 deletions Sources/Parsing/Documentation.docc/Articles/Parsers/Double.md

This file was deleted.

39 changes: 21 additions & 18 deletions Sources/Parsing/Documentation.docc/Articles/Parsers/Float.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,65 @@
# Float

A parser that consumes a float from the beginning of a string.
A parser that consumes a floating-point number from the beginning of a string.

Parses the same format parsed by `Float.init(_:)`.
Supports any type that conforms to `BinaryFloatingPoint` and `LosslessStringConvertible`. This
includes `Double`, `Float`, `Float16`, and `Float80`.

Parses the same format parsed by `LosslessStringConvertible.init(_:)` on `BinaryFloatingPoint`.

```swift
var input = "123.45 Hello world"[...]
try Float.parser().parse(&input) // 123.45
try Double.parser().parse(&input) // 123.45
input // " Hello world"

input = "-123. Hello world"[...]
try Float.parser().parse(&input) // -123.0
try Double.parser().parse(&input) // -123.0
input // " Hello world"


input = "123.123E+2 Hello world"[...]
try Float.parser().parse(&input) // 12312.3
try Double.parser().parse(&input) // 12312.3
input // " Hello world"
```

The `Float.parser()` method is overloaded to work on a variety of string representations in order
The `parser()` static method is overloaded to work on a variety of string representations in order
to be as efficient as possible, including `Substring`, `UTF8View`, and generally collections of
UTF-8 code units (see <doc:StringAbstractions> for more info).

Typically Swift can choose the correct overload by using type inference based on what other parsers
you are combining `Float.parser()` with. For example, if you use `Float.parser()` with a
`Substring` parser, say the literal `","` parser (see <doc:String> for more information), Swift
will choose the overload that works on substrings:
you are combining `parser()` with. For example, if you use `Double.parser()` with a `Substring`
parser, say the literal `","` parser (see <doc:String> for more information), Swift will choose the
overload that works on substrings:

```swift
let parser = Parse {
Float.parser()
Double.parser()
","
Float.parser()
Double.parser()
}

try parser.parse("1,-2") // (1.0, -2.0)
```

On the other hand, if `Float.parser()` is used in a context where the input type cannot be inferred,
then you will get an compiler error:
On the other hand, if `Double.parser()` is used in a context where the input type cannot be
inferred, then you will get an compiler error:

```swift
let parser = Parse {
Float.parser()
Float.parser() // 🛑 Ambiguous use of 'parser(of:)'
Double.parser()
Double.parser() // 🛑 Ambiguous use of 'parser(of:)'
}

try parser.parse(".1.2")
```

To fix this you can force one of the float parsers to be the `Substring` parser, and then the
To fix this you can force one of the double parsers to be the `Substring` parser, and then the
other will figure it out via type inference:

```swift
let parser = Parse {
Float.parser(of: Substring.self)
Float.parser() //
Double.parser(of: Substring.self)
Double.parser() //
}

try parser.parse(".1.2") // (0.1, 0.2)
Expand Down
16 changes: 10 additions & 6 deletions Sources/Parsing/Documentation.docc/Articles/Parsers/Int.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# Int

A parser that consumes an integer (with an optional leading `+` or `-` sign) from the beginning of
a string.
A parser that consumes an integer from the beginning of a string.

Supports any type that conforms to `FixedWidthInteger`. This includes `Int`, `UInt`, `UInt8`, and
many more.

Parses the same format parsed by `FixedWidthInteger.init(_:radix:)`.

```swift
var input = "123 Hello world"[...]
Expand Down Expand Up @@ -36,14 +40,14 @@ let number = try Int.parser().parse(&input)
// | ^^^^^^^^^^^^^^^^^^^ overflowed 9223372036854775807
```

The `Int.parser()` method is overloaded to work on a variety of string representations in order
The static `parser()` method is overloaded to work on a variety of string representations in order
to be as efficient as possible, including `Substring`, `UTF8View`, and generally collections of
UTF-8 code units (see <doc:StringAbstractions> for more info).

Typically Swift can choose the correct overload by using type inference based on what other parsers
you are combining `Int.parser()` with. For example, if you use `Int.parser()` with a
`Substring` parser, say the literal `","` parser (see <doc:String> for more information), Swift
will choose the overload that works on substrings:
you are combining `parser()` with. For example, if you use `Int.parser()` with a `Substring` parser,
say the literal `","` parser (see <doc:String> for more information), Swift will choose the overload
that works on substrings:

```swift
let parser = Parse {
Expand Down
1 change: 0 additions & 1 deletion Sources/Parsing/Documentation.docc/Extensions/Parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ to build complex parsers from simpler pieces.
- <doc:Int>
- <doc:String>
- <doc:Bool>
- <doc:Double>
- <doc:Float>
- <doc:CharacterSet>
- <doc:UUID>
Expand Down
Loading

0 comments on commit 5189e0e

Please sign in to comment.