1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: use token.pos instead of token.col, calculate col when needed

This commit is contained in:
joe-conigliaro 2019-11-24 03:31:28 +11:00 committed by Alexander Medvednikov
parent f42be0622e
commit 666509623e
3 changed files with 15 additions and 37 deletions

View File

@ -208,44 +208,21 @@ fn (s mut Scanner) goto_scanner_position(scp ScannerPos) {
s.last_nl_pos = scp.last_nl_pos s.last_nl_pos = scp.last_nl_pos
} }
// get_scanner_pos_of_token rescans *the whole source* till it reaches {t.line_nr, t.col} . fn (s mut Scanner) get_last_nl_from_pos(pos int) int {
fn (s mut Scanner) get_scanner_pos_of_token(t &Token) ScannerPos { for i := pos; i >= 0; i-- {
// This rescanning is done just once on error, so it is fine for now. if s.text[i] == `\n` {
// Be careful for the performance implications, if you want to return i
// do it more frequently. The alternative would be to store
// the scanpos (12 bytes) for each token, and there are potentially many tokens.
tline := t.line_nr
tcol := if t.line_nr == 0 { t.col + 1 } else { t.col - 1 }
// save the current scanner position, it will be restored later
cpos := s.get_scanner_pos()
mut sptoken := ScannerPos{}
// Starting from the start, scan the source lines
// till the desired tline is reached, then
// s.pos + tcol would be the proper position
// of the token.
s.goto_scanner_position(ScannerPos{})
maxline := imin( s.nlines, tline + 2 * error_context_after)
for {
if s.pos >= s.text.len { break }
if s.line_nr > maxline { break }
////////////////////////////////////////
if tline == s.line_nr {
sptoken = s.get_scanner_pos()
sptoken.pos += tcol
} }
s.ignore_line() s.eat_single_newline()
} }
////////////////////////////////////////////////// return 0
s.goto_scanner_position(cpos)
return sptoken
} }
fn (s mut Scanner) eat_single_newline(){ fn (s mut Scanner) get_scanner_pos_of_token(tok &Token) ScannerPos {
if s.pos >= s.text.len { return } return ScannerPos{
if s.expect('\r\n', s.pos) { s.pos += 2 return } pos: tok.pos
if s.text[ s.pos ] == `\n` { s.pos ++ return } line_nr: tok.line_nr
if s.text[ s.pos ] == `\r` { s.pos ++ return } last_nl_pos: s.get_last_nl_from_pos(tok.pos)
}
} }
/////////////////////////////// ///////////////////////////////

View File

@ -188,7 +188,7 @@ fn (p mut Parser) scan_tokens() {
tok: res.tok tok: res.tok
lit: res.lit lit: res.lit
line_nr: p.scanner.line_nr line_nr: p.scanner.line_nr
col: p.scanner.pos - p.scanner.last_nl_pos pos: p.scanner.pos
} }
if res.tok == .eof { if res.tok == .eof {
break break
@ -2384,7 +2384,8 @@ fn (p mut Parser) array_init() string {
if is_integer && p.tok == .rsbr && p.peek() == .name && if is_integer && p.tok == .rsbr && p.peek() == .name &&
p.cur_tok().line_nr == p.peek_token().line_nr { p.cur_tok().line_nr == p.peek_token().line_nr {
// there is no space between `[10]` and `byte` // there is no space between `[10]` and `byte`
if p.cur_tok().col + p.peek_token().lit.len == p.peek_token().col { // if p.cur_tok().col + p.peek_token().lit.len == p.peek_token().col {
if p.cur_tok().pos + p.peek_token().lit.len == p.peek_token().pos {
p.check(.rsbr) p.check(.rsbr)
array_elem_typ := p.get_type() array_elem_typ := p.get_type()
if !p.table.known_type(array_elem_typ) { if !p.table.known_type(array_elem_typ) {

View File

@ -9,7 +9,7 @@ struct Token {
lit string // literal representation of the token lit string // literal representation of the token
line_nr int // the line number in the source where the token occured line_nr int // the line number in the source where the token occured
name_idx int // name table index for O(1) lookup name_idx int // name table index for O(1) lookup
col int // the column where the token ends pos int // the position of the token in scanner text
} }