diff options
author | Robert Griesemer <gri@golang.org> | 2016-11-29 16:13:09 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2016-12-09 00:42:42 +0000 |
commit | 8d20b25779d4ce32e8eaeb52374fba1e74f7df57 (patch) | |
tree | 1dd10782d5b321986850604da0bc743789ee31b8 /src/cmd/compile/internal/syntax/source.go | |
parent | eaca0e0529b780f4c862a97aa47008aa1b403adf (diff) | |
download | go-8d20b25779d4ce32e8eaeb52374fba1e74f7df57.tar.gz go-8d20b25779d4ce32e8eaeb52374fba1e74f7df57.zip |
[dev.inline] cmd/compile/internal/syntax: introduce general position info for nodes
Reviewed in and cherry-picked from https://go-review.googlesource.com/#/c/33758/.
Minor adjustments in noder.go to fix merge.
Change-Id: Ibe429e327c7f8554f8ac205c61ce3738013aed98
Reviewed-on: https://go-review.googlesource.com/34231
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax/source.go')
-rw-r--r-- | src/cmd/compile/internal/syntax/source.go | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/syntax/source.go b/src/cmd/compile/internal/syntax/source.go index 05a11960c6..db161166ed 100644 --- a/src/cmd/compile/internal/syntax/source.go +++ b/src/cmd/compile/internal/syntax/source.go @@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// This file implements source, a buffered rune reader +// which is specialized for the needs of the Go scanner: +// Contiguous sequences of runes (literals) are extracted +// directly as []byte without the need to re-encode the +// runes in UTF-8 (as would be necessary with bufio.Reader). + package syntax import ( @@ -23,7 +29,8 @@ type source struct { buf [4 << 10]byte offs int // source offset of buf r0, r, w int // previous/current read and write buf positions, excluding sentinel - line0, line int // previous/current line + line0, line uint // previous/current line + col0, col uint // previous/current column err error // pending io error // literal buffer @@ -40,6 +47,7 @@ func (s *source) init(src io.Reader, errh ErrorHandler) { s.offs = 0 s.r0, s.r, s.w = 0, 0, 0 s.line0, s.line = 1, 1 + s.col0, s.col = 1, 1 s.err = nil s.lit = s.lit[:0] @@ -47,11 +55,11 @@ func (s *source) init(src io.Reader, errh ErrorHandler) { } func (s *source) error(msg string) { - s.error_at(s.pos0(), s.line0, msg) + s.error_at(s.line0, s.col0, msg) } -func (s *source) error_at(pos, line int, msg string) { - err := Error{pos, line, msg} +func (s *source) error_at(line, col uint, msg string) { + err := Error{line, col, msg} if s.first == nil { s.first = err } @@ -61,18 +69,24 @@ func (s *source) error_at(pos, line int, msg string) { s.errh(err) } -// pos0 returns the byte position of the last character read. -func (s *source) pos0() int { - return s.offs + s.r0 +// ungetr ungets the most recently read rune. +func (s *source) ungetr() { + s.r, s.line, s.col = s.r0, s.line0, s.col0 } -func (s *source) ungetr() { - s.r, s.line = s.r0, s.line0 +// ungetr2 is like ungetr but enables a 2nd ungetr. +// It must not be called if one of the runes seen +// was a newline. +func (s *source) ungetr2() { + s.ungetr() + // line must not have changed + s.r0-- + s.col0-- } func (s *source) getr() rune { redo: - s.r0, s.line0 = s.r, s.line + s.r0, s.line0, s.col0 = s.r, s.line, s.col // We could avoid at least one test that is always taken in the // for loop below by duplicating the common case code (ASCII) @@ -88,12 +102,14 @@ redo: // (invariant: s.buf[s.w] == utf8.RuneSelf) if b := s.buf[s.r]; b < utf8.RuneSelf { s.r++ + s.col++ if b == 0 { s.error("invalid NUL character") goto redo } if b == '\n' { s.line++ + s.col = 1 } return rune(b) } @@ -109,6 +125,7 @@ redo: // uncommon case: not ASCII r, w := utf8.DecodeRune(s.buf[s.r:s.w]) s.r += w + s.col++ if r == utf8.RuneError && w == 1 { s.error("invalid UTF-8 encoding") |