package token import ( "fmt" "git.maximhutz.com/max/lambda/pkg/iterator" ) // ParseRawToken consumes the next token from the iterator if its type matches // the expected type. // 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) { 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 // slice. // Stops when the parse function returns an error. // Returns an error if fewer than minimum results are collected. func ParseList[T Type, U any](i *iterator.Iterator[Token[T]], fn func(*iterator.Iterator[Token[T]]) (U, error), minimum int) ([]U, error) { results := []U{} for { if u, err := fn(i); err != nil { if len(results) < minimum { return nil, fmt.Errorf("expected at least '%v' items, got only '%v': %w", minimum, len(results), err) } return results, nil } else { results = append(results, u) } } }