mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
run vfmt on scanner.v
This commit is contained in:
parent
20e73ff69a
commit
81045023c4
@ -89,7 +89,7 @@ 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.nlines > 0 {
|
||||
if s.print_line_on_error && s.nlines > 0 {
|
||||
context_start_line := imax(0, (s.line_nr - error_context_before ))
|
||||
context_end_line := imin(s.nlines-1, (s.line_nr + error_context_after + 1 ))
|
||||
for cline := context_start_line; cline < context_end_line; cline++ {
|
||||
@ -130,7 +130,7 @@ fn (s &Scanner) get_error_filepath() string {
|
||||
use_relative_paths := match verror_paths_override {
|
||||
'relative' { true }
|
||||
'absolute' { false }
|
||||
else { s.should_print_relative_paths_on_error }
|
||||
else { s.print_rel_paths_on_error }
|
||||
}
|
||||
if use_relative_paths {
|
||||
workdir := os.getwd() + os.path_separator
|
||||
@ -143,7 +143,7 @@ fn (s &Scanner) get_error_filepath() string {
|
||||
}
|
||||
|
||||
fn (s &Scanner) is_color_output_on() bool {
|
||||
return s.should_print_errors_in_color && term.can_show_color_on_stderr()
|
||||
return s.print_colored_error && term.can_show_color_on_stderr()
|
||||
}
|
||||
|
||||
fn (p mut Parser) print_error_context(){
|
||||
|
@ -172,7 +172,7 @@ fn (v mut V) new_parser_from_file(path string) Parser {
|
||||
println('new_parser: V script')
|
||||
}
|
||||
if p.pref.building_v {
|
||||
p.scanner.should_print_relative_paths_on_error = true
|
||||
p.scanner.print_rel_paths_on_error = true
|
||||
}
|
||||
// if p.pref.generating_vh {
|
||||
// Keep newlines
|
||||
@ -205,9 +205,9 @@ fn (v mut V) new_parser(scanner &Scanner) Parser {
|
||||
p.is_js = true
|
||||
}
|
||||
if p.pref.is_repl {
|
||||
p.scanner.should_print_line_on_error = false
|
||||
p.scanner.should_print_errors_in_color = false
|
||||
p.scanner.should_print_relative_paths_on_error = true
|
||||
p.scanner.print_line_on_error = false
|
||||
p.scanner.print_colored_error = false
|
||||
p.scanner.print_rel_paths_on_error = true
|
||||
}
|
||||
return p
|
||||
}
|
||||
@ -942,7 +942,7 @@ fn (p mut Parser) get_type() string {
|
||||
// fn type
|
||||
if p.tok == .key_fn {
|
||||
mut f := Fn{
|
||||
name: '_',
|
||||
name: '_'
|
||||
mod: p.mod
|
||||
}
|
||||
p.next()
|
||||
@ -2212,8 +2212,8 @@ fn (p mut Parser) index_expr(typ_ string,fn_ph int) string {
|
||||
index_val := l[idx..].trim_space()
|
||||
p.cgen.resetln(l[..fn_ph])
|
||||
p.table.varg_access << VargAccess{
|
||||
fn_name: p.cur_fn.name,
|
||||
tok_idx: index_error_tok_pos,
|
||||
fn_name: p.cur_fn.name
|
||||
tok_idx: index_error_tok_pos
|
||||
index: index_val.int()
|
||||
}
|
||||
p.cgen.set_placeholder(fn_ph, '${v.name}->args[$index_val]')
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module compiler
|
||||
|
||||
import (
|
||||
@ -38,9 +37,9 @@ mut:
|
||||
// fmt_needs_nl bool
|
||||
prev_tok TokenKind
|
||||
fn_name string // needed for @FN
|
||||
should_print_line_on_error bool
|
||||
should_print_errors_in_color bool
|
||||
should_print_relative_paths_on_error bool
|
||||
print_line_on_error bool
|
||||
print_colored_error bool
|
||||
print_rel_paths_on_error bool
|
||||
quote byte // which quote is used to denote current string: ' or "
|
||||
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
|
||||
@ -48,33 +47,27 @@ mut:
|
||||
is_fmt bool // Used only for skipping ${} in strings, since we need literal
|
||||
// string values when generating formatted code.
|
||||
}
|
||||
|
||||
// new scanner from file.
|
||||
fn new_scanner_file(file_path string) &Scanner {
|
||||
if !os.exists(file_path) {
|
||||
verror("$file_path doesn't exist")
|
||||
}
|
||||
|
||||
mut raw_text := os.read_file(file_path)or{
|
||||
verror('scanner: failed to open $file_path')
|
||||
return 0
|
||||
}
|
||||
|
||||
// BOM check
|
||||
if raw_text.len >= 3 {
|
||||
c_text := raw_text.str
|
||||
|
||||
if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF {
|
||||
// skip three BOM bytes
|
||||
offset_from_begin := 3
|
||||
raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin)
|
||||
}
|
||||
}
|
||||
|
||||
mut s := new_scanner(raw_text)
|
||||
s.init_fmt()
|
||||
s.file_path = file_path
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@ -83,12 +76,12 @@ fn new_scanner(text string) &Scanner {
|
||||
return &Scanner{
|
||||
text: text
|
||||
// fmt_out: strings.new_builder(1000)
|
||||
should_print_line_on_error: true
|
||||
should_print_errors_in_color: true
|
||||
should_print_relative_paths_on_error: true
|
||||
}
|
||||
}
|
||||
|
||||
print_line_on_error: true
|
||||
print_colored_error: true
|
||||
print_rel_paths_on_error: true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO remove once multiple return values are implemented
|
||||
struct ScanRes {
|
||||
@ -97,7 +90,8 @@ struct ScanRes {
|
||||
}
|
||||
|
||||
fn scan_res(tok TokenKind,lit string) ScanRes {
|
||||
return ScanRes{tok, lit}
|
||||
return ScanRes{
|
||||
tok,lit}
|
||||
}
|
||||
|
||||
fn (s mut Scanner) ident_name() string {
|
||||
@ -146,7 +140,8 @@ fn (s mut Scanner) ident_oct_number() string {
|
||||
if !c.is_oct_digit() {
|
||||
s.error('malformed octal constant')
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
break
|
||||
}
|
||||
s.pos++
|
||||
@ -158,12 +153,10 @@ fn (s mut Scanner) ident_oct_number() string {
|
||||
|
||||
fn (s mut Scanner) ident_dec_number() string {
|
||||
start_pos := s.pos
|
||||
|
||||
// scan integer part
|
||||
for s.pos < s.text.len && s.text[s.pos].is_digit() {
|
||||
s.pos++
|
||||
}
|
||||
|
||||
// e.g. 1..9
|
||||
// we just return '1' and don't scan '..9'
|
||||
if s.expect('..', s.pos) {
|
||||
@ -171,7 +164,6 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||
s.pos--
|
||||
return number
|
||||
}
|
||||
|
||||
// scan fractional part
|
||||
if s.pos < s.text.len && s.text[s.pos] == `.` {
|
||||
s.pos++
|
||||
@ -182,7 +174,6 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||
s.error('no `f` is needed for floats')
|
||||
}
|
||||
}
|
||||
|
||||
// scan exponential part
|
||||
mut has_exponential_part := false
|
||||
if s.expect('e+', s.pos) || s.expect('e-', s.pos) {
|
||||
@ -195,7 +186,6 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||
}
|
||||
has_exponential_part = true
|
||||
}
|
||||
|
||||
// error check: 1.23.4, 123.e+3.4
|
||||
if s.pos < s.text.len && s.text[s.pos] == `.` {
|
||||
if has_exponential_part {
|
||||
@ -205,7 +195,6 @@ fn (s mut Scanner) ident_dec_number() string {
|
||||
s.error('too many decimal points in number')
|
||||
}
|
||||
}
|
||||
|
||||
number := s.text[start_pos..s.pos]
|
||||
s.pos--
|
||||
return number
|
||||
@ -215,15 +204,12 @@ fn (s mut Scanner) ident_number() string {
|
||||
if s.expect('0x', s.pos) {
|
||||
return s.ident_hex_number()
|
||||
}
|
||||
|
||||
if s.expect('0.', s.pos) || s.expect('0e', s.pos) {
|
||||
return s.ident_dec_number()
|
||||
}
|
||||
|
||||
if s.text[s.pos] == `0` {
|
||||
return s.ident_oct_number()
|
||||
}
|
||||
|
||||
return s.ident_dec_number()
|
||||
}
|
||||
|
||||
@ -232,7 +218,6 @@ fn (s mut Scanner) skip_whitespace() {
|
||||
for s.pos < s.text.len && s.text[s.pos].is_white() {
|
||||
if is_nl(s.text[s.pos]) && s.is_vh {
|
||||
return
|
||||
|
||||
}
|
||||
// Count \r\n as one line
|
||||
if is_nl(s.text[s.pos]) && !s.expect('\r\n', s.pos - 1) {
|
||||
@ -380,11 +365,11 @@ fn (s mut Scanner) scan() ScanRes {
|
||||
single_quote,double_quote {
|
||||
return scan_res(.str, s.ident_string())
|
||||
}
|
||||
`\`` { // ` // apostrophe balance comment. do not remove
|
||||
`\`` {
|
||||
// ` // apostrophe balance comment. do not remove
|
||||
return scan_res(.chartoken, s.ident_char())
|
||||
}
|
||||
`(` {
|
||||
|
||||
return scan_res(.lpar, '')
|
||||
}
|
||||
`)` {
|
||||
@ -406,7 +391,8 @@ fn (s mut Scanner) scan() ScanRes {
|
||||
`$` {
|
||||
if s.inside_string {
|
||||
return scan_res(.str_dollar, '')
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return scan_res(.dollar, '')
|
||||
}
|
||||
}
|
||||
@ -461,11 +447,21 @@ fn (s mut Scanner) scan() ScanRes {
|
||||
// This allows things like this:
|
||||
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
|
||||
// ... which is useful while debugging/tracing
|
||||
if name == 'FN' { return scan_res(.str, s.fn_name) }
|
||||
if name == 'FILE' { return scan_res(.str, cescaped_path(os.realpath(s.file_path))) }
|
||||
if name == 'LINE' { return scan_res(.str, (s.line_nr+1).str()) }
|
||||
if name == 'COLUMN' { return scan_res(.str, (s.current_column()).str()) }
|
||||
if name == 'VHASH' { return scan_res(.str, vhash()) }
|
||||
if name == 'FN' {
|
||||
return scan_res(.str, s.fn_name)
|
||||
}
|
||||
if name == 'FILE' {
|
||||
return scan_res(.str, cescaped_path(os.realpath(s.file_path)))
|
||||
}
|
||||
if name == 'LINE' {
|
||||
return scan_res(.str, (s.line_nr + 1).str())
|
||||
}
|
||||
if name == 'COLUMN' {
|
||||
return scan_res(.str, (s.current_column()).str())
|
||||
}
|
||||
if name == 'VHASH' {
|
||||
return scan_res(.str, vhash())
|
||||
}
|
||||
if !is_key(name) {
|
||||
s.error('@ must be used before keywords (e.g. `@type string`)')
|
||||
}
|
||||
@ -484,6 +480,7 @@ fn (s mut Scanner) scan() ScanRes {
|
||||
return scan_res(.nl, '')
|
||||
}
|
||||
*/
|
||||
|
||||
`.` {
|
||||
if nextc == `.` {
|
||||
s.pos++
|
||||
@ -649,8 +646,8 @@ fn (s mut Scanner) scan() ScanRes {
|
||||
}
|
||||
return scan_res(.div, '')
|
||||
}
|
||||
else { }
|
||||
}
|
||||
else {
|
||||
}}
|
||||
$if windows {
|
||||
if c == `\0` {
|
||||
return s.end_of_file()
|
||||
@ -707,8 +704,8 @@ fn (s mut Scanner) ident_string() string {
|
||||
// Don't allow \0
|
||||
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash {
|
||||
if s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit() {
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
s.error('0 character in a string literal')
|
||||
}
|
||||
}
|
||||
@ -717,18 +714,14 @@ fn (s mut Scanner) ident_string() string {
|
||||
s.error('0 character in a string literal')
|
||||
}
|
||||
// ${var} (ignore in vfmt mode)
|
||||
if c == `{` && prevc == `$` && !is_raw && !s.is_fmt &&
|
||||
s.count_symbol_before(s.pos-2, slash) % 2 == 0
|
||||
{
|
||||
if c == `{` && prevc == `$` && !is_raw && !s.is_fmt && 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.is_fmt &&
|
||||
!is_raw && s.count_symbol_before(s.pos-2, slash) % 2 == 0
|
||||
{
|
||||
if (c.is_letter() || c == `_`) && prevc == `$` && !s.is_fmt && !is_raw && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 {
|
||||
s.inside_string = true
|
||||
s.inter_start = true
|
||||
s.pos -= 2
|
||||
@ -743,7 +736,8 @@ fn (s mut Scanner) ident_string() string {
|
||||
if s.inside_string {
|
||||
end++
|
||||
}
|
||||
if start > s.pos{}
|
||||
if start > s.pos {
|
||||
}
|
||||
else {
|
||||
lit = s.text[start..end]
|
||||
}
|
||||
@ -763,7 +757,8 @@ fn (s mut Scanner) ident_char() string {
|
||||
len++
|
||||
}
|
||||
double_slash := s.expect('\\\\', s.pos - 2)
|
||||
if s.text[s.pos] == `\`` && (s.text[s.pos - 1] != slash || double_slash) { // ` // apostrophe balance comment. do not remove
|
||||
if s.text[s.pos] == `\`` && (s.text[s.pos - 1] != slash || double_slash) {
|
||||
// ` // apostrophe balance comment. do not remove
|
||||
if double_slash {
|
||||
len++
|
||||
}
|
||||
@ -775,15 +770,14 @@ fn (s mut Scanner) ident_char() string {
|
||||
if len != 1 {
|
||||
u := c.ustring()
|
||||
if u.len != 1 {
|
||||
s.error('invalid character literal (more than one character)\n' +
|
||||
'use quotes for strings, backticks for characters')
|
||||
s.error('invalid character literal (more than one character)\n' + 'use quotes for strings, backticks for characters')
|
||||
}
|
||||
}
|
||||
if c == '\\`' {
|
||||
return '`'
|
||||
}
|
||||
// Escapes a `'` character
|
||||
return if c == '\'' { '\\' + c } else { c }
|
||||
return if c == "\'" {'\\' + c}else {c}
|
||||
}
|
||||
|
||||
fn (s &Scanner) expect(want string,start_pos int) bool {
|
||||
@ -806,10 +800,8 @@ fn (s mut Scanner) debug_tokens() {
|
||||
s.pos = 0
|
||||
s.started = false
|
||||
s.debug = true
|
||||
|
||||
fname := s.file_path.all_after(os.path_separator)
|
||||
println('\n===DEBUG TOKENS $fname===')
|
||||
|
||||
for {
|
||||
res := s.scan()
|
||||
tok := res.tok
|
||||
@ -828,7 +820,6 @@ fn (s mut Scanner) debug_tokens() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn (s mut Scanner) ignore_line() {
|
||||
s.eat_to_end_of_line()
|
||||
s.inc_line_number()
|
||||
@ -851,8 +842,7 @@ fn (s mut Scanner) inc_line_number() {
|
||||
|
||||
fn (s Scanner) line(n int) string {
|
||||
mut res := ''
|
||||
if n >= 0 &&
|
||||
n < s.line_ends.len {
|
||||
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 {
|
||||
@ -898,11 +888,6 @@ fn good_type_name(s string) bool {
|
||||
// registrationdate bad
|
||||
fn (s &Scanner) validate_var_name(name string) {
|
||||
if name.len > 15 && !name.contains('_') {
|
||||
s.error('bad variable name `$name`\n' +
|
||||
'looks like you have a multi-word name without separating them with `_`' +
|
||||
'\nfor example, use `registration_date` instead of `registrationdate` ')
|
||||
|
||||
s.error('bad variable name `$name`\n' + 'looks like you have a multi-word name without separating them with `_`' + '\nfor example, use `registration_date` instead of `registrationdate` ')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -315,6 +315,7 @@ fn (p mut Parser) struct_init(typ string) string {
|
||||
p.check_types(p.bool_expression(), f.typ)
|
||||
if p.tok == .comma {
|
||||
p.next()
|
||||
p.fremove_last()
|
||||
}
|
||||
if p.tok != .rcbr {
|
||||
p.gen(',')
|
||||
|
@ -161,8 +161,8 @@ fn (p mut Parser) fnext() {
|
||||
if p.tokens[p.token_idx].tok in [.line_comment, .mline_comment] {
|
||||
// Newline before the comment and after consts and closing }
|
||||
if p.inside_const {
|
||||
p.fgen_nl()
|
||||
p.fgen_nl()
|
||||
//p.fgen_nl()
|
||||
//p.fgen_nl()
|
||||
}
|
||||
//is_rcbr := p.tok == .rcbr
|
||||
for p.token_idx < p.tokens.len - 1 {
|
||||
@ -218,6 +218,12 @@ fn (p mut Parser) fnext() {
|
||||
}
|
||||
}
|
||||
|
||||
[if vfmt]
|
||||
fn (p mut Parser) fremove_last() {
|
||||
p.scanner.fmt_lines[p.scanner.fmt_lines.len-1] = ''
|
||||
|
||||
}
|
||||
|
||||
|
||||
[if vfmt]
|
||||
fn (p &Parser) gen_fmt() {
|
||||
@ -237,7 +243,7 @@ fn (p &Parser) gen_fmt() {
|
||||
if s == '' {
|
||||
return
|
||||
}
|
||||
if !p.file_name.contains('parser.v') {return}
|
||||
if !p.file_name.contains('scanner.v') {return}
|
||||
path := os.tmpdir() + '/' + p.file_name
|
||||
println('generating ${path}')
|
||||
mut out := os.create(path) or {
|
||||
|
Loading…
Reference in New Issue
Block a user