1
0
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:
Alexander Medvednikov 2019-12-18 08:13:31 +03:00
parent 20e73ff69a
commit 81045023c4
7 changed files with 412 additions and 420 deletions

View File

@ -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. // 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') 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_start_line := imax(0, (s.line_nr - error_context_before ))
context_end_line := imin(s.nlines-1, (s.line_nr + error_context_after + 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++ { 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 { use_relative_paths := match verror_paths_override {
'relative' { true } 'relative' { true }
'absolute' { false } 'absolute' { false }
else { s.should_print_relative_paths_on_error } else { s.print_rel_paths_on_error }
} }
if use_relative_paths { if use_relative_paths {
workdir := os.getwd() + os.path_separator 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 { 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(){ fn (p mut Parser) print_error_context(){

View File

@ -172,7 +172,7 @@ fn (v mut V) new_parser_from_file(path string) Parser {
println('new_parser: V script') println('new_parser: V script')
} }
if p.pref.building_v { 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 { // if p.pref.generating_vh {
// Keep newlines // Keep newlines
@ -205,9 +205,9 @@ fn (v mut V) new_parser(scanner &Scanner) Parser {
p.is_js = true p.is_js = true
} }
if p.pref.is_repl { if p.pref.is_repl {
p.scanner.should_print_line_on_error = false p.scanner.print_line_on_error = false
p.scanner.should_print_errors_in_color = false p.scanner.print_colored_error = false
p.scanner.should_print_relative_paths_on_error = true p.scanner.print_rel_paths_on_error = true
} }
return p return p
} }
@ -942,7 +942,7 @@ fn (p mut Parser) get_type() string {
// fn type // fn type
if p.tok == .key_fn { if p.tok == .key_fn {
mut f := Fn{ mut f := Fn{
name: '_', name: '_'
mod: p.mod mod: p.mod
} }
p.next() p.next()
@ -2212,8 +2212,8 @@ fn (p mut Parser) index_expr(typ_ string,fn_ph int) string {
index_val := l[idx..].trim_space() index_val := l[idx..].trim_space()
p.cgen.resetln(l[..fn_ph]) p.cgen.resetln(l[..fn_ph])
p.table.varg_access << VargAccess{ p.table.varg_access << VargAccess{
fn_name: p.cur_fn.name, fn_name: p.cur_fn.name
tok_idx: index_error_tok_pos, tok_idx: index_error_tok_pos
index: index_val.int() index: index_val.int()
} }
p.cgen.set_placeholder(fn_ph, '${v.name}->args[$index_val]') p.cgen.set_placeholder(fn_ph, '${v.name}->args[$index_val]')

View File

@ -1,12 +1,11 @@
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module compiler module compiler
import ( import (
os os
//strings // strings
) )
const ( const (
@ -30,17 +29,17 @@ mut:
line_comment string line_comment string
started bool started bool
// vfmt fields TODO move to a separate struct // vfmt fields TODO move to a separate struct
//fmt_out strings.Builder // fmt_out strings.Builder
fmt_lines []string fmt_lines []string
//fmt_line string // fmt_line string
fmt_indent int fmt_indent int
fmt_line_empty bool fmt_line_empty bool
//fmt_needs_nl bool // fmt_needs_nl bool
prev_tok TokenKind prev_tok TokenKind
fn_name string // needed for @FN fn_name string // needed for @FN
should_print_line_on_error bool print_line_on_error bool
should_print_errors_in_color bool print_colored_error bool
should_print_relative_paths_on_error bool print_rel_paths_on_error bool
quote byte // which quote is used to denote current string: ' or " quote byte // which quote is used to denote current string: ' or "
line_ends []int // the positions of source lines ends (i.e. \n signs) 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 nlines int // total number of lines in the source file that were scanned
@ -48,56 +47,51 @@ mut:
is_fmt bool // Used only for skipping ${} in strings, since we need literal is_fmt bool // Used only for skipping ${} in strings, since we need literal
// string values when generating formatted code. // string values when generating formatted code.
} }
// new scanner from file. // new scanner from file.
fn new_scanner_file(file_path string) &Scanner { fn new_scanner_file(file_path string) &Scanner {
if !os.exists(file_path) { if !os.exists(file_path) {
verror("$file_path doesn't exist") verror("$file_path doesn't exist")
} }
mut raw_text := os.read_file(file_path)or{
mut raw_text := os.read_file(file_path) or {
verror('scanner: failed to open $file_path') verror('scanner: failed to open $file_path')
return 0 return 0
} }
// BOM check // BOM check
if raw_text.len >= 3 { if raw_text.len >= 3 {
c_text := raw_text.str c_text := raw_text.str
if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF { if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF {
// skip three BOM bytes // skip three BOM bytes
offset_from_begin := 3 offset_from_begin := 3
raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin) raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin)
} }
} }
mut s := new_scanner(raw_text) mut s := new_scanner(raw_text)
s.init_fmt() s.init_fmt()
s.file_path = file_path s.file_path = file_path
return s return s
} }
// new scanner from string. // new scanner from string.
fn new_scanner(text string) &Scanner { fn new_scanner(text string) &Scanner {
return &Scanner { return &Scanner{
text: text text: text
//fmt_out: strings.new_builder(1000) // fmt_out: strings.new_builder(1000)
should_print_line_on_error: true
should_print_errors_in_color: true print_line_on_error: true
should_print_relative_paths_on_error: true print_colored_error: true
print_rel_paths_on_error: true
} }
} }
// TODO remove once multiple return values are implemented // TODO remove once multiple return values are implemented
struct ScanRes { struct ScanRes {
tok TokenKind tok TokenKind
lit string lit string
} }
fn scan_res(tok TokenKind, lit string) ScanRes { fn scan_res(tok TokenKind,lit string) ScanRes {
return ScanRes{tok, lit} return ScanRes{
tok,lit}
} }
fn (s mut Scanner) ident_name() string { fn (s mut Scanner) ident_name() string {
@ -146,7 +140,8 @@ fn (s mut Scanner) ident_oct_number() string {
if !c.is_oct_digit() { if !c.is_oct_digit() {
s.error('malformed octal constant') s.error('malformed octal constant')
} }
} else { }
else {
break break
} }
s.pos++ s.pos++
@ -158,12 +153,10 @@ fn (s mut Scanner) ident_oct_number() string {
fn (s mut Scanner) ident_dec_number() string { fn (s mut Scanner) ident_dec_number() string {
start_pos := s.pos start_pos := s.pos
// scan integer part // scan integer part
for s.pos < s.text.len && s.text[s.pos].is_digit() { for s.pos < s.text.len && s.text[s.pos].is_digit() {
s.pos++ s.pos++
} }
// e.g. 1..9 // e.g. 1..9
// we just return '1' and don't scan '..9' // we just return '1' and don't scan '..9'
if s.expect('..', s.pos) { if s.expect('..', s.pos) {
@ -171,7 +164,6 @@ fn (s mut Scanner) ident_dec_number() string {
s.pos-- s.pos--
return number return number
} }
// scan fractional part // scan fractional part
if s.pos < s.text.len && s.text[s.pos] == `.` { if s.pos < s.text.len && s.text[s.pos] == `.` {
s.pos++ s.pos++
@ -182,7 +174,6 @@ fn (s mut Scanner) ident_dec_number() string {
s.error('no `f` is needed for floats') s.error('no `f` is needed for floats')
} }
} }
// scan exponential part // scan exponential part
mut has_exponential_part := false mut has_exponential_part := false
if s.expect('e+', s.pos) || s.expect('e-', s.pos) { 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 has_exponential_part = true
} }
// error check: 1.23.4, 123.e+3.4 // error check: 1.23.4, 123.e+3.4
if s.pos < s.text.len && s.text[s.pos] == `.` { if s.pos < s.text.len && s.text[s.pos] == `.` {
if has_exponential_part { if has_exponential_part {
@ -205,7 +195,6 @@ fn (s mut Scanner) ident_dec_number() string {
s.error('too many decimal points in number') s.error('too many decimal points in number')
} }
} }
number := s.text[start_pos..s.pos] number := s.text[start_pos..s.pos]
s.pos-- s.pos--
return number return number
@ -215,27 +204,23 @@ fn (s mut Scanner) ident_number() string {
if s.expect('0x', s.pos) { if s.expect('0x', s.pos) {
return s.ident_hex_number() return s.ident_hex_number()
} }
if s.expect('0.', s.pos) || s.expect('0e', s.pos) { if s.expect('0.', s.pos) || s.expect('0e', s.pos) {
return s.ident_dec_number() return s.ident_dec_number()
} }
if s.text[s.pos] == `0` { if s.text[s.pos] == `0` {
return s.ident_oct_number() return s.ident_oct_number()
} }
return s.ident_dec_number() return s.ident_dec_number()
} }
fn (s mut Scanner) skip_whitespace() { fn (s mut Scanner) skip_whitespace() {
//if s.is_vh { println('vh') return } // if s.is_vh { println('vh') return }
for s.pos < s.text.len && s.text[s.pos].is_white() { for s.pos < s.text.len && s.text[s.pos].is_white() {
if is_nl(s.text[s.pos]) && s.is_vh { if is_nl(s.text[s.pos]) && s.is_vh {
return return
} }
// Count \r\n as one line // Count \r\n as one line
if is_nl(s.text[s.pos]) && !s.expect('\r\n', s.pos-1) { if is_nl(s.text[s.pos]) && !s.expect('\r\n', s.pos - 1) {
s.inc_line_number() s.inc_line_number()
} }
s.pos++ s.pos++
@ -249,10 +234,10 @@ fn (s mut Scanner) end_of_file() ScanRes {
} }
fn (s mut Scanner) scan() ScanRes { fn (s mut Scanner) scan() ScanRes {
//if s.line_comment != '' { // if s.line_comment != '' {
//s.fgenln('// LC "$s.line_comment"') // s.fgenln('// LC "$s.line_comment"')
//s.line_comment = '' // s.line_comment = ''
//} // }
if s.started { if s.started {
s.pos++ s.pos++
} }
@ -288,7 +273,7 @@ fn (s mut Scanner) scan() ScanRes {
name := s.ident_name() name := s.ident_name()
// tmp hack to detect . in ${} // tmp hack to detect . in ${}
// Check if not .eof to prevent panic // Check if not .eof to prevent panic
next_char := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` } next_char := if s.pos + 1 < s.text.len {s.text[s.pos + 1]}else {`\0`}
if is_key(name) { if is_key(name) {
return scan_res(key_to_token(name), '') return scan_res(key_to_token(name), '')
} }
@ -308,8 +293,8 @@ fn (s mut Scanner) scan() ScanRes {
s.inter_start = false s.inter_start = false
} }
if s.pos == 0 && next_char == ` ` { if s.pos == 0 && next_char == ` ` {
//If a single letter name at the start of the file, increment // If a single letter name at the start of the file, increment
//Otherwise the scanner would be stuck at s.pos = 0 // Otherwise the scanner would be stuck at s.pos = 0
s.pos++ s.pos++
} }
return scan_res(.name, name) return scan_res(.name, name)
@ -323,7 +308,7 @@ fn (s mut Scanner) scan() ScanRes {
if c == `)` && s.inter_start { if c == `)` && s.inter_start {
s.inter_end = true s.inter_end = true
s.inter_start = false s.inter_start = false
next_char := if s.pos + 1 < s.text.len { s.text[s.pos + 1] } else { `\0` } next_char := if s.pos + 1 < s.text.len {s.text[s.pos + 1]}else {`\0`}
if next_char == s.quote { if next_char == s.quote {
s.inside_string = false s.inside_string = false
} }
@ -377,14 +362,14 @@ fn (s mut Scanner) scan() ScanRes {
`?` { `?` {
return scan_res(.question, '') return scan_res(.question, '')
} }
single_quote, double_quote { single_quote,double_quote {
return scan_res(.str, s.ident_string()) 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(.chartoken, s.ident_char())
} }
`(` { `(` {
return scan_res(.lpar, '') return scan_res(.lpar, '')
} }
`)` { `)` {
@ -406,7 +391,8 @@ fn (s mut Scanner) scan() ScanRes {
`$` { `$` {
if s.inside_string { if s.inside_string {
return scan_res(.str_dollar, '') return scan_res(.str_dollar, '')
} else { }
else {
return scan_res(.dollar, '') return scan_res(.dollar, '')
} }
} }
@ -461,11 +447,21 @@ fn (s mut Scanner) scan() ScanRes {
// This allows things like this: // This allows things like this:
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN) // println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @FN)
// ... which is useful while debugging/tracing // ... which is useful while debugging/tracing
if name == 'FN' { return scan_res(.str, s.fn_name) } if name == 'FN' {
if name == 'FILE' { return scan_res(.str, cescaped_path(os.realpath(s.file_path))) } return scan_res(.str, s.fn_name)
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 == 'FILE' {
if name == 'VHASH' { return scan_res(.str, vhash()) } 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) { if !is_key(name) {
s.error('@ must be used before keywords (e.g. `@type string`)') s.error('@ must be used before keywords (e.g. `@type string`)')
} }
@ -484,10 +480,11 @@ fn (s mut Scanner) scan() ScanRes {
return scan_res(.nl, '') return scan_res(.nl, '')
} }
*/ */
`.` { `.` {
if nextc == `.` { if nextc == `.` {
s.pos++ s.pos++
if s.text[s.pos+1] == `.` { if s.text[s.pos + 1] == `.` {
s.pos++ s.pos++
return scan_res(.ellipsis, '') return scan_res(.ellipsis, '')
} }
@ -501,7 +498,7 @@ fn (s mut Scanner) scan() ScanRes {
if nextc == `!` { if nextc == `!` {
// treat shebang line (#!) as a comment // treat shebang line (#!) as a comment
s.line_comment = s.text[start + 1..s.pos].trim_space() s.line_comment = s.text[start + 1..s.pos].trim_space()
//s.fgenln('// shebang line "$s.line_comment"') // s.fgenln('// shebang line "$s.line_comment"')
return s.scan() return s.scan()
} }
hash := s.text[start..s.pos] hash := s.text[start..s.pos]
@ -525,7 +522,7 @@ fn (s mut Scanner) scan() ScanRes {
} }
} }
0xE2 { 0xE2 {
//case `≠`: // case `≠`:
if nextc == 0x89 && s.text[s.pos + 2] == 0xA0 { if nextc == 0x89 && s.text[s.pos + 2] == 0xA0 {
s.pos += 2 s.pos += 2
return scan_res(.ne, '') return scan_res(.ne, '')
@ -610,7 +607,7 @@ fn (s mut Scanner) scan() ScanRes {
s.line_nr-- s.line_nr--
return scan_res(.line_comment, s.line_comment) return scan_res(.line_comment, s.line_comment)
} }
//s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"') // s.fgenln('// ${s.prev_tok.str()} "$s.line_comment"')
// Skip the comment (return the next token) // Skip the comment (return the next token)
return s.scan() return s.scan()
} }
@ -649,8 +646,8 @@ fn (s mut Scanner) scan() ScanRes {
} }
return scan_res(.div, '') return scan_res(.div, '')
} }
else { } else {
} }}
$if windows { $if windows {
if c == `\0` { if c == `\0` {
return s.end_of_file() return s.end_of_file()
@ -664,9 +661,9 @@ fn (s &Scanner) current_column() int {
return s.pos - s.last_nl_pos return s.pos - s.last_nl_pos
} }
fn (s Scanner) count_symbol_before(p int, sym byte) int { fn (s Scanner) count_symbol_before(p int,sym byte) int {
mut count := 0 mut count := 0
for i:=p; i>=0; i-- { for i := p; i >= 0; i-- {
if s.text[i] != sym { if s.text[i] != sym {
break break
} }
@ -678,14 +675,14 @@ fn (s Scanner) count_symbol_before(p int, sym byte) int {
fn (s mut Scanner) ident_string() string { fn (s mut Scanner) ident_string() string {
q := s.text[s.pos] q := s.text[s.pos]
is_quote := q == single_quote || q == double_quote is_quote := q == single_quote || q == double_quote
is_raw := is_quote && s.text[s.pos-1] == `r` is_raw := is_quote && s.text[s.pos - 1] == `r`
if is_quote && !s.inside_string { if is_quote && !s.inside_string {
s.quote = q s.quote = q
} }
//if s.file_path.contains('string_test') { // if s.file_path.contains('string_test') {
//println('\nident_string() at char=${s.text[s.pos].str()}') // println('\nident_string() at char=${s.text[s.pos].str()}')
//println('linenr=$s.line_nr quote= $qquote ${qquote.str()}') // println('linenr=$s.line_nr quote= $qquote ${qquote.str()}')
//} // }
mut start := s.pos mut start := s.pos
s.inside_string = false s.inside_string = false
slash := `\\` slash := `\\`
@ -706,9 +703,9 @@ fn (s mut Scanner) ident_string() string {
} }
// Don't allow \0 // Don't allow \0
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash { 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() { if s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit() {
}
} else { else {
s.error('0 character in a string literal') 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') s.error('0 character in a string literal')
} }
// ${var} (ignore in vfmt mode) // ${var} (ignore in vfmt mode)
if c == `{` && prevc == `$` && !is_raw && !s.is_fmt && if c == `{` && prevc == `$` && !is_raw && !s.is_fmt && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 {
s.count_symbol_before(s.pos-2, slash) % 2 == 0
{
s.inside_string = true s.inside_string = true
// so that s.pos points to $ at the next step // so that s.pos points to $ at the next step
s.pos -= 2 s.pos -= 2
break break
} }
// $var // $var
if (c.is_letter() || c == `_`) && prevc == `$` && !s.is_fmt && if (c.is_letter() || c == `_`) && prevc == `$` && !s.is_fmt && !is_raw && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 {
!is_raw && s.count_symbol_before(s.pos-2, slash) % 2 == 0
{
s.inside_string = true s.inside_string = true
s.inter_start = true s.inter_start = true
s.pos -= 2 s.pos -= 2
@ -743,7 +736,8 @@ fn (s mut Scanner) ident_string() string {
if s.inside_string { if s.inside_string {
end++ end++
} }
if start > s.pos{} if start > s.pos {
}
else { else {
lit = s.text[start..end] lit = s.text[start..end]
} }
@ -763,7 +757,8 @@ fn (s mut Scanner) ident_char() string {
len++ len++
} }
double_slash := s.expect('\\\\', s.pos - 2) 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 { if double_slash {
len++ len++
} }
@ -775,18 +770,17 @@ fn (s mut Scanner) ident_char() string {
if len != 1 { if len != 1 {
u := c.ustring() u := c.ustring()
if u.len != 1 { if u.len != 1 {
s.error('invalid character literal (more than one character)\n' + s.error('invalid character literal (more than one character)\n' + 'use quotes for strings, backticks for characters')
'use quotes for strings, backticks for characters')
} }
} }
if c == '\\`' { if c == '\\`' {
return '`' return '`'
} }
// Escapes a `'` character // 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 { fn (s &Scanner) expect(want string,start_pos int) bool {
end_pos := start_pos + want.len end_pos := start_pos + want.len
if start_pos < 0 || start_pos >= s.text.len { if start_pos < 0 || start_pos >= s.text.len {
return false return false
@ -794,8 +788,8 @@ fn (s &Scanner) expect(want string, start_pos int) bool {
if end_pos < 0 || end_pos > s.text.len { if end_pos < 0 || end_pos > s.text.len {
return false return false
} }
for pos in start_pos..end_pos { for pos in start_pos .. end_pos {
if s.text[pos] != want[pos-start_pos] { if s.text[pos] != want[pos - start_pos] {
return false return false
} }
} }
@ -806,10 +800,8 @@ fn (s mut Scanner) debug_tokens() {
s.pos = 0 s.pos = 0
s.started = false s.started = false
s.debug = true s.debug = true
fname := s.file_path.all_after(os.path_separator) fname := s.file_path.all_after(os.path_separator)
println('\n===DEBUG TOKENS $fname===') println('\n===DEBUG TOKENS $fname===')
for { for {
res := s.scan() res := s.scan()
tok := res.tok tok := res.tok
@ -828,13 +820,12 @@ fn (s mut Scanner) debug_tokens() {
} }
} }
fn (s mut Scanner) ignore_line() { fn (s mut Scanner) ignore_line() {
s.eat_to_end_of_line() s.eat_to_end_of_line()
s.inc_line_number() s.inc_line_number()
} }
fn (s mut Scanner) eat_to_end_of_line(){ fn (s mut Scanner) eat_to_end_of_line() {
for s.pos < s.text.len && s.text[s.pos] != `\n` { for s.pos < s.text.len && s.text[s.pos] != `\n` {
s.pos++ s.pos++
} }
@ -851,9 +842,8 @@ fn (s mut Scanner) inc_line_number() {
fn (s Scanner) line(n int) string { fn (s Scanner) line(n int) string {
mut res := '' mut res := ''
if n >= 0 && if n >= 0 && n < s.line_ends.len {
n < s.line_ends.len { nline_start := if n == 0 {0}else {s.line_ends[n - 1]}
nline_start := if n == 0 { 0 } else { s.line_ends[ n - 1 ] }
nline_end := s.line_ends[n] nline_end := s.line_ends[n]
if nline_start <= nline_end { if nline_start <= nline_end {
res = s.text[nline_start..nline_end] res = s.text[nline_start..nline_end]
@ -887,7 +877,7 @@ fn good_type_name(s string) bool {
return true return true
} }
for i in 2 .. s.len { for i in 2 .. s.len {
if s[i].is_capital() && s[i-1].is_capital() && s[i-2].is_capital() { if s[i].is_capital() && s[i - 1].is_capital() && s[i - 2].is_capital() {
return false return false
} }
} }
@ -898,11 +888,6 @@ fn good_type_name(s string) bool {
// registrationdate bad // registrationdate bad
fn (s &Scanner) validate_var_name(name string) { fn (s &Scanner) validate_var_name(name string) {
if name.len > 15 && !name.contains('_') { if name.len > 15 && !name.contains('_') {
s.error('bad variable name `$name`\n' + 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` ')
'looks like you have a multi-word name without separating them with `_`' +
'\nfor example, use `registration_date` instead of `registrationdate` ')
} }
} }

View File

@ -315,6 +315,7 @@ fn (p mut Parser) struct_init(typ string) string {
p.check_types(p.bool_expression(), f.typ) p.check_types(p.bool_expression(), f.typ)
if p.tok == .comma { if p.tok == .comma {
p.next() p.next()
p.fremove_last()
} }
if p.tok != .rcbr { if p.tok != .rcbr {
p.gen(',') p.gen(',')

View File

@ -161,8 +161,8 @@ fn (p mut Parser) fnext() {
if p.tokens[p.token_idx].tok in [.line_comment, .mline_comment] { if p.tokens[p.token_idx].tok in [.line_comment, .mline_comment] {
// Newline before the comment and after consts and closing } // Newline before the comment and after consts and closing }
if p.inside_const { if p.inside_const {
p.fgen_nl() //p.fgen_nl()
p.fgen_nl() //p.fgen_nl()
} }
//is_rcbr := p.tok == .rcbr //is_rcbr := p.tok == .rcbr
for p.token_idx < p.tokens.len - 1 { 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] [if vfmt]
fn (p &Parser) gen_fmt() { fn (p &Parser) gen_fmt() {
@ -237,7 +243,7 @@ fn (p &Parser) gen_fmt() {
if s == '' { if s == '' {
return return
} }
if !p.file_name.contains('parser.v') {return} if !p.file_name.contains('scanner.v') {return}
path := os.tmpdir() + '/' + p.file_name path := os.tmpdir() + '/' + p.file_name
println('generating ${path}') println('generating ${path}')
mut out := os.create(path) or { mut out := os.create(path) or {