aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/source.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/syntax/source.go')
-rw-r--r--src/cmd/compile/internal/syntax/source.go32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/syntax/source.go b/src/cmd/compile/internal/syntax/source.go
index 9f00f1e87e..a04c089367 100644
--- a/src/cmd/compile/internal/syntax/source.go
+++ b/src/cmd/compile/internal/syntax/source.go
@@ -5,6 +5,7 @@
package syntax
import (
+ "fmt"
"io"
"unicode/utf8"
)
@@ -15,7 +16,8 @@ import (
// suf r0 r w
type source struct {
- src io.Reader
+ src io.Reader
+ errh ErrorHandler
// source buffer
buf [4 << 10]byte
@@ -29,8 +31,10 @@ type source struct {
suf int // literal suffix; suf >= 0 means we are scanning a literal
}
-func (s *source) init(src io.Reader) {
+func (s *source) init(src io.Reader, errh ErrorHandler) {
s.src = src
+ s.errh = errh
+
s.buf[0] = utf8.RuneSelf // terminate with sentinel
s.offs = 0
s.r0, s.r, s.w = 0, 0, 0
@@ -41,6 +45,18 @@ func (s *source) init(src io.Reader) {
s.suf = -1
}
+func (s *source) error(msg string) {
+ s.error_at(s.pos(), s.line, msg)
+}
+
+func (s *source) error_at(pos, line int, msg string) {
+ if s.errh != nil {
+ s.errh(pos, line, msg)
+ return
+ }
+ panic(fmt.Sprintf("%d: %s", line, msg))
+}
+
func (s *source) pos() int {
return s.offs + s.r
}
@@ -57,7 +73,7 @@ func (s *source) getr() rune {
if b := s.buf[s.r]; b < utf8.RuneSelf {
s.r++
if b == 0 {
- panic("invalid NUL character")
+ s.error("invalid NUL character")
continue
}
if b == '\n' {
@@ -73,7 +89,7 @@ func (s *source) getr() rune {
// BOM's are only allowed as the first character in a file
const BOM = 0xfeff
if r == BOM && s.r0 > 0 { // s.r0 is always > 0 after 1st character (fill will set it to 1)
- panic("invalid BOM in the middle of the file")
+ s.error("invalid BOM in the middle of the file")
continue
}
return r
@@ -81,14 +97,14 @@ func (s *source) getr() rune {
if w == 0 && s.err != nil {
if s.err != io.EOF {
- panic(s.err)
+ s.error(s.err.Error())
}
return -1
}
if w == 1 && (s.r+utf8.UTFMax <= s.w || utf8.FullRune(s.buf[s.r:s.w])) {
s.r++
- panic("invalid UTF-8 encoding")
+ s.error("invalid UTF-8 encoding")
continue
}
@@ -119,7 +135,7 @@ func (s *source) fill() {
for i := 100; i > 0; i-- {
n, err := s.src.Read(s.buf[s.w : len(s.buf)-1]) // -1 to leave space for sentinel
if n < 0 {
- panic("negative read")
+ s.error("negative read")
}
s.w += n
if n > 0 || err != nil {
@@ -131,7 +147,7 @@ func (s *source) fill() {
}
}
- panic("no progress")
+ s.error("no progress")
}
func (s *source) startLit() {