diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3017fd653..f464a49032 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,37 +18,42 @@ jobs: ./v vet vlib/v - name: v fmt -verify run: | - ./v fmt -verify vlib/v/scanner/scanner.v - ./v fmt -verify vlib/v/parser/parser.v - ./v fmt -verify vlib/v/parser/fn.v - ./v fmt -verify vlib/v/checker/checker.v - ./v fmt -verify vlib/v/gen/cgen.v - ./v fmt -verify vlib/v/gen/fn.v - ./v fmt -verify vlib/v/gen/x64/gen.v - ./v fmt -verify vlib/v/table/table.v - ./v fmt -verify vlib/v/fmt/fmt.v ./v fmt -verify vlib/builtin/array.v ./v fmt -verify vlib/os/file.v - ./v fmt -verify vlib/v/util/errors.v - ./v fmt -verify vlib/v/util/suggestions.v - ./v fmt -verify vlib/v/util/util.v - ./v fmt -verify vlib/v/builder/builder.v - ./v fmt -verify vlib/v/builder/cc.v - ./v fmt -verify vlib/v/builder/compile.v - ./v fmt -verify vlib/v/builder/msvc.v ./v fmt -verify vlib/math/bits/bits.v ./v fmt -verify vlib/time/time.v ./v fmt -verify vlib/term/colors.v ./v fmt -verify vlib/term/term.v - ./v fmt -verify vlib/v/ast/scope.v - ./v fmt -verify vlib/v/checker/check_types.v - ./v fmt -verify vlib/v/table/atypes.v - ./v fmt -verify vlib/v/cflag/cflags.v - ./v fmt -verify vlib/v/table/cflags.v + ./v fmt -verify vlib/v/ast/ + ./v fmt -verify vlib/v/builder/ + ./v fmt -verify vlib/v/cflag/ + ./v fmt -verify vlib/v/checker/ + ./v fmt -verify vlib/v/depgraph/ + ./v fmt -verify vlib/v/doc/ + ./v fmt -verify vlib/v/errors/ + ./v fmt -verify vlib/v/eval/ + ./v fmt -verify vlib/v/fmt/ ./v fmt -verify vlib/v/gen/auto_str_methods.v - ./v fmt -verify vlib/v/parser/parse_type.v + ./v fmt -verify vlib/v/gen/cgen.v + ./v fmt -verify vlib/v/gen/cgen_test.v + ./v fmt -verify vlib/v/gen/cmain.v + ./v fmt -verify vlib/v/gen/comptime.v + ./v fmt -verify vlib/v/gen/fn.v ./v fmt -verify vlib/v/gen/json.v - + ./v fmt -verify vlib/v/gen/live.v + ./v fmt -verify vlib/v/gen/profile.v + ./v fmt -verify vlib/v/gen/sql.v + ./v fmt -verify vlib/v/gen/str.v + ./v fmt -verify vlib/v/gen/x64/elf.v + ./v fmt -verify vlib/v/gen/x64/elf_obj.v + ./v fmt -verify vlib/v/gen/x64/gen.v + ./v fmt -verify vlib/v/parser/ + ./v fmt -verify vlib/v/pref/ + ./v fmt -verify vlib/v/scanner/ + ./v fmt -verify vlib/v/table/ + ./v fmt -verify vlib/v/util/ + ./v fmt -verify vlib/v/vet/ + ./v fmt -verify vlib/v/vmod/ - name: v test-fmt run: ./v -silent test-fmt diff --git a/vlib/time/time.v b/vlib/time/time.v index 07953d3c6a..7479fec121 100644 --- a/vlib/time/time.v +++ b/vlib/time/time.v @@ -240,13 +240,13 @@ pub fn (t Time) relative_short() string { return '1m' } if secs < 3600 { - return '${secs/60}m' + return '${secs / 60}m' } if secs < 3600 * 24 { - return '${secs/3600}h' + return '${secs / 3600}h' } if secs < 3600 * 24 * 5 { - return '${secs/3600/24}d' + return '${secs / 3600 / 24}d' } if secs > 3600 * 24 * 10000 { return '' diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 9b9da0be58..7278ac1bbb 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -179,11 +179,11 @@ pub: pub struct InterfaceDecl { pub: - name string - field_names []string - is_pub bool - methods []FnDecl - pos token.Position + name string + field_names []string + is_pub bool + methods []FnDecl + pos token.Position pre_comments []Comment } @@ -602,8 +602,8 @@ pub: stmts []Stmt pos token.Position val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array -pub mut: // and the array cannot be indexed inside the loop +pub mut: key_type table.Type val_type table.Type cond_type table.Type @@ -625,10 +625,10 @@ pub: // #include etc pub struct HashStmt { pub: - mod string - pos token.Position + mod string + pos token.Position pub mut: - val string + val string kind string } diff --git a/vlib/v/builder/c.v b/vlib/v/builder/c.v index 0bbbcd3eac..4341ba0123 100644 --- a/vlib/v/builder/c.v +++ b/vlib/v/builder/c.v @@ -58,7 +58,9 @@ pub fn (mut b Builder) compile_c() { // println(files) } $if windows { - b.find_win_cc() or { verror(no_compiler_error) } + b.find_win_cc() or { + verror(no_compiler_error) + } // TODO Probably extend this to other OS's? } // v1 compiler files @@ -83,7 +85,8 @@ pub fn (mut b Builder) compile_c() { bundle_id := if b.pref.bundle_id != '' { b.pref.bundle_id } else { 'app.vlang.$bundle_name' } display_name := if b.pref.display_name != '' { b.pref.display_name } else { bundle_name } os.mkdir('$display_name\.app') - os.write_file('$display_name\.app/Info.plist', make_ios_plist(display_name, bundle_id, bundle_name, 1)) + os.write_file('$display_name\.app/Info.plist', make_ios_plist(display_name, bundle_id, + bundle_name, 1)) } b.cc() } diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 23c86ce4e0..bfd874b65d 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -761,7 +761,7 @@ fn (mut v Builder) build_thirdparty_obj_file(path string, moduleflags []cflag.CF return } println('$obj_path not found, building it...') - cfile := '${path[..path.len-2]}.c' + cfile := '${path[..path.len - 2]}.c' btarget := moduleflags.c_options_before_target() atarget := moduleflags.c_options_after_target() cppoptions := if v.pref.ccompiler.contains('++') { ' -fpermissive -w ' } else { '' } diff --git a/vlib/v/builder/generics.v b/vlib/v/builder/generics.v index 491e526fa3..8de2770727 100644 --- a/vlib/v/builder/generics.v +++ b/vlib/v/builder/generics.v @@ -5,7 +5,7 @@ import v.table // generic struct instantiations to concrete types pub fn (b &Builder) generic_struct_insts_to_concrete() { for idx, _ in b.table.types { - mut typ := unsafe { &b.table.types[idx] } + mut typ := unsafe {&b.table.types[idx]} if typ.kind == .generic_struct_inst { info := typ.info as table.GenericStructInst parent := b.table.types[info.parent_idx] diff --git a/vlib/v/builder/iosplist.v b/vlib/v/builder/iosplist.v index 08d5ee8735..29630a171c 100644 --- a/vlib/v/builder/iosplist.v +++ b/vlib/v/builder/iosplist.v @@ -36,4 +36,4 @@ fn make_ios_plist(display_name string, bundle_id string, bundle_name string, bun ' -} \ No newline at end of file +} diff --git a/vlib/v/builder/msvc.v b/vlib/v/builder/msvc.v index de92ab8032..974fc86804 100644 --- a/vlib/v/builder/msvc.v +++ b/vlib/v/builder/msvc.v @@ -331,7 +331,7 @@ fn (mut v Builder) build_thirdparty_obj_file_with_msvc(path string, moduleflags return } println('$obj_path not found, building it (with msvc)...') - cfiles := '${path[..path.len-2]}.c' + cfiles := '${path[..path.len - 2]}.c' flags := msvc_string_flags(moduleflags) inc_dirs := flags.inc_paths.join(' ') defines := flags.defines.join(' ') diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index c69593485f..2c7b050ad9 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1168,8 +1168,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } } if got_arg_typ != table.void_type { - c.error('cannot use type `$got_arg_sym.source_name` as type `$exp_arg_sym.source_name` in argument ${i+1} to `${left_type_sym.source_name}.$method_name`', - call_expr.pos) + c.error('cannot use type `$got_arg_sym.source_name` as type `$exp_arg_sym.source_name` in argument ${i + + 1} to `${left_type_sym.source_name}.$method_name`', call_expr.pos) } } param := if method.is_variadic && i >= method.params.len - 1 { method.params[method.params.len - @@ -1186,8 +1186,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } else { if param.is_mut && (!arg.is_mut || param.typ.share() != arg.share) { tok := arg.share.str() - c.error('`$call_expr.name` parameter `$param.name` is `$tok`, you need to provide `$tok` e.g. `$tok arg${i+1}`', - arg.expr.position()) + c.error('`$call_expr.name` parameter `$param.name` is `$tok`, you need to provide `$tok` e.g. `$tok arg${i + + 1}`', arg.expr.position()) } } } @@ -1460,8 +1460,8 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } else { if arg.is_mut && (!call_arg.is_mut || arg.typ.share() != call_arg.share) { tok := call_arg.share.str() - c.error('`$call_expr.name` parameter `$arg.name` is `$tok`, you need to provide `$tok` e.g. `$tok arg${i+1}`', - call_arg.expr.position()) + c.error('`$call_expr.name` parameter `$arg.name` is `$tok`, you need to provide `$tok` e.g. `$tok arg${i + + 1}`', call_arg.expr.position()) } } // Handle expected interface @@ -1492,11 +1492,11 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } if typ_sym.kind == .function && arg_typ_sym.kind == .function { candidate_fn_name := if typ_sym.source_name.starts_with('anon_') { 'anonymous function' } else { 'fn `$typ_sym.source_name`' } - c.error('cannot use $candidate_fn_name as function type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', - call_expr.pos) + c.error('cannot use $candidate_fn_name as function type `$arg_typ_sym.str()` in argument ${i + + 1} to `$fn_name`', call_expr.pos) } else { - c.error('cannot use type `$typ_sym.source_name` as type `$arg_typ_sym.source_name` in argument ${i+1} to `$fn_name`', - call_expr.pos) + c.error('cannot use type `$typ_sym.source_name` as type `$arg_typ_sym.source_name` in argument ${i + + 1} to `$fn_name`', call_expr.pos) } } } @@ -3197,21 +3197,27 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol mut is_exhaustive := true mut unhandled := []string{} match type_sym.info as info { - table.SumType { for v in info.variants { + table.SumType { + for v in info.variants { v_str := c.table.type_to_str(v) if v_str !in branch_exprs { is_exhaustive = false unhandled << '`$v_str`' } - } } + } + } // - table.Enum { for v in info.vals { + table.Enum { + for v in info.vals { if v !in branch_exprs { is_exhaustive = false unhandled << '`.$v`' } - } } - else { is_exhaustive = false } + } + } + else { + is_exhaustive = false + } } mut else_branch := node.branches[node.branches.len - 1] mut has_else := else_branch.is_else diff --git a/vlib/v/checker/tests/modules/overload_return_type.out b/vlib/v/checker/tests/modules/overload_return_type.out index d5f3df3537..a6d1346992 100644 --- a/vlib/v/checker/tests/modules/overload_return_type.out +++ b/vlib/v/checker/tests/modules/overload_return_type.out @@ -1,6 +1,6 @@ -vlib/v/checker/tests/modules/overload_return_type/main.v:8:11: error: cannot assign to `two`: expected `Point`, not `int` - 6 | one := Point {x:1, y:2} - 7 | mut two := Point {x:5, y:1} - 8 | two = one + two +vlib/v/checker/tests/modules/overload_return_type/main.v:14:8: error: cannot assign to `two`: expected `Point`, not `int` + 12 | y: 1 + 13 | } + 14 | two = one + two | ~~~~~~~~~ - 9 | } + 15 | } diff --git a/vlib/v/checker/tests/modules/overload_return_type/main.v b/vlib/v/checker/tests/modules/overload_return_type/main.v index fe27e3ee3f..b682c49697 100644 --- a/vlib/v/checker/tests/modules/overload_return_type/main.v +++ b/vlib/v/checker/tests/modules/overload_return_type/main.v @@ -3,7 +3,13 @@ module main import point { Point } fn main() { - one := Point {x:1, y:2} - mut two := Point {x:5, y:1} - two = one + two + one := Point{ + x: 1 + y: 2 + } + mut two := Point{ + x: 5 + y: 1 + } + two = one + two } diff --git a/vlib/v/checker/tests/modules/overload_return_type/point.v b/vlib/v/checker/tests/modules/overload_return_type/point.v index 5f6da09637..f0ccbf43ce 100644 --- a/vlib/v/checker/tests/modules/overload_return_type/point.v +++ b/vlib/v/checker/tests/modules/overload_return_type/point.v @@ -1,11 +1,11 @@ module point pub struct Point { - mut: - x int - y int +mut: + x int + y int } pub fn (a Point) +(b Point) int { - return a.x + b.x + return a.x + b.x } diff --git a/vlib/v/depgraph/depgraph.v b/vlib/v/depgraph/depgraph.v index e3c8fbd301..8370b585a2 100644 --- a/vlib/v/depgraph/depgraph.v +++ b/vlib/v/depgraph/depgraph.v @@ -35,8 +35,8 @@ pub fn (mut o OrderedDepMap) add(name string, deps []string) { for dep in deps { if dep !in d { d << dep + } else { } - else{} } o.set(name, d) } @@ -135,7 +135,7 @@ pub fn (graph &DepGraph) display() string { } pub fn (graph &DepGraph) display_cycles() string { - mut node_names := map[string]DepGraphNode + mut node_names := map[string]DepGraphNode{} for node in graph.nodes { node_names[node.name] = node } diff --git a/vlib/v/doc/doc.v b/vlib/v/doc/doc.v index e024fd1021..ed507c6472 100644 --- a/vlib/v/doc/doc.v +++ b/vlib/v/doc/doc.v @@ -56,7 +56,7 @@ pub mut: pub fn merge_comments(comments []ast.Comment) string { mut res := []string{} for comment in comments { - res << comment.text.trim_left('|') + res << comment.text.trim_left('\x01') } return res.join('\n') } @@ -74,7 +74,7 @@ pub fn get_comment_block_right_before(comments []ast.Comment) string { // located right above the top level statement. // break } - mut cmt_content := cmt.text.trim_left('|') + mut cmt_content := cmt.text.trim_left('\x01') if cmt_content.len == cmt.text.len || cmt.is_multi { // ignore /* */ style comments for now continue diff --git a/vlib/v/doc/doc_test.v b/vlib/v/doc/doc_test.v index 9cc32414e0..8036b0cae9 100644 --- a/vlib/v/doc/doc_test.v +++ b/vlib/v/doc/doc_test.v @@ -1,10 +1,9 @@ -//import v.table -//import v.doc -//import v.pref - +// import v.table +// import v.doc +// import v.pref // fn test_vdoc() { -// mut prefs := &pref.Preferences{} -// prefs.fill_with_defaults() -// table := table.new_table() -// println(doc.doc('net', table, prefs)) +// mut prefs := &pref.Preferences{} +// prefs.fill_with_defaults() +// table := table.new_table() +// println(doc.doc('net', table, prefs)) // } diff --git a/vlib/v/errors/errors.v b/vlib/v/errors/errors.v index 6b342fd507..a1cb6bfde8 100644 --- a/vlib/v/errors/errors.v +++ b/vlib/v/errors/errors.v @@ -12,7 +12,7 @@ pub enum Reporter { pub struct Error { pub: message string - details string + details string file_path string pos token.Position backtrace string diff --git a/vlib/v/eval/eval.v b/vlib/v/eval/eval.v index 13c2ce5d0f..aee1475909 100644 --- a/vlib/v/eval/eval.v +++ b/vlib/v/eval/eval.v @@ -34,14 +34,14 @@ pub fn (mut e Eval) eval(file ast.File, table &table.Table) string { fn print_object(o Object) { match o { - int { println(it) } + int { println(o) } else { println('unknown object') } } } pub fn (o Object) str() string { match o { - int { return it.str() } + int { return o.str() } else { println('unknown object') } } return '' @@ -53,18 +53,18 @@ fn (mut e Eval) stmt(node ast.Stmt) string { // TODO; replaced VarDecl } ast.ExprStmt { - o := e.expr(it.expr) + o := e.expr(node.expr) print('out: ') print_object(o) return o.str() } // ast.StructDecl { - // println('s decl') + // println('s decl') // } // ast.VarDecl { - // e.vars[it.name] = Var{ - // value: e.expr(it.expr) - // } + // e.vars[it.name] = Var{ + // value: e.expr(it.expr) + // } // } else {} } @@ -74,20 +74,20 @@ fn (mut e Eval) stmt(node ast.Stmt) string { fn (mut e Eval) expr(node ast.Expr) Object { match node { ast.IntegerLiteral { - return it.val + return node.val } ast.Ident { - print_object(it.value) + print_object(node.value) // Find the variable - v := e.vars[it.name] + v := e.vars[node.name] return v.value } ast.InfixExpr { - e.checker.infix_expr(mut it) + e.checker.infix_expr(mut node) // println('bin $it.op') - left := e.expr(it.left) as int - right := e.expr(it.right) as int - match it.op { + left := e.expr(node.left) as int + right := e.expr(node.right) as int + match node.op { .plus { return left + right } .mul { return left * right } else {} diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 2c876d2383..e294efd70e 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -38,7 +38,6 @@ pub mut: file ast.File did_imports bool is_assign bool - is_inside_interp bool auto_imports []string // automatically inserted imports that the user forgot to specify import_pos int // position of the imports in the resulting string for later autoimports insertion used_imports []string // to remove unused imports @@ -609,55 +608,48 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { } end_pos := field.pos.pos + field.pos.len comments := field.comments - if comments.len == 0 { - f.write('\t$field.name ') - f.write(strings.repeat(` `, max - field.name.len)) - f.write(field_types[i]) - if field.attrs.len > 0 && field.attrs[0].name != 'ref_only' { // TODO a bug with [ref_only] attr being added to fields, fix it - f.write(strings.repeat(` `, max_type - field_types[i].len)) - f.inline_attrs(field.attrs) - } - if field.has_default_expr { - f.write(' = ') - f.prefix_expr_cast_expr(field.default_expr) - } - f.write('\n') - continue - } // Handle comments before field - mut j := 0 - for j < comments.len && comments[j].pos.pos < field.pos.pos { + mut comm_idx := 0 + for comm_idx < comments.len && comments[comm_idx].pos.pos < field.pos.pos { f.indent++ f.empty_line = true - f.comment(comments[j], { - inline: true - }) + f.comment(comments[comm_idx], {}) f.writeln('') f.indent-- - j++ + comm_idx++ } f.write('\t$field.name ') // Handle comments between field name and type mut comments_len := 0 - for j < comments.len && comments[j].pos.pos < end_pos { - comment := '/* ${comments[j].text} */ ' // TODO: handle in a function - comments_len += comment.len - f.write(comment) - j++ + for comm_idx < comments.len && comments[comm_idx].pos.pos < end_pos { + comment_text := '/* ${comments[comm_idx].text} */ ' // TODO handle in a function + comments_len += comment_text.len + f.write(comment_text) + comm_idx++ } f.write(strings.repeat(` `, max - field.name.len - comments_len)) f.write(field_types[i]) - f.inline_attrs(field.attrs) + if field.attrs.len > 0 && field.attrs[0].name != 'ref_only' { // TODO a bug with [ref_only] attr being added to fields, fix it + f.write(strings.repeat(` `, max_type - field_types[i].len)) + f.inline_attrs(field.attrs) + } if field.has_default_expr { f.write(' = ') f.prefix_expr_cast_expr(field.default_expr) } // Handle comments after field type (same line) - for j < comments.len && field.pos.line_nr == comments[j].pos.line_nr { - f.write(' // ${comments[j].text}') // TODO: handle in a function - j++ + if comm_idx < comments.len { + if comments[comm_idx].pos.line_nr > field.pos.line_nr { + f.writeln('') + } else { + f.write(' ') + } + f.comments(comments[comm_idx..], { + level: .indent + }) + } else { + f.writeln('') } - f.write('\n') } f.comments_after_last_field(node.end_comments) f.writeln('}\n') @@ -1011,7 +1003,6 @@ pub fn (mut f Fmt) expr(node ast.Expr) { } else { f.write("'") } - f.is_inside_interp = true for i, val in node.vals { f.write(val) if i >= node.exprs.len { @@ -1028,7 +1019,6 @@ pub fn (mut f Fmt) expr(node ast.Expr) { f.expr(node.exprs[i]) } } - f.is_inside_interp = false if contains_single_quote { f.write('"') } else { @@ -1093,11 +1083,7 @@ pub fn (mut f Fmt) call_args(args []ast.CallArg) { } f.expr(arg.expr) if i < args.len - 1 { - if f.is_inside_interp { - f.write(',') - } else { - f.write(', ') - } + f.write(', ') } } } @@ -1145,16 +1131,20 @@ enum CommentsLevel { indent } +// CommentsOptions defines the way comments are going to be written +// - has_nl: adds an newline at the end of the list of comments +// - inline: single-line comments will be on the same line as the last statement +// - level: either .keep (don't indent), or .indent (increment indentation) struct CommentsOptions { has_nl bool = true inline bool - level CommentsLevel = .keep + level CommentsLevel } pub fn (mut f Fmt) comment(node ast.Comment, options CommentsOptions) { if !node.text.contains('\n') { - is_separate_line := !options.inline || node.text.starts_with('|') - mut s := if node.text.starts_with('|') { node.text[1..] } else { node.text } + is_separate_line := !options.inline || node.text.starts_with('\x01') + mut s := if node.text.starts_with('\x01') { node.text[1..] } else { node.text } if s == '' { s = '//' } else { @@ -1258,73 +1248,67 @@ pub fn (mut f Fmt) lock_expr(lex ast.LockExpr) { } pub fn (mut f Fmt) infix_expr(node ast.InfixExpr) { - if f.is_inside_interp { - f.expr(node.left) - f.write('$node.op.str()') - f.expr(node.right) - } else { - buffering_save := f.buffering - if !f.buffering { - f.out_save = f.out - f.out = strings.new_builder(60) - f.buffering = true - } - f.expr(node.left) - is_one_val_array_init := node.op in [.key_in, .not_in] && - node.right is ast.ArrayInit && (node.right as ast.ArrayInit).exprs.len == 1 - if is_one_val_array_init { - // `var in [val]` => `var == val` - f.write(if node.op == .key_in { - ' == ' - } else { - ' != ' - }) - } else { - f.write(' $node.op.str() ') - } - f.expr_bufs << f.out.str() - mut penalty := 3 - match node.left as left { - ast.InfixExpr { - if int(token.precedences[left.op]) > int(token.precedences[node.op]) { - penalty-- - } - } - ast.ParExpr { - penalty = 1 - } - else {} - } - match node.right as right { - ast.InfixExpr { penalty-- } - ast.ParExpr { penalty = 1 } - else {} - } - f.penalties << penalty - // combine parentheses level with operator precedence to form effective precedence - f.precedences << int(token.precedences[node.op]) | (f.par_level << 16) + buffering_save := f.buffering + if !f.buffering { + f.out_save = f.out f.out = strings.new_builder(60) f.buffering = true - if is_one_val_array_init { - // `var in [val]` => `var == val` - f.expr((node.right as ast.ArrayInit).exprs[0]) + } + f.expr(node.left) + is_one_val_array_init := node.op in [.key_in, .not_in] && + node.right is ast.ArrayInit && (node.right as ast.ArrayInit).exprs.len == 1 + if is_one_val_array_init { + // `var in [val]` => `var == val` + f.write(if node.op == .key_in { + ' == ' } else { - f.expr(node.right) - } - if !buffering_save && f.buffering { // now decide if and where to break - f.expr_bufs << f.out.str() - f.out = f.out_save - f.buffering = false - f.adjust_complete_line() - for i, p in f.penalties { - f.write(f.expr_bufs[i]) - f.wrap_long_line(p, true) + ' != ' + }) + } else { + f.write(' $node.op.str() ') + } + f.expr_bufs << f.out.str() + mut penalty := 3 + match node.left as left { + ast.InfixExpr { + if int(token.precedences[left.op]) > int(token.precedences[node.op]) { + penalty-- } - f.write(f.expr_bufs[f.expr_bufs.len - 1]) - f.expr_bufs = []string{} - f.penalties = []int{} - f.precedences = []int{} } + ast.ParExpr { + penalty = 1 + } + else {} + } + match node.right as right { + ast.InfixExpr { penalty-- } + ast.ParExpr { penalty = 1 } + else {} + } + f.penalties << penalty + // combine parentheses level with operator precedence to form effective precedence + f.precedences << int(token.precedences[node.op]) | (f.par_level << 16) + f.out = strings.new_builder(60) + f.buffering = true + if is_one_val_array_init { + // `var in [val]` => `var == val` + f.expr((node.right as ast.ArrayInit).exprs[0]) + } else { + f.expr(node.right) + } + if !buffering_save && f.buffering { // now decide if and where to break + f.expr_bufs << f.out.str() + f.out = f.out_save + f.buffering = false + f.adjust_complete_line() + for i, p in f.penalties { + f.write(f.expr_bufs[i]) + f.wrap_long_line(p, true) + } + f.write(f.expr_bufs[f.expr_bufs.len - 1]) + f.expr_bufs = []string{} + f.penalties = []int{} + f.precedences = []int{} } } @@ -1499,13 +1483,9 @@ pub fn (mut f Fmt) match_expr(it ast.MatchExpr) { if branch.stmts.len == 0 { continue } - stmt := branch.stmts[0] - if stmt is ast.ExprStmt { - // If expressions inside match branches can't be one a single line - if !expr_is_single_line(stmt.expr) { - single_line = false - break - } + if !stmt_is_single_line(branch.stmts[0]) { + single_line = false + break } } for branch in it.branches { @@ -1595,6 +1575,15 @@ fn (mut f Fmt) write_language_prefix(lang table.Language) { } } +fn stmt_is_single_line(stmt ast.Stmt) bool { + match stmt { + ast.ExprStmt { return expr_is_single_line(stmt.expr) } + ast.Return { return true } + ast.AssignStmt { return true } + else { return false } + } +} + fn expr_is_single_line(expr ast.Expr) bool { match expr { ast.IfExpr { return false } diff --git a/vlib/v/fmt/fmt_keep_test.v b/vlib/v/fmt/fmt_keep_test.v index b474c30f03..9ecbc8279d 100644 --- a/vlib/v/fmt/fmt_keep_test.v +++ b/vlib/v/fmt/fmt_keep_test.v @@ -47,31 +47,31 @@ fn test_fmt() { opath := ipath expected_ocontent := os.read_file(opath) or { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('cannot read from ${vrelpath}')) + eprintln(fmt_bench.step_message_fail('cannot read from $vrelpath')) continue } table := table.new_table() file_ast := parser.parse_file(ipath, table, .parse_comments, &pref.Preferences{ - is_fmt: true, - ccompiler: 'gcc' - }, &ast.Scope{ - parent: 0 + is_fmt: true + ccompiler: 'gcc' + }, &ast.Scope{ + parent: 0 }) result_ocontent := fmt.fmt(file_ast, table, false) if expected_ocontent != result_ocontent { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('file ${vrelpath} after formatting, does not look as expected.')) + eprintln(fmt_bench.step_message_fail('file $vrelpath after formatting, does not look as expected.')) if diff_cmd == '' { eprintln('>> sorry, but no working "diff" CLI command can be found') continue } - vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_${ifilename}') + vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename') os.write_file(vfmt_result_file, result_ocontent) eprintln(util.color_compare_files(diff_cmd, opath, vfmt_result_file)) continue } fmt_bench.ok() - eprintln(fmt_bench.step_message_ok('${vrelpath}')) + eprintln(fmt_bench.step_message_ok('$vrelpath')) } fmt_bench.stop() eprintln(term.h_divider('-')) diff --git a/vlib/v/fmt/fmt_test.v b/vlib/v/fmt/fmt_test.v index 46486443db..d526032fd5 100644 --- a/vlib/v/fmt/fmt_test.v +++ b/vlib/v/fmt/fmt_test.v @@ -23,7 +23,9 @@ fn test_fmt() { } vroot := os.dir(vexe) tmpfolder := os.temp_dir() - diff_cmd := util.find_working_diff_command() or { '' } + diff_cmd := util.find_working_diff_command() or { + '' + } mut fmt_bench := benchmark.new_benchmark() // Lookup the existing test _input.vv files: input_files := os.walk_ext('$vroot/vlib/v/fmt/tests', '_input.vv') @@ -35,35 +37,35 @@ fn test_fmt() { opath := ipath.replace('_input.vv', '_expected.vv') if !os.exists(opath) { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('missing file ${opath}')) + eprintln(fmt_bench.step_message_fail('missing file $opath')) continue } expected_ocontent := os.read_file(opath) or { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('cannot read from ${opath}')) + eprintln(fmt_bench.step_message_fail('cannot read from $opath')) continue } table := table.new_table() file_ast := parser.parse_file(ipath, table, .parse_comments, &pref.Preferences{ - is_fmt: true - }, &ast.Scope{ - parent: 0 + is_fmt: true + }, &ast.Scope{ + parent: 0 }) result_ocontent := fmt.fmt(file_ast, table, false) if expected_ocontent != result_ocontent { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('file ${ipath} after formatting, does not look as expected.')) + eprintln(fmt_bench.step_message_fail('file $ipath after formatting, does not look as expected.')) if diff_cmd == '' { eprintln('>> sorry, but no working "diff" CLI command can be found') continue } - vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_${ifilename}') + vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename') os.write_file(vfmt_result_file, result_ocontent) eprintln(util.color_compare_files(diff_cmd, opath, vfmt_result_file)) continue } fmt_bench.ok() - eprintln(fmt_bench.step_message_ok('${ipath}')) + eprintln(fmt_bench.step_message_ok('$ipath')) } fmt_bench.stop() eprintln(term.h_divider('-')) diff --git a/vlib/v/fmt/fmt_vlib_test.v b/vlib/v/fmt/fmt_vlib_test.v index 33bdfd8c76..5733744231 100644 --- a/vlib/v/fmt/fmt_vlib_test.v +++ b/vlib/v/fmt/fmt_vlib_test.v @@ -40,30 +40,30 @@ fn test_vlib_fmt() { opath := ipath expected_ocontent := os.read_file(opath) or { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('cannot read from ${opath}')) + eprintln(fmt_bench.step_message_fail('cannot read from $opath')) continue } table := table.new_table() file_ast := parser.parse_file(ipath, table, .parse_comments, &pref.Preferences{ - is_fmt: true - }, &ast.Scope{ - parent: 0 + is_fmt: true + }, &ast.Scope{ + parent: 0 }) result_ocontent := fmt.fmt(file_ast, table, false) if expected_ocontent != result_ocontent { fmt_bench.fail() - eprintln(fmt_bench.step_message_fail('file ${ipath} after formatting, does not look as expected.')) + eprintln(fmt_bench.step_message_fail('file $ipath after formatting, does not look as expected.')) if diff_cmd == '' { eprintln('>> sorry, but no working "diff" CLI command can be found') continue } - vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_${ifilename}') + vfmt_result_file := os.join_path(tmpfolder, 'vfmt_run_over_$ifilename') os.write_file(vfmt_result_file, result_ocontent) eprintln(util.color_compare_files(diff_cmd, opath, vfmt_result_file)) continue } fmt_bench.ok() - eprintln(fmt_bench.step_message_ok('${ipath}')) + eprintln(fmt_bench.step_message_ok('$ipath')) } fmt_bench.stop() eprintln(term.h_divider('-')) diff --git a/vlib/v/fmt/tests/anon_fn_as_param_keep.vv b/vlib/v/fmt/tests/anon_fn_as_param_keep.vv index 15fe3d7a6a..dd5f3180ea 100644 --- a/vlib/v/fmt/tests/anon_fn_as_param_keep.vv +++ b/vlib/v/fmt/tests/anon_fn_as_param_keep.vv @@ -1,3 +1,7 @@ pub fn (a []int) reduce(iter fn (int, int) int, accum_start int) int { iter(accum_start) } + +pub fn test_anon_fn_void(func fn ()) int { + return 0 +} diff --git a/vlib/v/fmt/tests/string_interpolation_expected.vv b/vlib/v/fmt/tests/string_interpolation_expected.vv index b8d97d5c98..4b0944b11a 100644 --- a/vlib/v/fmt/tests/string_interpolation_expected.vv +++ b/vlib/v/fmt/tests/string_interpolation_expected.vv @@ -27,6 +27,6 @@ fn main() { println('$st.a.xy${ar.a[2].xy}$aa.xy$z') println('${st.a.xy}ya ${ar.a[2].xy}X2 ${aa.xy}.b ${z}3') println('${z:-5} ${z:+5.3} ${z:+09.3f} ${z:-7.2} ${z:+09} ${z:08.3f}') - println('$ar.f() ${ar.g(1,2)} ${ar.a}() ${z}(') - println('${z>12.3*z-3} ${@VEXE} ${4*5}') + println('$ar.f() ${ar.g(1, 2)} ${ar.a}() ${z}(') + println('${z > 12.3 * z - 3} ${@VEXE} ${4 * 5}') } diff --git a/vlib/v/fmt/tests/structs_expected.vv b/vlib/v/fmt/tests/structs_expected.vv index 1b3fde3628..963087549d 100644 --- a/vlib/v/fmt/tests/structs_expected.vv +++ b/vlib/v/fmt/tests/structs_expected.vv @@ -28,7 +28,9 @@ mut: // 1 // 2 // 3 - somefield /* 4 */ /* 5 */ int // 6 // 7 // 8 + somefield /* 4 */ /* 5 */ int // 6 + // 7 + // 8 /* 9 10 diff --git a/vlib/v/gen/auto_str_methods.v b/vlib/v/gen/auto_str_methods.v index ab39696d9b..96150dbf02 100644 --- a/vlib/v/gen/auto_str_methods.v +++ b/vlib/v/gen/auto_str_methods.v @@ -170,7 +170,7 @@ fn (mut g Gen) gen_str_for_array_fixed(info table.ArrayFixed, styp string, str_f g.auto_str_funcs.writeln('\t\tstrings__Builder_write(&sb, ${elem_str_fn_name}(*a[i]));') } } - g.auto_str_funcs.writeln('\t\tif (i < ${info.size-1}) {') + g.auto_str_funcs.writeln('\t\tif (i < ${info.size - 1}) {') g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write(&sb, tos_lit(", "));') g.auto_str_funcs.writeln('\t\t}') g.auto_str_funcs.writeln('\t}') @@ -337,7 +337,7 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st } g.auto_str_funcs.writeln('\t\t"%.*s\\000 $field.name: $fmt\\n"') } - g.auto_str_funcs.write('\t\t"%.*s\\000}", ${2*(info.fields.len+1)}') + g.auto_str_funcs.write('\t\t"%.*s\\000}", ${2 * (info.fields.len + 1)}') if info.fields.len > 0 { g.auto_str_funcs.write(',\n\t\t') for i, field in info.fields { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index f4cf7b7792..298ceaa316 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2601,7 +2601,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { node.op in [.eq, .ne, .gt, .lt, .ge, .le] { bitsize := if unaliased_left.idx() == table.u32_type_idx && unaliased_right.idx() != table.i64_type_idx { 32 } else { 64 } - g.write('_us${bitsize}_${cmp_str[int(node.op)-int(token.Kind.eq)]}(') + g.write('_us${bitsize}_${cmp_str[int(node.op) - int(token.Kind.eq)]}(') g.expr(node.left) g.write(',') g.expr(node.right) @@ -2610,7 +2610,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { node.op in [.eq, .ne, .gt, .lt, .ge, .le] { bitsize := if unaliased_right.idx() == table.u32_type_idx && unaliased_left.idx() != table.i64_type_idx { 32 } else { 64 } - g.write('_us${bitsize}_${cmp_rev[int(node.op)-int(token.Kind.eq)]}(') + g.write('_us${bitsize}_${cmp_rev[int(node.op) - int(token.Kind.eq)]}(') g.expr(node.right) g.write(',') g.expr(node.left) @@ -4016,7 +4016,7 @@ fn verror(s string) { } fn (g &Gen) error(s string, pos token.Position) { - p := if pos.line_nr == 0 { '?' } else { '${pos.line_nr+1}' } + p := if pos.line_nr == 0 { '?' } else { '${pos.line_nr + 1}' } util.verror('$g.file.path:$p: cgen error', s) } @@ -4151,7 +4151,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) { styp, base := g.optional_type_name(field.typ) g.optionals << styp g.typedefs2.writeln('typedef struct $styp $styp;') - g.type_definitions.writeln('${g.optional_type_text(styp,base)};') + g.type_definitions.writeln('${g.optional_type_text(styp, base)};') g.type_definitions.write(last_text) } type_name := g.typ(field.typ) @@ -5031,7 +5031,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt) { g.writeln(';') } for i, arg in expr.args { - g.write('$arg_tmp_var->arg${i+1} = ') + g.write('$arg_tmp_var->arg${i + 1} = ') g.expr(arg.expr) g.writeln(';') } @@ -5056,7 +5056,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt) { } else { for i, arg in expr.args { styp := g.typ(arg.typ) - g.type_definitions.writeln('\t$styp arg${i+1};') + g.type_definitions.writeln('\t$styp arg${i + 1};') } } g.type_definitions.writeln('} $wrapper_struct_name;') @@ -5070,7 +5070,7 @@ fn (mut g Gen) go_stmt(node ast.GoStmt) { } } for i in 0 .. expr.args.len { - g.gowrappers.write('arg->arg${i+1}') + g.gowrappers.write('arg->arg${i + 1}') if i < expr.args.len - 1 { g.gowrappers.write(', ') } diff --git a/vlib/v/gen/cgen_test.v b/vlib/v/gen/cgen_test.v index 1cb8dbb65b..c34f239c97 100644 --- a/vlib/v/gen/cgen_test.v +++ b/vlib/v/gen/cgen_test.v @@ -32,14 +32,14 @@ fn test_c_files() { res = res[..pos] + res[end + 15..] } if compare_texts(res, ctext, path) { - println('${term_ok} ${i}') + println('$term_ok $i') } else { assert false } } } -fn compare_texts(a, b, path string) bool { +fn compare_texts(a string, b string, path string) bool { lines_a_ := a.trim_space().split_into_lines() lines_b_ := b.trim_space().split_into_lines() lines_a := lines_a_.filter(it != '') @@ -60,8 +60,8 @@ fn compare_texts(a, b, path string) bool { } line_b := lines_b[i] if line_a.trim_space() != line_b.trim_space() { - println('${path}: Got\n$a') - println('${path}:${i}: ${term_fail}') + println('$path: Got\n$a') + println('$path:$i: $term_fail') println(term.bold(term.bright_yellow('actual : ')) + line_a) println(term.green('expected: ') + line_b) println(lines_b[i + 1]) @@ -72,8 +72,3 @@ fn compare_texts(a, b, path string) bool { } return true } - -fn test_nested_if() { - a := if true { if true { 'a' } else { 'b' } } else { 'c' } - assert a == 'a' -} diff --git a/vlib/v/gen/cmain.v b/vlib/v/gen/cmain.v index e7dd4e478b..f5746b3600 100644 --- a/vlib/v/gen/cmain.v +++ b/vlib/v/gen/cmain.v @@ -35,7 +35,7 @@ fn (mut g Gen) gen_vlines_reset() { g.vlines_path = util.vlines_escape_path(g.pref.out_name_c, g.pref.ccompiler) g.writeln('') g.writeln('\n// Reset the file/line numbers') - g.writeln('\n#line $lines_so_far "${g.vlines_path}"') + g.writeln('\n#line $lines_so_far "$g.vlines_path"') g.writeln('') } } @@ -111,7 +111,6 @@ void (_vsokol_cleanup_userdata_cb)(void* user_data) { } ') } - g.writeln('// The sokol_main entry point on Android sapp_desc sokol_main(int argc, char* argv[]) { (void)argc; (void)argv; diff --git a/vlib/v/gen/comptime.v b/vlib/v/gen/comptime.v index b776997372..d6fcc6174b 100644 --- a/vlib/v/gen/comptime.v +++ b/vlib/v/gen/comptime.v @@ -53,9 +53,9 @@ fn (mut g Gen) comptime_call(node ast.ComptimeCall) { if m.params[i].typ.is_int() || m.params[i].typ.idx() == table.bool_type_idx { // Gets the type name and cast the string to the type with the string_ function type_name := g.table.types[int(m.params[i].typ)].str() - g.write('string_${type_name}(((string*)${node.args_var}.data) [${i-1}])') + g.write('string_${type_name}(((string*)${node.args_var}.data) [${i - 1}])') } else { - g.write('((string*)${node.args_var}.data) [${i-1}] ') + g.write('((string*)${node.args_var}.data) [${i - 1}] ') } if i < m.params.len - 1 { g.write(', ') @@ -106,7 +106,9 @@ fn (mut g Gen) comp_if(node ast.IfExpr) { stmt_str := g.go_before_stmt(0) g.write(tabs[g.indent]) stmt_str.trim_space() - } else { '' } + } else { + '' + } for i, branch in node.branches { start_pos := g.out.len if i == node.branches.len - 1 && node.has_else { @@ -132,7 +134,7 @@ fn (mut g Gen) comp_if(node ast.IfExpr) { g.indent++ g.writeln('$styp $tmp;') g.writeln('{') - g.stmts(branch.stmts[0 .. len - 1]) + g.stmts(branch.stmts[0..len - 1]) g.write('\t$tmp = ') g.stmt(last) g.writeln('}') @@ -146,13 +148,21 @@ fn (mut g Gen) comp_if(node ast.IfExpr) { } else { // Only wrap the contents in {} if we're inside a function, not on the top level scope should_create_scope := g.fn_decl != 0 - if should_create_scope { g.writeln('{') } + if should_create_scope { + g.writeln('{') + } g.stmts(branch.stmts) - if should_create_scope { g.writeln('}') } + if should_create_scope { + g.writeln('}') + } } g.defer_ifdef = '' } - if node.is_expr { g.write('#endif') } else { g.writeln('#endif') } + if node.is_expr { + g.write('#endif') + } else { + g.writeln('#endif') + } } fn (mut g Gen) comp_if_expr(cond ast.Expr) { @@ -161,13 +171,16 @@ fn (mut g Gen) comp_if_expr(cond ast.Expr) { g.write('(') g.comp_if_expr(cond.expr) g.write(')') - } ast.PrefixExpr { + } + ast.PrefixExpr { g.write(cond.op.str()) g.comp_if_expr(cond.right) - } ast.PostfixExpr { + } + ast.PostfixExpr { ifdef := g.comp_if_to_ifdef((cond.expr as ast.Ident).name, true) g.write('defined($ifdef)') - } ast.InfixExpr { + } + ast.InfixExpr { match cond.op { .and, .logical_or { g.comp_if_expr(cond.left) @@ -180,14 +193,18 @@ fn (mut g Gen) comp_if_expr(cond ast.Expr) { exp_type := g.comptime_var_type_map[name] got_type := (cond.right as ast.Type).typ g.write('$exp_type == $got_type') - } .eq, .ne { + } + .eq, .ne { // TODO Implement `$if method.args.len == 1` - } else {} + } + else {} } - } ast.Ident { + } + ast.Ident { ifdef := g.comp_if_to_ifdef(cond.name, false) g.write('defined($ifdef)') - } else {} + } + else {} } } diff --git a/vlib/v/gen/sql.v b/vlib/v/gen/sql.v index eb1558c53d..04972ffff8 100644 --- a/vlib/v/gen/sql.v +++ b/vlib/v/gen/sql.v @@ -48,7 +48,7 @@ fn (mut g Gen) sql_stmt(node ast.SqlStmt) { if field.name == 'id' { continue } - g.write('?${i+0}') + g.write('?${i + 0}') if i < node.fields.len - 1 { g.write(', ') } @@ -78,9 +78,9 @@ fn (mut g Gen) sql_stmt(node ast.SqlStmt) { } x := '${node.object_var_name}.$field.name' if field.typ == table.string_type { - g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i+0}, ${x}.str, ${x}.len, 0);') + g.writeln('sqlite3_bind_text($g.sql_stmt_name, ${i + 0}, ${x}.str, ${x}.len, 0);') } else { - g.writeln('sqlite3_bind_int($g.sql_stmt_name, ${i+0}, $x); // stmt') + g.writeln('sqlite3_bind_int($g.sql_stmt_name, ${i + 0}, $x); // stmt') } } } diff --git a/vlib/v/gen/x64/elf.v b/vlib/v/gen/x64/elf.v index e232cc9581..e102435b8b 100644 --- a/vlib/v/gen/x64/elf.v +++ b/vlib/v/gen/x64/elf.v @@ -34,11 +34,7 @@ const ( ) pub fn (mut g Gen) generate_elf_header() { - g.buf << [byte(mag0), - mag1, - mag2, - mag3 - ] + g.buf << [byte(mag0), mag1, mag2, mag3] g.buf << elfclass64 // file class g.buf << elfdata2lsb // data encoding g.buf << ev_current // file version diff --git a/vlib/v/gen/x64/tests/x64_test.v b/vlib/v/gen/x64/tests/x64_test.v index b10cac7596..154ffe5ad1 100644 --- a/vlib/v/gen/x64/tests/x64_test.v +++ b/vlib/v/gen/x64/tests/x64_test.v @@ -32,7 +32,7 @@ fn test_x64() { bench.step() full_test_path := os.real_path(test) println('x.v: $wrkdir/x.v') - os.system('cp ${dir}/${test} $wrkdir/x.v') // cant run .vv file + os.system('cp $dir/$test $wrkdir/x.v') // cant run .vv file os.exec('$vexe -o exe -x64 $wrkdir/x.v') or { bench.fail() eprintln(bench.step_message_fail('x64 $test failed')) diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v index 362b84dafe..b1afd45f5e 100644 --- a/vlib/v/parser/assign.v +++ b/vlib/v/parser/assign.v @@ -63,9 +63,15 @@ fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool { } } } - ast.InfixExpr { return p.check_cross_variables(exprs, val_.left) || p.check_cross_variables(exprs, val_.right) } - ast.PrefixExpr { return p.check_cross_variables(exprs, val_.right) } - ast.PostfixExpr { return p.check_cross_variables(exprs, val_.expr) } + ast.InfixExpr { + return p.check_cross_variables(exprs, val_.left) || p.check_cross_variables(exprs, val_.right) + } + ast.PrefixExpr { + return p.check_cross_variables(exprs, val_.right) + } + ast.PostfixExpr { + return p.check_cross_variables(exprs, val_.expr) + } ast.SelectorExpr { for expr in exprs { if expr.str() == val.str() { @@ -119,7 +125,8 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme share = iv.share if iv.is_static { if !p.pref.translated { - p.error_with_pos('static variables are supported only in -translated mode', lx.pos) + p.error_with_pos('static variables are supported only in -translated mode', + lx.pos) } is_static = true } diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index eff9ddd792..807bf0493a 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -22,7 +22,7 @@ fn (mut p Parser) hash() ast.HashStmt { val := p.tok.lit kind := val.all_before(' ') p.next() - //p.trace('a.v', 'kind: ${kind:-10s} | pos: ${pos:-45s} | hash: $val') + // p.trace('a.v', 'kind: ${kind:-10s} | pos: ${pos:-45s} | hash: $val') return ast.HashStmt{ mod: p.mod val: val diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index acb7914932..7f7feb68aa 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -72,7 +72,8 @@ fn (mut p Parser) array_init() ast.ArrayInit { last_pos = p.tok.position() p.check(.rcbr) } else { - p.warn_with_pos('use e.g. `x := [1]Type{}` instead of `x := [1]Type`', last_pos) + p.warn_with_pos('use e.g. `x := [1]Type{}` instead of `x := [1]Type`', + last_pos) } } else { if p.tok.kind == .not { diff --git a/vlib/v/parser/lock.v b/vlib/v/parser/lock.v index 31a38b406e..2889456119 100644 --- a/vlib/v/parser/lock.v +++ b/vlib/v/parser/lock.v @@ -13,8 +13,6 @@ fn (mut p Parser) lock_expr() ast.LockExpr { for p.tok.kind == .name { lockeds << ast.Ident{ language: table.Language.v - // kind is set in checker once ident is processed - // kind: .variable pos: p.tok.position() mod: p.mod name: p.tok.lit diff --git a/vlib/v/parser/module.v b/vlib/v/parser/module.v index 19857c7b47..0c6d26d44c 100644 --- a/vlib/v/parser/module.v +++ b/vlib/v/parser/module.v @@ -36,8 +36,8 @@ fn (mut p Parser) register_auto_import(alias string) { p.imports[alias] = alias p.table.imports << alias node := ast.Import{ - pos: p.tok.position() - mod: alias + pos: p.tok.position() + mod: alias alias: alias } p.ast_imports << node diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index edfb1cad1d..c0576a6256 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -21,7 +21,8 @@ pub struct Parser { pref &pref.Preferences mut: scanner &scanner.Scanner - comments_mode scanner.CommentsMode = .skip_comments // see comment in parse_file + comments_mode scanner.CommentsMode = .skip_comments + // see comment in parse_file tok token.Token prev_tok token.Token peek_tok token.Token @@ -832,7 +833,7 @@ pub fn (mut p Parser) warn_with_pos(s string, pos token.Position) { } pub fn (mut p Parser) vet_error(s string, line int) { - p.vet_errors << '$p.scanner.file_path:${line+1}: $s' + p.vet_errors << '$p.scanner.file_path:${line + 1}: $s' } fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt { diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 5be470b37c..dd65d279f5 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -47,13 +47,9 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { } .dollar { match p.peek_tok.kind { - .name { - return p.vweb() - } .key_if { - return p.if_expr(true) - } else { - p.error('unexpected $') - } + .name { return p.vweb() } + .key_if { return p.if_expr(true) } + else { p.error('unexpected $') } } } .chartoken { @@ -275,7 +271,8 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden return node } // added 10/2020: LATER this will be parsed as PrefixExpr instead - p.warn_with_pos('move infix `$p.tok.kind` operator before new line (if infix intended) or use brackets for a prefix expression', p.tok.position()) + p.warn_with_pos('move infix `$p.tok.kind` operator before new line (if infix intended) or use brackets for a prefix expression', + p.tok.position()) } // continue on infix expr node = p.infix_expr(node) @@ -286,9 +283,9 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden } else if p.tok.kind in [.inc, .dec] || (p.tok.kind == .question && p.inside_ct_if_expr) { // Postfix // detect `f(x++)`, `a[x++]` - if p.peek_tok.kind in [.rpar, .rsbr] && - p.mod !in ['builtin', 'regex', 'strconv'] { // temp - p.warn_with_pos('`$p.tok.kind` operator can only be used as a statement', p.peek_tok.position()) + if p.peek_tok.kind in [.rpar, .rsbr] && p.mod !in ['builtin', 'regex', 'strconv'] { // temp + p.warn_with_pos('`$p.tok.kind` operator can only be used as a statement', + p.peek_tok.position()) } node = ast.PostfixExpr{ op: p.tok.kind @@ -321,8 +318,8 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr { } right = p.expr(precedence) p.expecting_type = prev_expecting_type - if p.pref.is_vet && op in [.key_in, .not_in] && - right is ast.ArrayInit && (right as ast.ArrayInit).exprs.len == 1 { + if p.pref.is_vet && op in [.key_in, .not_in] && right is ast.ArrayInit && (right as ast.ArrayInit).exprs.len == + 1 { p.vet_error('Use `var == value` instead of `var in [value]`', pos.line_nr) } return ast.InfixExpr{ diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 2759d8fb74..3bb8b5920a 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -154,22 +154,8 @@ fn (mut p Parser) struct_decl() ast.StructDecl { typ := p.parse_type() type_pos := p.prev_tok.position() field_pos := field_start_pos.extend(type_pos) - // if name == '_net_module_s' { - // if name.contains('App') { - // s := p.table.get_type_symbol(typ) - // println('struct decl field type ' + s.str()) - // } // Comments after type (same line) - line_pos := field_pos.line_nr - for p.tok.kind == .comment && line_pos + 1 == p.tok.line_nr { - if p.tok.lit.contains('\n') { - break - } - comments << p.comment() - if p.tok.kind == .rcbr { - break - } - } + comments << p.eat_comments() if p.tok.kind == .lsbr { // attrs are stored in `p.attrs` p.attributes() @@ -284,38 +270,38 @@ fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit { p.is_amp = false for p.tok.kind != .rcbr && p.tok.kind != .rpar { mut field_name := '' + mut expr := ast.Expr{} + mut field_pos := token.Position{} + mut comments := []ast.Comment{} if no_keys { - expr := p.expr(0) - comments := p.eat_comments() // name will be set later in checker - fields << ast.StructInitField{ - expr: expr - pos: expr.position() - comments: comments - } + expr = p.expr(0) + field_pos = expr.position() + comments = p.eat_comments() } else { first_field_pos := p.tok.position() field_name = p.check_name() p.check(.colon) - expr := p.expr(0) - comments := p.eat_comments() + expr = p.expr(0) + comments = p.eat_comments() last_field_pos := expr.position() - field_pos := token.Position{ + field_pos = token.Position{ line_nr: first_field_pos.line_nr pos: first_field_pos.pos len: last_field_pos.pos - first_field_pos.pos + last_field_pos.len } - fields << ast.StructInitField{ - name: field_name - expr: expr - pos: field_pos - comments: comments - } } i++ if p.tok.kind == .comma { p.next() } + comments << p.eat_comments() + fields << ast.StructInitField{ + name: field_name + expr: expr + pos: field_pos + comments: comments + } } last_pos := p.tok.position() if !short_syntax { diff --git a/vlib/v/parser/v_parser_test.v b/vlib/v/parser/v_parser_test.v index cdfe9ac167..10282afe15 100644 --- a/vlib/v/parser/v_parser_test.v +++ b/vlib/v/parser/v_parser_test.v @@ -125,14 +125,15 @@ fn test_parse_expr() { if true { return } - input := ['1 == 1', '234234', '2 * 8 + 3', 'a := 3', 'a++', 'b := 4 + 2', 'neg := -a', - 'a + a', 'bo := 2 + 3 == 5', '2 + 1', 'q := 1', 'q + 777', '2 + 3', '2+2*4', 'x := 10', - 'mut aa := 12', 'ab := 10 + 3 * 9', 's := "hi"', 'x = 11', 'a += 10', '1.2 + 3.4', '4 + 4', - '1 + 2 * 5', '-a+1', '2+2'] - expecting := ['1 == 1;', '234234;', '2 * 8 + 3;', 'int a = 3;', 'a++;', 'int b = 4 + 2;', - 'int neg = -a;', 'a + a;', 'bool bo = 2 + 3 == 5;', '2 + 1;', 'int q = 1;', 'q + 777;', - '2 + 3;', '2 + 2 * 4;', 'int x = 10;', 'int aa = 12;', 'int ab = 10 + 3 * 9;', 'string s = tos3("hi");', - 'x = 11;', 'a += 10;', '1.2 + 3.4;', '4 + 4;', '1 + 2 * 5;', '-a + 1;', '2 + 2;'] + input := ['1 == 1', '234234', '2 * 8 + 3', 'a := 3', 'a++', 'b := 4 + 2', 'neg := -a', 'a + a', + 'bo := 2 + 3 == 5', '2 + 1', 'q := 1', 'q + 777', '2 + 3', '2+2*4', 'x := 10', 'mut aa := 12', + 'ab := 10 + 3 * 9', 's := "hi"', 'x = 11', 'a += 10', '1.2 + 3.4', '4 + 4', '1 + 2 * 5', '-a+1', + '2+2', + ] + expecting := ['1 == 1;', '234234;', '2 * 8 + 3;', 'int a = 3;', 'a++;', 'int b = 4 + 2;', 'int neg = -a;', + 'a + a;', 'bool bo = 2 + 3 == 5;', '2 + 1;', 'int q = 1;', 'q + 777;', '2 + 3;', '2 + 2 * 4;', + 'int x = 10;', 'int aa = 12;', 'int ab = 10 + 3 * 9;', 'string s = tos3("hi");', 'x = 11;', 'a += 10;', + '1.2 + 3.4;', '4 + 4;', '1 + 2 * 5;', '-a + 1;', '2 + 2;'] mut e := []ast.Stmt{} table := table.new_table() vpref := &pref.Preferences{} diff --git a/vlib/v/pref/os.v b/vlib/v/pref/os.v index cf02683ac7..c2a1e029b2 100644 --- a/vlib/v/pref/os.v +++ b/vlib/v/pref/os.v @@ -22,95 +22,39 @@ pub enum OS { // Helper function to convert string names to OS enum pub fn os_from_string(os_str string) ?OS { match os_str { - 'linux' { - return .linux - } - 'windows' { - return .windows - } - 'ios' { - return .ios - } - 'macos' { - return .macos - } - 'freebsd' { - return .freebsd - } - 'openbsd' { - return .openbsd - } - 'netbsd' { - return .netbsd - } - 'dragonfly' { - return .dragonfly - } - 'js' { - return .js - } - 'solaris' { - return .solaris - } - 'android' { - return .android - } - 'haiku' { - return .haiku - } - 'linux_or_macos' { - return .linux - } - '' { - return ._auto - } - else { - return error('bad OS $os_str') - } + 'linux' { return .linux } + 'windows' { return .windows } + 'ios' { return .ios } + 'macos' { return .macos } + 'freebsd' { return .freebsd } + 'openbsd' { return .openbsd } + 'netbsd' { return .netbsd } + 'dragonfly' { return .dragonfly } + 'js' { return .js } + 'solaris' { return .solaris } + 'android' { return .android } + 'haiku' { return .haiku } + 'linux_or_macos' { return .linux } + '' { return ._auto } + else { return error('bad OS $os_str') } } } pub fn (o OS) str() string { match o { - ._auto { - return 'RESERVED: AUTO' - } - .ios { - return 'iOS' - } - .macos { - return 'MacOS' - } - .linux { - return 'Linux' - } - .windows { - return 'Windows' - } - .freebsd { - return 'FreeBSD' - } - .openbsd { - return 'OpenBSD' - } - .netbsd { - return 'NetBSD' - } - .dragonfly { - return 'Dragonfly' - } - .js { - return 'JavaScript' - } - .android { - return 'Android' - } - .solaris { - return 'Solaris' - } - .haiku { - return 'Haiku' - } + ._auto { return 'RESERVED: AUTO' } + .ios { return 'iOS' } + .macos { return 'MacOS' } + .linux { return 'Linux' } + .windows { return 'Windows' } + .freebsd { return 'FreeBSD' } + .openbsd { return 'OpenBSD' } + .netbsd { return 'NetBSD' } + .dragonfly { return 'Dragonfly' } + .js { return 'JavaScript' } + .android { return 'Android' } + .solaris { return 'Solaris' } + .haiku { return 'Haiku' } } } diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 3f8afa7a33..9683de6e69 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1104,7 +1104,7 @@ fn (mut s Scanner) text_scan() token.Token { } } if is_separate_line_comment { - comment = '|' + comment + comment = '\x01' + comment } return s.new_token(.comment, comment, comment.len + 2) } diff --git a/vlib/v/scanner/scanner_at_literals_test.v b/vlib/v/scanner/scanner_at_literals_test.v index 8f65b895f6..3e4c886579 100644 --- a/vlib/v/scanner/scanner_at_literals_test.v +++ b/vlib/v/scanner/scanner_at_literals_test.v @@ -3,7 +3,7 @@ module scanner import os struct TestStruct { - test string + test string } fn (mut t TestStruct) test_struct() { @@ -15,18 +15,19 @@ fn (mut t TestStruct) test_struct_w_return() string { return t.test } -fn (mut t TestStruct) test_struct_w_high_order(cb fn(int)string) string { +fn (mut t TestStruct) test_struct_w_high_order(cb fn (int) string) string { assert @STRUCT == 'TestStruct' - return 'test'+cb(2) + return 'test' + cb(2) } -struct TestFn { } +struct TestFn { +} fn (mut t TestFn) tst_1() { assert @FN == 'tst_1' } -fn (mut t TestFn) tst_2(cb fn(int)) { +fn (mut t TestFn) tst_2(cb fn (int)) { assert @FN == 'tst_2' cb(1) } @@ -35,7 +36,7 @@ fn fn_name_mod_level() { assert @FN == 'fn_name_mod_level' } -fn fn_name_mod_level_high_order(cb fn(int)) { +fn fn_name_mod_level_high_order(cb fn (int)) { assert @FN == 'fn_name_mod_level_high_order' cb(1) } @@ -49,16 +50,14 @@ fn test_at_file() { fn test_at_fn() { // Test @FN assert @FN == 'test_at_fn' - fn_name_mod_level() - fn_name_mod_level_high_order(fn(i int){ + fn_name_mod_level_high_order(fn (i int) { t := i + 1 assert t == 2 }) - mut tfn := TestFn{} tfn.tst_1() - tfn.tst_2(fn(i int){ + tfn.tst_2(fn (i int) { t := i + 1 assert t == 2 }) @@ -72,10 +71,12 @@ fn test_at_mod() { fn test_at_struct() { // Test @STRUCT assert @STRUCT == '' - mut ts := TestStruct { test: "test" } + mut ts := TestStruct{ + test: 'test' + } ts.test_struct() r1 := ts.test_struct_w_return() - r2 := ts.test_struct_w_high_order(fn(i int)string{ + r2 := ts.test_struct_w_high_order(fn (i int) string { assert @STRUCT == '' return i.str() }) diff --git a/vlib/v/scanner/scanner_test.v b/vlib/v/scanner/scanner_test.v index cb846daa0c..41afe0546d 100644 --- a/vlib/v/scanner/scanner_test.v +++ b/vlib/v/scanner/scanner_test.v @@ -59,14 +59,12 @@ fn test_float_without_fraction() { assert result[0] == .name assert result[1] == .decl_assign assert result[2] == .number - result = scan_kinds('return 3., 4.') assert result.len == 4 assert result[0] == .key_return assert result[1] == .number assert result[2] == .comma assert result[3] == .number - result = scan_kinds('fun(5.)') assert result.len == 4 assert result[0] == .name diff --git a/vlib/v/table/attr.v b/vlib/v/table/attr.v index c94c5a2575..5ecfc92e68 100644 --- a/vlib/v/table/attr.v +++ b/vlib/v/table/attr.v @@ -6,10 +6,10 @@ module table // e.g. `[unsafe]` pub struct Attr { pub: - name string // [name] - is_string bool // ['name'] - is_ctdefine bool // [if name] - arg string // [name: arg] + name string // [name] + is_string bool // ['name'] + is_ctdefine bool // [if name] + arg string // [name: arg] is_string_arg bool // [name: 'arg'] } @@ -21,8 +21,7 @@ pub fn (attr Attr) str() string { } if attr.is_string { s += "'$attr.name'" - } - else { + } else { s += attr.name if attr.arg.len > 0 { s += ': ' @@ -31,8 +30,7 @@ pub fn (attr Attr) str() string { // FIXME: other escapes e.g. \r\n a = a.replace("'", "\\'") s += "'$a'" - } - else { + } else { s += attr.arg } } diff --git a/vlib/v/table/cflags_test.v b/vlib/v/table/cflags_test.v index 2913bc103d..d5c2465521 100644 --- a/vlib/v/table/cflags_test.v +++ b/vlib/v/table/cflags_test.v @@ -64,7 +64,7 @@ fn assert_parse_invalid_flag(mut t table.Table, flag string) { assert false } -fn make_flag(os, name, value string) cflag.CFlag { +fn make_flag(os string, name string, value string) cflag.CFlag { return cflag.CFlag{ mod: module_name os: os diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 446c20a3d4..4c235423b2 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -117,7 +117,10 @@ pub fn (f &Fn) source_signature() string { sig += ', ' } } - sig += ') $f.return_type_source_name' + sig += ')' + if f.return_type != void_type { + sig += ' $f.return_type_source_name' + } return sig } diff --git a/vlib/v/util/diff.v b/vlib/v/util/diff.v index e8bfd0a4e9..7ce012a47e 100644 --- a/vlib/v/util/diff.v +++ b/vlib/v/util/diff.v @@ -56,7 +56,7 @@ fn opendiff_exists() bool { pub fn color_compare_files(diff_cmd string, file1 string, file2 string) string { if diff_cmd != '' { - full_cmd := '$diff_cmd --minimal --text --unified=2 ' + ' --show-function-line="fn " "$file1" "$file2" ' + full_cmd := '$diff_cmd --minimal --text --unified=2 --show-function-line="fn " "$file1" "$file2" ' x := os.exec(full_cmd) or { return 'comparison command: `$full_cmd` failed' } diff --git a/vlib/v/util/errors.v b/vlib/v/util/errors.v index 359ea8ed0c..214e00ea34 100644 --- a/vlib/v/util/errors.v +++ b/vlib/v/util/errors.v @@ -91,7 +91,7 @@ pub fn formatted_error(kind string, omsg string, filepath string, pos token.Posi } } column := imax(0, pos.pos - p - 1) - position := '$path:${pos.line_nr+1}:${imax(1,column+1)}:' + position := '$path:${pos.line_nr + 1}:${imax(1, column + 1)}:' scontext := source_context(kind, source, column, pos).join('\n') final_position := bold(position) final_kind := bold(color(kind, kind)) @@ -116,7 +116,7 @@ pub fn source_context(kind string, source string, column int, pos token.Position end_column := imax(0, imin(column + imax(0, pos.len), sline.len)) cline := if iline == pos.line_nr { sline[..start_column] + color(kind, sline[start_column..end_column]) + sline[end_column..] } else { sline } - clines << '${iline+1:5d} | ' + cline.replace('\t', tab_spaces) + clines << '${iline + 1:5d} | ' + cline.replace('\t', tab_spaces) // if iline == pos.line_nr { // The pointerline should have the same spaces/tabs as the offending diff --git a/vlib/v/vet/vet_test.v b/vlib/v/vet/vet_test.v index 89f0a108cc..bb4d4018df 100644 --- a/vlib/v/vet/vet_test.v +++ b/vlib/v/vet/vet_test.v @@ -21,7 +21,7 @@ fn get_tests_in_dir(dir string) []string { return tests } -fn check_path(vexe, dir string, tests []string) int { +fn check_path(vexe string, dir string, tests []string) int { mut nb_fail := 0 paths := vtest.filter_vtest_only(tests, { basepath: dir diff --git a/vlib/v/vmod/parser.v b/vlib/v/vmod/parser.v index 9b5bcb2039..006d213997 100644 --- a/vlib/v/vmod/parser.v +++ b/vlib/v/vmod/parser.v @@ -166,7 +166,7 @@ fn get_array_content(tokens []Token, st_idx int) ?([]string, int) { .str { vals << tok.val if tokens[idx + 1].typ !in [.comma, .rabr] { - return error('vmod: invalid separator "${tokens[idx+1].val}"') + return error('vmod: invalid separator "${tokens[idx + 1].val}"') } idx += if tokens[idx + 1].typ == .comma { 2 } else { 1 } } @@ -233,14 +233,14 @@ fn (mut p Parser) parse() ?Manifest { mn.author = field_value } 'dependencies' { - deps, idx := get_array_content(tokens, i + 1)? + deps, idx := get_array_content(tokens, i + 1) ? mn.dependencies = deps i = idx continue } else { if tokens[i + 1].typ == .labr { - vals, idx := get_array_content(tokens, i + 1)? + vals, idx := get_array_content(tokens, i + 1) ? mn.unknown[field_name] = vals i = idx continue