Skip to content

Commit

Permalink
Merge pull request #3 from drewolson/drop-combinator
Browse files Browse the repository at this point in the history
Add the drop combinator
  • Loading branch information
RyanBrewer317 authored Dec 12, 2024
2 parents a1465e7 + 12c2cae commit b22db7c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ jobs:
gleam-version: "1.0.0"
rebar3-version: "3"
# elixir-version: "1.15.4"
- run: gleam format --check src test
- run: gleam format --check
- run: gleam deps download
- run: gleam test
26 changes: 20 additions & 6 deletions src/party.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import gleam/result
import gleam/string

/// The custom error type for the parser,
/// The custom error type for the parser,
/// which can itself be parameterized by a user-defined error type.
/// The user-defined error type is useful for, for example,
/// The user-defined error type is useful for, for example,
/// adding a `int.parse` call into your parser pipeline.
/// See `try` for using this feature.
pub type ParseError(e) {
Expand All @@ -23,7 +23,7 @@ pub type Position {
Position(row: Int, col: Int)
}

/// The parser type, parameterized by the type it parses and
/// The parser type, parameterized by the type it parses and
/// the user-defined error type it can return.
pub opaque type Parser(a, e) {
Parser(
Expand Down Expand Up @@ -221,6 +221,20 @@ pub fn seq(p: Parser(a, e), q: Parser(b, e)) -> Parser(b, e) {
q
}

/// A version of `seq` for pleasant interplay with gleam's `use` syntax.
/// example:
/// ```
/// fn pair() -> Parser(#(String, String), e) {
/// use a <- do(alphanum())
/// use <- drop(char(","))
/// use b <- do(alphanum())
/// return(#(a, b))
/// }
/// ```
pub fn drop(p: Parser(a, e), f: fn() -> Parser(b, e)) -> Parser(b, e) {
seq(p, lazy(f))
}

/// Parse a sequence separated by the given separator parser.
pub fn sep(parser: Parser(a, e), by s: Parser(b, e)) -> Parser(List(a), e) {
use res <- do(perhaps(sep1(parser, by: s)))
Expand Down Expand Up @@ -249,7 +263,7 @@ pub fn map(p: Parser(a, e), f: fn(a) -> b) -> Parser(b, e) {
}

/// Do `p`, the apply `f` to the result if it succeeded.
/// `f` itself can fail with the user-defined error type,
/// `f` itself can fail with the user-defined error type,
/// and if it does the result is a `UserError` with the error.
pub fn try(p: Parser(a, e), f: fn(a) -> Result(b, e)) -> Parser(b, e) {
Parser(fn(source, pos) {
Expand All @@ -264,7 +278,7 @@ pub fn try(p: Parser(a, e), f: fn(a) -> Result(b, e)) -> Parser(b, e) {
})
}

/// Transform the user-defined error type
/// Transform the user-defined error type
/// with a user-provided conversion function.
pub fn error_map(p: Parser(a, e), f: fn(e) -> f) -> Parser(a, f) {
Parser(fn(source, pos) {
Expand Down Expand Up @@ -348,7 +362,7 @@ pub fn lazy(p: fn() -> Parser(a, e)) -> Parser(a, e) {
}

/// A monadic bind for pleasant interplay with gleam's `use` syntax.
/// example:
/// example:
/// ```
/// fn identifier() -> Parser(String, e) {
/// use pos <- do(pos())
Expand Down
10 changes: 10 additions & 0 deletions test/party_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,16 @@ pub fn do_return_test() {
|> should.equal(Ok("aa"))
}

pub fn do_drop_return_test() {
{
use a <- party.do(party.char("a"))
use <- party.drop(party.char("*"))
party.return(a <> a)
}
|> party.go("a*")
|> should.equal(Ok("aa"))
}

pub fn fail_test() {
party.go(party.fail(), "a")
|> should.equal(Error(party.Unexpected(party.Position(1, 1), "a")))
Expand Down

0 comments on commit b22db7c

Please sign in to comment.