diff --git a/pkg/iterator/iterator.go b/pkg/iterator/iterator.go index cf98056..d7504d8 100644 --- a/pkg/iterator/iterator.go +++ b/pkg/iterator/iterator.go @@ -81,6 +81,17 @@ func (i Iterator[T]) Done() bool { return i.index == len(i.items) } +// While increments the iterator as long as the current item satisfies the +// predicate. The first item that does not match is left unconsumed. +func (i *Iterator[T]) While(fn func(T) bool) { + for !i.Done() { + if !fn(i.MustGet()) { + return + } + i.Forward() + } +} + // Try attempts to perform an operation using the iterator. If the operation // succeeds, the iterator is updated. If the operation fails, the iterator is // rolled back, and an error is returned. diff --git a/pkg/saccharine/scan.go b/pkg/saccharine/scan.go index a89733a..fd79d39 100644 --- a/pkg/saccharine/scan.go +++ b/pkg/saccharine/scan.go @@ -47,18 +47,7 @@ func scanToken(i *iterator.Iterator[rune]) (*Token, error) { return token.New(TokenHardBreak, index), nil case letter == '#': // Skip everything until the next newline or EOF. - for !i.Done() { - r, err := i.Next() - if err != nil { - return nil, fmt.Errorf("error while parsing comment: %w", err) - } - - if r == '\n' { - // Put the newline back so it can be processed as a soft break. - i.Back() - break - } - } + i.While(func(r rune) bool { return r != '\n' }) return nil, nil case unicode.IsSpace(letter): return nil, nil