diff --git a/TODO.txt b/TODO.txt index c0c7e02..2dfb4c5 100644 --- a/TODO.txt +++ b/TODO.txt @@ -2,3 +2,4 @@ Test RuneReader Test Regexp Add SPDX tags What's Megaparsec got that we ain't got? +Add Do parser that runs an action on the result of the previous parser. diff --git a/gigaparsec.go b/gigaparsec.go index e07bd31..051f174 100644 --- a/gigaparsec.go +++ b/gigaparsec.go @@ -125,6 +125,20 @@ func (s State[In]) At(pos uint64) State[In] { type Parser[In, Out any] func(State[In]) (Result[In, Out], error) +func (p Parser[In, Out]) Label(label string) Parser[In, Out] { + return func(input State[In]) (Result[In, Out], error) { + result, err := p(input) + if err != nil || result.Consumed() { + return result, err + } + if succeeded, _, value, next, msg := result.Succeeded(); succeeded { + return Succeed(false, value, next, msg.expect(label)), nil + } + _, _, msg := result.Failed() + return Fail[In, Out](false, msg.expect(label)), nil + } +} + func Return[In, Out any](value Out) Parser[In, Out] { return func(state State[In]) (Result[In, Out], error) { return Succeed(false, value, state, MessageOK(state.Pos())), nil @@ -246,20 +260,6 @@ func Try[In, Out any](p Parser[In, Out]) Parser[In, Out] { } } -func Label[In, Out any](p Parser[In, Out], l string) Parser[In, Out] { - return func(input State[In]) (Result[In, Out], error) { - result, err := p(input) - if err != nil || result.Consumed() { - return result, err - } - if succeeded, _, value, next, msg := result.Succeeded(); succeeded { - return Succeed(false, value, next, msg.expect(l)), nil - } - _, _, msg := result.Failed() - return Fail[In, Out](false, msg.expect(l)), nil - } -} - func Map[In, Out1, Out2 any](p Parser[In, Out1], f func(Out1) Out2) Parser[In, Out2] { return Bind(p, func(out Out1) Parser[In, Out2] { return Return[In](f(out))