From 8f9c0b621e97e02560841ab3a2f72d5c39e3f59a Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Fri, 27 Sep 2019 05:27:57 +0300 Subject: [PATCH] parser: fix columns in errors --- compiler/parser.v | 58 +++++++--------------------------------------- compiler/scanner.v | 12 +++++++--- 2 files changed, 18 insertions(+), 52 deletions(-) diff --git a/compiler/parser.v b/compiler/parser.v index cf9547097d..2501acac52 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -20,7 +20,7 @@ struct Tok { lit string line_nr int name_idx int // name table index for O(1) lookup -// col int + col int } struct Parser { @@ -131,35 +131,24 @@ fn (v mut V) new_parser(path string) Parser { $if js { p.is_js = true } - if p.pref.is_repl { p.scanner.should_print_line_on_error = false } - v.cgen.line_directives = v.pref.is_debuggable v.cgen.file = path - for { res := p.scanner.scan() p.tokens << Tok { tok: res.tok lit: res.lit line_nr: p.scanner.line_nr + col: p.scanner.pos - p.scanner.last_nl_pos } if res.tok == .eof { break } } - v.add_parser(p) - /* - if !(p in v.parsers) { - v.parsers << p - - } - */ - - //p.next() //p.scanner.debug_tokens() return p } @@ -184,8 +173,7 @@ fn (p mut Parser) next() { p.tok = res.tok p.lit = res.lit p.scanner.line_nr = res.line_nr - } - +} fn (p & Parser) peek() Token { if p.token_idx >= p.tokens.len - 2 { @@ -193,40 +181,8 @@ fn (p & Parser) peek() Token { } tok := p.tokens[p.token_idx] return tok.tok -/* - // save scanner state - pos := s.pos - line := s.line_nr - inside_string := s.inside_string - inter_start := s.inter_start - inter_end := s.inter_end - - res := s.scan() - tok := res.tok - - // restore scanner state - s.pos = pos - s.line_nr = line - s.inside_string = inside_string - s.inter_start = inter_start - s.inter_end = inter_end - return tok - */ } - - -/* -fn (p mut Parser) next_old() { - p.prev_tok2 = p.prev_tok - p.prev_tok = p.tok - p.scanner.prev_tok = p.tok - res := p.scanner.scan() - p.tok = res.tok - p.lit = res.lit -} -*/ - fn (p &Parser) log(s string) { /* if !p.pref.is_verbose { @@ -911,7 +867,7 @@ fn (p mut Parser) error(s string) { println('pass=$p.pass fn=`$p.cur_fn.name`\n') } p.cgen.save() - // V git pull hint + // V up hint cur_path := os.getwd() if !p.pref.is_repl && !p.pref.is_test && ( p.file_path.contains('v/compiler') || cur_path.contains('v/compiler') ){ println('\n=========================') @@ -928,7 +884,11 @@ fn (p mut Parser) error(s string) { } // p.scanner.debug_tokens() // Print `[]int` instead of `array_int` in errors - p.scanner.error(s.replace('array_', '[]').replace('__', '.').replace('Option_', '?')) + e := s.replace('array_', '[]') + .replace('__', '.') + .replace('Option_', '?') + .replace('main.', '') + p.scanner.error_with_col(e, p.tokens[p.token_idx-1].col) } fn (p &Parser) first_pass() bool { diff --git a/compiler/scanner.v b/compiler/scanner.v index dae1b67b5b..7bc2b3ed1f 100644 --- a/compiler/scanner.v +++ b/compiler/scanner.v @@ -20,6 +20,7 @@ mut: text string pos int line_nr int + last_nl_pos int // for calculating column inside_string bool inter_start bool // for hacky string interpolation TODO simplify inter_end bool @@ -238,6 +239,7 @@ fn (s mut Scanner) skip_whitespace() { for s.pos < s.text.len && s.text[s.pos].is_white() { // Count \r\n as one line if is_nl(s.text[s.pos]) && !s.expect('\r\n', s.pos-1) { + s.last_nl_pos = s.pos s.line_nr++ } s.pos++ @@ -640,9 +642,13 @@ fn (s &Scanner) current_column() int { } fn (s &Scanner) error(msg string) { + s.error_with_col(msg, 0) +} + +fn (s &Scanner) error_with_col(msg string, col int) { + column := col-1 linestart := s.find_current_line_start_position() lineend := s.find_current_line_end_position() - column := s.pos - linestart if s.should_print_line_on_error && lineend > linestart { line := s.text.substr( linestart, lineend ) // The pointerline should have the same spaces/tabs as the offending @@ -667,8 +673,8 @@ fn (s &Scanner) error(msg string) { // and jump to their source with a keyboard shortcut. // Using only the filename leads to inability of IDE/editors // to find the source file, when it is in another folder. - println('${s.file_path}:${s.line_nr + 1}:${column+1}: $msg') - //println('${fullpath}:${s.line_nr + 1}:${column+1}: $msg') + //println('${s.file_path}:${s.line_nr + 1}:${column+1}: $msg') + println('${fullpath}:${s.line_nr + 1}:${column+1}: $msg') exit(1) }