From b09a14147d397904722ee7c25e4defc56135b96f Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 9 May 2022 00:01:02 +0200 Subject: Extract source walk part of scanner --- pkg/libs/source/walker.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 pkg/libs/source/walker.go (limited to 'pkg/libs/source/walker.go') diff --git a/pkg/libs/source/walker.go b/pkg/libs/source/walker.go new file mode 100644 index 0000000..aeac82a --- /dev/null +++ b/pkg/libs/source/walker.go @@ -0,0 +1,80 @@ +package source + +import ( + "bufio" + "errors" + "io" +) + +type Walker struct { + source *bufio.Reader + + row int + col int +} + +func NewWalker(source io.Reader) *Walker { + return &Walker{ + source: bufio.NewReader(source), + row: 0, + col: 0, + } +} + +func (w *Walker) Loc() Loc { + return Loc{ + Row: w.row, + Col: w.col, + } +} + +func (w *Walker) Next() (rune, bool, error) { + r, _, err := w.source.ReadRune() + if err != nil { + if errors.Is(err, io.EOF) { + return 0, true, nil + } + + return 0, false, err + } + + if r == '\n' { + w.row++ + w.col = 0 + } else { + w.col++ + } + + return r, false, nil +} + +func (w *Walker) Consume(want rune) (bool, error) { + c, _, err := w.Next() + if err != nil { + return false, err + } + + if c != want { + return true, ErrUnexpectedChar{ + Expected: want, + Actual: c, + } + } + + return true, nil +} + +func (w *Walker) Peek() (rune, bool, error) { + r, _, err := w.source.ReadRune() + defer w.source.UnreadRune() + + if err != nil { + if errors.Is(err, io.EOF) { + return 0, true, nil + } + + return 0, false, err + } + + return r, false, nil +} -- cgit 1.4.1