diff --git a/bind.go b/bind.go index c63ac65..f15131f 100644 --- a/bind.go +++ b/bind.go @@ -278,3 +278,421 @@ func Bind5[In, Out, T, T2, T3, T4, T5 any]( return Succeed(anyConsumed, val6, next, MessageOK(s.Pos())), nil } } + +// Bind6 is equivalent to 6 nested calls to Bind. +func Bind6[In, Out, T, T2, T3, T4, T5, T6 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, Out], +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := f(val)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := f2(val2)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := f3(val3)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := f4(val4)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := f5(val5)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := f6(val6)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + return Succeed(anyConsumed, val7, next, MessageOK(s.Pos())), nil + } +} + +// Bind7 is equivalent to 7 nested calls to Bind. +func Bind7[In, Out, T, T2, T3, T4, T5, T6, T7 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, T7], + f7 func(T7) Parser[In, Out], +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := f(val)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := f2(val2)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := f3(val3)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := f4(val4)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := f5(val5)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := f6(val6)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + r8, err := f7(val7)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r8.Consumed() + success, val8, next := r8.Status() + if !success { + return Fail[In, Out](anyConsumed, r8.Message()), nil + } + + return Succeed(anyConsumed, val8, next, MessageOK(s.Pos())), nil + } +} + +// Bind8 is equivalent to 8 nested calls to Bind. +func Bind8[In, Out, T, T2, T3, T4, T5, T6, T7, T8 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, T7], + f7 func(T7) Parser[In, T8], + f8 func(T8) Parser[In, Out], +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := f(val)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := f2(val2)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := f3(val3)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := f4(val4)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := f5(val5)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := f6(val6)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + r8, err := f7(val7)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r8.Consumed() + success, val8, next := r8.Status() + if !success { + return Fail[In, Out](anyConsumed, r8.Message()), nil + } + + r9, err := f8(val8)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r9.Consumed() + success, val9, next := r9.Status() + if !success { + return Fail[In, Out](anyConsumed, r9.Message()), nil + } + + return Succeed(anyConsumed, val9, next, MessageOK(s.Pos())), nil + } +} + +// Bind9 is equivalent to 9 nested calls to Bind. +func Bind9[In, Out, T, T2, T3, T4, T5, T6, T7, T8, T9 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, T7], + f7 func(T7) Parser[In, T8], + f8 func(T8) Parser[In, T9], + f9 func(T9) Parser[In, Out], +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := f(val)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := f2(val2)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := f3(val3)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := f4(val4)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := f5(val5)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := f6(val6)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + r8, err := f7(val7)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r8.Consumed() + success, val8, next := r8.Status() + if !success { + return Fail[In, Out](anyConsumed, r8.Message()), nil + } + + r9, err := f8(val8)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r9.Consumed() + success, val9, next := r9.Status() + if !success { + return Fail[In, Out](anyConsumed, r9.Message()), nil + } + + r10, err := f9(val9)(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r10.Consumed() + success, val10, next := r10.Status() + if !success { + return Fail[In, Out](anyConsumed, r10.Message()), nil + } + + return Succeed(anyConsumed, val10, next, MessageOK(s.Pos())), nil + } +} diff --git a/gigaparsec.go b/gigaparsec.go index 39e984b..7471db6 100644 --- a/gigaparsec.go +++ b/gigaparsec.go @@ -2,7 +2,7 @@ package gigaparsec -//go:generate go run ./internal/bindgen -bindpath bind.go -seqpath seq.go -max 5 -pkg gigaparsec +//go:generate go run ./internal/bindgen -bindpath bind.go -seqpath seq.go -max 9 -pkg gigaparsec import ( "errors" "fmt" diff --git a/naive.go b/naive.go new file mode 100644 index 0000000..bf70903 --- /dev/null +++ b/naive.go @@ -0,0 +1,86 @@ +package gigaparsec + +func Bind2Naïve[In, Out, T, T2 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(p, f), f2) +} +func Bind3Naïve[In, Out, T, T2, T3, T4, T5, T6, T7, T8, T9 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(p, f), f2), f3) +} +func Bind4Naïve[In, Out, T, T2, T3, T4 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(Bind(p, f), f2), f3), f4) +} +func Bind5Naïve[In, Out, T, T2, T3, T4, T5 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(Bind(Bind(p, f), f2), f3), f4), f5) +} +func Bind6Naïve[In, Out, T, T2, T3, T4, T5, T6 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(Bind(Bind(Bind(p, f), f2), f3), f4), f5), f6) +} +func Bind7Naïve[In, Out, T, T2, T3, T4, T5, T6, T7 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, T7], + f7 func(T7) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(Bind(Bind(Bind(Bind(p, f), f2), f3), f4), f5), f6), f7) +} +func Bind8Naïve[In, Out, T, T2, T3, T4, T5, T6, T7, T8 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, T7], + f7 func(T7) Parser[In, T8], + f8 func(T8) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(Bind(Bind(Bind(Bind(Bind(p, f), f2), f3), f4), f5), f6), f7), f8) +} +func Bind9Naïve[In, Out, T, T2, T3, T4, T5, T6, T7, T8, T9 any]( + p Parser[In, T], + f func(T) Parser[In, T2], + f2 func(T2) Parser[In, T3], + f3 func(T3) Parser[In, T4], + f4 func(T4) Parser[In, T5], + f5 func(T5) Parser[In, T6], + f6 func(T6) Parser[In, T7], + f7 func(T7) Parser[In, T8], + f8 func(T8) Parser[In, T9], + f9 func(T9) Parser[In, Out], +) Parser[In, Out] { + return Bind(Bind(Bind(Bind(Bind(Bind(Bind(Bind(Bind(p, f), f2), f3), f4), f5), f6), f7), f8), f9) +} diff --git a/naïve_test.go b/naïve_test.go new file mode 100644 index 0000000..7594bf1 --- /dev/null +++ b/naïve_test.go @@ -0,0 +1,55 @@ +package gigaparsec_test + +import ( + "testing" + + "git.codemonkeysoftware.net/b/gigaparsec" +) + +func BenchmarkBind5(b *testing.B) { + type Bind5T = func(p gigaparsec.Parser[byte, byte], f func(byte) gigaparsec.Parser[byte, byte], f2 func(byte) gigaparsec.Parser[byte, byte], f3 func(byte) gigaparsec.Parser[byte, byte], f4 func(byte) gigaparsec.Parser[byte, byte], f5 func(byte) gigaparsec.Parser[byte, byte]) gigaparsec.Parser[byte, byte] + + f := func(b byte) gigaparsec.Parser[byte, byte] { + return gigaparsec.Return[byte](b + 1) + } + p := func(bind5 Bind5T) gigaparsec.Parser[byte, byte] { + // gigaparsec.Bind5() + return bind5(gigaparsec.Match(byte(0)), f, f, f, f, f) + } + input := gigaparsec.SliceReaderAt[byte]{0} + b.Run("Bind5", func(b *testing.B) { + for range b.N { + gigaparsec.Run(p(gigaparsec.Bind5), input) + } + + }) + b.Run("Bind5Naïve", func(b *testing.B) { + for range b.N { + gigaparsec.Run(p(gigaparsec.Bind5Naïve), input) + } + }) +} + +func BenchmarkBind9(b *testing.B) { + type Bind9T = func(p gigaparsec.Parser[byte, byte], f func(byte) gigaparsec.Parser[byte, byte], f2 func(byte) gigaparsec.Parser[byte, byte], f3 func(byte) gigaparsec.Parser[byte, byte], f4 func(byte) gigaparsec.Parser[byte, byte], f5 func(byte) gigaparsec.Parser[byte, byte], f6 func(byte) gigaparsec.Parser[byte, byte], f7 func(byte) gigaparsec.Parser[byte, byte], f8 func(byte) gigaparsec.Parser[byte, byte], f9 func(byte) gigaparsec.Parser[byte, byte]) gigaparsec.Parser[byte, byte] + + f := func(b byte) gigaparsec.Parser[byte, byte] { + return gigaparsec.Return[byte](b + 1) + } + p := func(bind5 Bind9T) gigaparsec.Parser[byte, byte] { + // gigaparsec.Bind5() + return bind5(gigaparsec.Match(byte(0)), f, f, f, f, f, f, f, f, f) + } + input := gigaparsec.SliceReaderAt[byte]{0} + b.Run("Bind9", func(b *testing.B) { + for range b.N { + gigaparsec.Run(p(gigaparsec.Bind9), input) + } + + }) + b.Run("Bind9Naïve", func(b *testing.B) { + for range b.N { + gigaparsec.Run(p(gigaparsec.Bind9Naïve), input) + } + }) +} diff --git a/seq.go b/seq.go index 546ffbe..27c8ccd 100644 --- a/seq.go +++ b/seq.go @@ -205,3 +205,381 @@ func Seq5[In, Out, T, T2, T3, T4, T5 any]( return Succeed(anyConsumed, final, next, MessageOK(s.Pos())), nil } } + +func Seq6[In, Out, T, T2, T3, T4, T5, T6 any]( + p Parser[In, T], + p2 Parser[In, T2], + p3 Parser[In, T3], + p4 Parser[In, T4], + p5 Parser[In, T5], + p6 Parser[In, T6], + f func(T, T2, T3, T4, T5, T6) Out, +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := p2(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := p3(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := p4(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := p5(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := p6(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + final := f(val, val2, val3, val4, val5, val6) + return Succeed(anyConsumed, final, next, MessageOK(s.Pos())), nil + } +} + +func Seq7[In, Out, T, T2, T3, T4, T5, T6, T7 any]( + p Parser[In, T], + p2 Parser[In, T2], + p3 Parser[In, T3], + p4 Parser[In, T4], + p5 Parser[In, T5], + p6 Parser[In, T6], + p7 Parser[In, T7], + f func(T, T2, T3, T4, T5, T6, T7) Out, +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := p2(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := p3(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := p4(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := p5(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := p6(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := p7(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + final := f(val, val2, val3, val4, val5, val6, val7) + return Succeed(anyConsumed, final, next, MessageOK(s.Pos())), nil + } +} + +func Seq8[In, Out, T, T2, T3, T4, T5, T6, T7, T8 any]( + p Parser[In, T], + p2 Parser[In, T2], + p3 Parser[In, T3], + p4 Parser[In, T4], + p5 Parser[In, T5], + p6 Parser[In, T6], + p7 Parser[In, T7], + p8 Parser[In, T8], + f func(T, T2, T3, T4, T5, T6, T7, T8) Out, +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := p2(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := p3(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := p4(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := p5(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := p6(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := p7(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + r8, err := p8(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r8.Consumed() + success, val8, next := r8.Status() + if !success { + return Fail[In, Out](anyConsumed, r8.Message()), nil + } + + final := f(val, val2, val3, val4, val5, val6, val7, val8) + return Succeed(anyConsumed, final, next, MessageOK(s.Pos())), nil + } +} + +func Seq9[In, Out, T, T2, T3, T4, T5, T6, T7, T8, T9 any]( + p Parser[In, T], + p2 Parser[In, T2], + p3 Parser[In, T3], + p4 Parser[In, T4], + p5 Parser[In, T5], + p6 Parser[In, T6], + p7 Parser[In, T7], + p8 Parser[In, T8], + p9 Parser[In, T9], + f func(T, T2, T3, T4, T5, T6, T7, T8, T9) Out, +) Parser[In, Out] { + return func(s State[In]) (Result[In, Out], error) { + var anyConsumed bool + var next = s + + r, err := p(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r.Consumed() + success, val, next := r.Status() + if !success { + return Fail[In, Out](anyConsumed, r.Message()), nil + } + + r2, err := p2(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r2.Consumed() + success, val2, next := r2.Status() + if !success { + return Fail[In, Out](anyConsumed, r2.Message()), nil + } + + r3, err := p3(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r3.Consumed() + success, val3, next := r3.Status() + if !success { + return Fail[In, Out](anyConsumed, r3.Message()), nil + } + + r4, err := p4(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r4.Consumed() + success, val4, next := r4.Status() + if !success { + return Fail[In, Out](anyConsumed, r4.Message()), nil + } + + r5, err := p5(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r5.Consumed() + success, val5, next := r5.Status() + if !success { + return Fail[In, Out](anyConsumed, r5.Message()), nil + } + + r6, err := p6(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r6.Consumed() + success, val6, next := r6.Status() + if !success { + return Fail[In, Out](anyConsumed, r6.Message()), nil + } + + r7, err := p7(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r7.Consumed() + success, val7, next := r7.Status() + if !success { + return Fail[In, Out](anyConsumed, r7.Message()), nil + } + + r8, err := p8(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r8.Consumed() + success, val8, next := r8.Status() + if !success { + return Fail[In, Out](anyConsumed, r8.Message()), nil + } + + r9, err := p9(next) + if err != nil { + return Result[In, Out]{}, err + } + anyConsumed = anyConsumed || r9.Consumed() + success, val9, next := r9.Status() + if !success { + return Fail[In, Out](anyConsumed, r9.Message()), nil + } + + final := f(val, val2, val3, val4, val5, val6, val7, val8, val9) + return Succeed(anyConsumed, final, next, MessageOK(s.Pos())), nil + } +}