@@ -13,6 +13,11 @@ func Lex(source *file.Source) ([]Token, error) {
1313 input : source .Content (),
1414 tokens : make ([]Token , 0 ),
1515 }
16+
17+ l .loc = file.Location {1 , 0 }
18+ l .prev = l .loc
19+ l .startLoc = l .loc
20+
1621 for state := root ; state != nil ; {
1722 state = state (l )
1823 }
@@ -28,8 +33,10 @@ type lexer struct {
2833 input string
2934 state stateFn
3035 tokens []Token
31- start , end int // current position in input
32- width int // last rune with
36+ start , end int // current position in input
37+ width int // last rune with
38+ startLoc file.Location // start location
39+ prev , loc file.Location // prev location of end location, end location
3340 err * file.Error
3441}
3542
@@ -43,6 +50,15 @@ func (l *lexer) next() rune {
4350 r , w := utf8 .DecodeRuneInString (l .input [l .end :])
4451 l .width = w
4552 l .end += w
53+
54+ l .prev = l .loc
55+ if r == '\n' {
56+ l .loc .Line ++
57+ l .loc .Column = 0
58+ } else {
59+ l .loc .Column ++
60+ }
61+
4662 return r
4763}
4864
@@ -54,6 +70,7 @@ func (l *lexer) peek() rune {
5470
5571func (l * lexer ) backup () {
5672 l .end -= l .width
73+ l .loc = l .prev
5774}
5875
5976func (l * lexer ) emit (t Kind ) {
@@ -62,19 +79,21 @@ func (l *lexer) emit(t Kind) {
6279
6380func (l * lexer ) emitValue (t Kind , value string ) {
6481 l .tokens = append (l .tokens , Token {
65- Location : l .loc ( l . start ) ,
82+ Location : l .startLoc ,
6683 Kind : t ,
6784 Value : value ,
6885 })
6986 l .start = l .end
87+ l .startLoc = l .loc
7088}
7189
7290func (l * lexer ) emitEOF () {
7391 l .tokens = append (l .tokens , Token {
74- Location : l .loc ( l . start - 1 ) , // Point to previous position for better error messages.
92+ Location : l .prev , // Point to previous position for better error messages.
7593 Kind : EOF ,
7694 })
7795 l .start = l .end
96+ l .startLoc = l .loc
7897}
7998
8099func (l * lexer ) word () string {
@@ -83,6 +102,7 @@ func (l *lexer) word() string {
83102
84103func (l * lexer ) ignore () {
85104 l .start = l .end
105+ l .startLoc = l .loc
86106}
87107
88108func (l * lexer ) accept (valid string ) bool {
@@ -101,9 +121,13 @@ func (l *lexer) acceptRun(valid string) {
101121
102122func (l * lexer ) acceptWord (word string ) bool {
103123 pos := l .end
124+ loc := l .loc
125+ prev := l .prev
104126 for _ , ch := range word {
105127 if l .next () != ch {
106128 l .end = pos
129+ l .loc = loc
130+ l .prev = prev
107131 return false
108132 }
109133 }
@@ -113,32 +137,13 @@ func (l *lexer) acceptWord(word string) bool {
113137func (l * lexer ) error (format string , args ... interface {}) stateFn {
114138 if l .err == nil { // show first error
115139 l .err = & file.Error {
116- Location : l .loc ( l . end - 1 ) ,
140+ Location : l .loc ,
117141 Message : fmt .Sprintf (format , args ... ),
118142 }
119143 }
120144 return nil
121145}
122146
123- func (l * lexer ) loc (pos int ) file.Location {
124- line , column := 1 , 0
125- for i , ch := range []rune (l .input ) {
126- if i == pos {
127- break
128- }
129- if ch == '\n' {
130- line ++
131- column = 0
132- } else {
133- column ++
134- }
135- }
136- return file.Location {
137- Line : line ,
138- Column : column ,
139- }
140- }
141-
142147func digitVal (ch rune ) int {
143148 switch {
144149 case '0' <= ch && ch <= '9' :
0 commit comments