refactor: simplify iterator.Try and remove unnecessary backtracking
Simplify Try to save/restore the index directly instead of copying and syncing the entire iterator. Remove the now-unused Copy and Sync methods. Rewrite ScanRune and ParseRawToken as peek-then-advance so they no longer need Try at all. Remove redundant Try wrappers from parse functions that are already disambiguated by their callers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,17 +8,18 @@ import (
|
||||
|
||||
// ParseRawToken consumes the next token from the iterator if its type matches
|
||||
// the expected type.
|
||||
// Uses [iterator.Try] for automatic backtracking on failure.
|
||||
// Returns an error if the iterator is exhausted or the token type does not
|
||||
// match.
|
||||
func ParseRawToken[T Type](i *iterator.Iterator[Token[T]], expected T) (*Token[T], error) {
|
||||
return iterator.Try(i, func(i *iterator.Iterator[Token[T]]) (*Token[T], error) {
|
||||
if tok, err := i.Next(); err != nil {
|
||||
return nil, err
|
||||
} else if tok.Type != expected {
|
||||
return nil, fmt.Errorf("expected token %v, got %v'", expected.Name(), tok.Value)
|
||||
} else {
|
||||
return &tok, nil
|
||||
}
|
||||
})
|
||||
tok, err := i.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tok.Type != expected {
|
||||
return nil, fmt.Errorf("expected token %v, got %v'", expected.Name(), tok.Value)
|
||||
}
|
||||
i.Forward()
|
||||
return &tok, nil
|
||||
}
|
||||
|
||||
// ParseList repeatedly applies a parse function, collecting results into a
|
||||
|
||||
@@ -17,15 +17,15 @@ func IsVariable(r rune) bool {
|
||||
// predicate.
|
||||
// Returns an error if the iterator is exhausted or the rune does not match.
|
||||
func ScanRune(i *iterator.Iterator[rune], expected func(rune) bool) (rune, error) {
|
||||
return iterator.Try(i, func(i *iterator.Iterator[rune]) (rune, error) {
|
||||
if r, err := i.Next(); err != nil {
|
||||
return r, err
|
||||
} else if !expected(r) {
|
||||
return r, fmt.Errorf("got unexpected rune %v'", r)
|
||||
} else {
|
||||
return r, nil
|
||||
}
|
||||
})
|
||||
r, err := i.Get()
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
if !expected(r) {
|
||||
return r, fmt.Errorf("got unexpected rune %v'", r)
|
||||
}
|
||||
i.Forward()
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// ScanCharacter consumes the next rune from the iterator if it matches the
|
||||
|
||||
Reference in New Issue
Block a user