clean up empty lines in errors; simplify source line tracking

pull/2504/head
Delyan Angelov 2019-10-22 18:38:17 +03:00 committed by Alexander Medvednikov
parent d289a90cc7
commit eeea257467
2 changed files with 27 additions and 14 deletions

View File

@ -95,11 +95,11 @@ fn (s &Scanner) error_with_col(msg string, col int) {
// to find the source file, when the IDE has a different working folder than v itself.
eprintln('${fullpath}:${s.line_nr + 1}:${col}: $final_message')
if s.should_print_line_on_error && s.file_lines.len > 0 {
context_start_line := imax(0, (s.line_nr - error_context_before + 1 ))
context_end_line := imin(s.file_lines.len, (s.line_nr + error_context_after + 1 ))
if s.should_print_line_on_error && s.nlines > 0 {
context_start_line := imax(0, (s.line_nr - error_context_before + 1 ))
context_end_line := imin(s.nlines-1, (s.line_nr + error_context_after + 1 ))
for cline := context_start_line; cline < context_end_line; cline++ {
line := '${(cline+1):5d}| ' + s.file_lines[ cline ]
line := '${(cline+1):5d}| ' + s.line( cline )
coloredline := if cline == s.line_nr && color_on { term.red(line) } else { line }
eprintln( coloredline )
if cline != s.line_nr { continue }
@ -225,9 +225,8 @@ fn (s mut Scanner) get_scanner_pos_of_token(t &Token) 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. Continue scanning for some more lines of context too.
// of the token.
s.goto_scanner_position(ScannerPos{})
s.file_lines = []string
mut prevlinepos := 0
// NB: TCC BUG workaround: removing the `mut ate:=0 ate++` line
@ -251,15 +250,13 @@ fn (s mut Scanner) get_scanner_pos_of_token(t &Token) ScannerPos {
for {
prevlinepos = s.pos
if s.pos >= s.text.len { break }
if s.line_nr > tline + 10 { break }
if s.line_nr > tline { break }
////////////////////////////////////////
if tline == s.line_nr {
sptoken = s.get_scanner_pos()
sptoken.pos += tcol
}
s.ignore_line() s.eat_single_newline()
sline := s.text.substr( prevlinepos, s.pos )//.trim_right('\r\n')
s.file_lines << sline
}
//////////////////////////////////////////////////
s.goto_scanner_position(cpos)

View File

@ -39,7 +39,8 @@ mut:
should_print_errors_in_color bool
should_print_relative_paths_on_error bool
quote byte // which quote is used to denote current string: ' or "
file_lines []string // filled *only on error* by rescanning the source till the error (and several lines more)
line_ends []int // the positions of source lines ends (i.e. \n signs)
nlines int // total number of lines in the source file that were scanned
}
// new scanner from file.
@ -632,7 +633,7 @@ fn (s mut Scanner) ident_string() string {
s.inc_line_number()
}
// Don't allow \0
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == `\\` {
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash {
s.error('0 character in a string literal')
}
// Don't allow \x00
@ -640,14 +641,14 @@ fn (s mut Scanner) ident_string() string {
s.error('0 character in a string literal')
}
// ${var}
if c == `{` && prevc == `$` && s.count_symbol_before(s.pos-2, `\\`) % 2 == 0 {
if c == `{` && prevc == `$` && s.count_symbol_before(s.pos-2, slash) % 2 == 0 {
s.inside_string = true
// so that s.pos points to $ at the next step
s.pos -= 2
break
}
// $var
if (c.is_letter() || c == `_`) && prevc == `$` && s.count_symbol_before(s.pos-2, `\\`) % 2 == 0 {
if (c.is_letter() || c == `_`) && prevc == `$` && s.count_symbol_before(s.pos-2, slash) % 2 == 0 {
s.inside_string = true
s.inter_start = true
s.pos -= 2
@ -748,7 +749,7 @@ fn (s mut Scanner) debug_tokens() {
fn (s mut Scanner) ignore_line() {
s.eat_to_end_of_line()
s.eat_to_end_of_line()
s.inc_line_number()
}
@ -761,6 +762,21 @@ fn (s mut Scanner) eat_to_end_of_line(){
fn (s mut Scanner) inc_line_number() {
s.last_nl_pos = s.pos
s.line_nr++
s.line_ends << s.pos
s.nlines++
}
fn (s Scanner) line(n int) string {
mut res := ''
if n >= 0 &&
n < s.line_ends.len {
nline_start := if n == 0 { 0 } else { s.line_ends[ n - 1 ] }
nline_end := s.line_ends[n]
if nline_start <= nline_end {
res = s.text.substr( nline_start, nline_end )
}
}
return res.trim_right('\r\n').trim_left('\r\n')
}
fn is_name_char(c byte) bool {