diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index c0bb87c8ad..2e55e3fbc3 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -6,11 +6,11 @@ module ast import v.token import v.table -pub type TypeDecl = AliasTypeDecl | SumTypeDecl | FnTypeDecl +pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl -pub type Expr = AnonFn | ArrayInit | AsCast | AssignExpr | Assoc | BoolLiteral | CastExpr | CallExpr | CharLiteral | ConcatExpr | EnumVal | FloatLiteral | IfExpr | Ident | IfGuardExpr | InfixExpr | IndexExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringLiteral | StringInterLiteral | StructInit | Type | TypeOf +pub type Expr = AnonFn | ArrayInit | AsCast | AssignExpr | Assoc | BoolLiteral | CallExpr | CastExpr | CharLiteral | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringInterLiteral | StringLiteral | StructInit | Type | TypeOf -pub type Stmt = AssignStmt | AssertStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | TypeDecl | UnsafeStmt +pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt | GotoLabel | GotoStmt | HashStmt | Import | InterfaceDecl | Module | Return | StructDecl | TypeDecl | UnsafeStmt pub type ScopeObject = ConstField | GlobalDecl | Var @@ -428,7 +428,6 @@ pub: is_else bool } - /* CompIf.is_opt: `$if xyz? {}` => this compile time `if` is optional, @@ -438,7 +437,6 @@ if `xyz` is NOT defined. If .is_opt is false, then when `xyz` is not defined, the compilation will fail. */ - pub struct CompIf { pub: val string diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index cd7bcb29e7..26a61c8fde 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -28,7 +28,7 @@ pub fn (node &FnDecl) str(t &table.Table) string { m = '&' } receiver = '($node.receiver.name $m$name) ' -*/ + */ } mut name := if node.is_anon { '' } else { node.name.after('.') } if node.is_c { diff --git a/vlib/v/builder/x64.v b/vlib/v/builder/x64.v index 0435c8cd02..a49446f8e3 100644 --- a/vlib/v/builder/x64.v +++ b/vlib/v/builder/x64.v @@ -30,7 +30,7 @@ pub fn (mut b Builder) build_x64(v_files []string, out_file string) { pub fn (mut b Builder) compile_x64() { // v.files << v.v_files_from_dir(os.join_path(v.pref.vlib_path,'builtin','bare')) - files := [ b.pref.path] + files := [b.pref.path] b.set_module_lookup_paths() b.build_x64(files, b.pref.out_name) } diff --git a/vlib/v/checker/tests/inout/checker_error_test.v b/vlib/v/checker/tests/inout/checker_error_test.v index 5ac03c4750..a7c015937f 100644 --- a/vlib/v/checker/tests/inout/checker_error_test.v +++ b/vlib/v/checker/tests/inout/checker_error_test.v @@ -4,7 +4,7 @@ import term fn test_all() { mut total_errors := 0 vexe := os.getenv('VEXE') - //vroot := os.dir(vexe) + // vroot := os.dir(vexe) dir := 'vlib/v/checker/tests/inout' files := os.ls(dir) or { panic(err) @@ -28,8 +28,10 @@ fn test_all() { mut expected := os.read_file(program.replace('.v', '') + '.out') or { panic(err) } - expected = expected.trim_space().replace(' \n', '\n').replace(' \r\n', '\n').replace('\r\n', '\n').trim('\n') - found := res.output.trim_space().replace(' \n', '\n').replace(' \r\n', '\n').replace('\r\n', '\n').trim('\n') + expected = expected.trim_space().replace(' \n', '\n').replace(' \r\n', '\n').replace('\r\n', + '\n').trim('\n') + found := res.output.trim_space().replace(' \n', '\n').replace(' \r\n', '\n').replace('\r\n', + '\n').trim('\n') if expected != found { println(term.red('FAIL')) println('============') @@ -40,8 +42,7 @@ fn test_all() { println(found) println('============\n') total_errors++ - } - else { + } else { println(term.green('OK')) } } diff --git a/vlib/v/doc/doc.v b/vlib/v/doc/doc.v index 986f43eb6e..2ca2b3de2a 100644 --- a/vlib/v/doc/doc.v +++ b/vlib/v/doc/doc.v @@ -1,14 +1,11 @@ module doc -import ( - strings - // v.builder - v.pref - v.table - v.parser - v.ast - os -) +import strings +import v.pref +import v.table +import v.parser +import v.ast +import os struct Doc { out strings.Builder @@ -18,7 +15,7 @@ mut: stmts []ast.Stmt // all module statements from all files } -type FilterFn fn(node ast.FnDecl)bool +type FilterFn = fn (node ast.FnDecl) bool pub fn doc(mod string, table &table.Table) string { mut d := Doc{ @@ -28,7 +25,7 @@ pub fn doc(mod string, table &table.Table) string { } vlib_path := os.dir(pref.vexe_path()) + '/vlib' mod_path := mod.replace('.', os.path_separator) - path := os.join_path(vlib_path,mod_path) + path := os.join_path(vlib_path, mod_path) if !os.exists(path) { println('module "$mod" not found') println(path) @@ -45,7 +42,10 @@ pub fn doc(mod string, table &table.Table) string { if file.ends_with('_test.v') || file.ends_with('_windows.c.v') || file.ends_with('_macos.c.v') { continue } - file_ast := parser.parse_file(os.join_path(path,file), table, .skip_comments, &pref.Preferences{}, &ast.Scope{parent: 0}) + file_ast := parser.parse_file(os.join_path(path, file), table, .skip_comments, &pref.Preferences{}, + &ast.Scope{ + parent: 0 + }) d.stmts << file_ast.stmts } if d.stmts.len == 0 { @@ -58,12 +58,11 @@ pub fn doc(mod string, table &table.Table) string { d.out.writeln('') d.print_methods() /* - for stmt in file_ast.stmts { + for stmt in file_ast.stmts { d.stmt(stmt) } println(path) */ - return d.out.str().trim_space() } @@ -71,18 +70,18 @@ fn (d &Doc) get_fn_node(f ast.FnDecl) string { return f.str(d.table).replace_each([d.mod + '.', '', 'pub ', '']) } -fn (d mut Doc) print_fns() { +fn (mut d Doc) print_fns() { fn_signatures := d.get_fn_signatures(is_pub_function) d.write_fn_signatures(fn_signatures) } -fn (d mut Doc) print_methods() { +fn (mut d Doc) print_methods() { fn_signatures := d.get_fn_signatures(is_pub_method) d.write_fn_signatures(fn_signatures) } [inline] -fn (d mut Doc) write_fn_signatures(fn_signatures []string) { +fn (mut d Doc) write_fn_signatures(fn_signatures []string) { for s in fn_signatures { d.out.writeln(s) } @@ -98,7 +97,7 @@ fn (d Doc) get_fn_signatures(filter_fn FilterFn) []string { } } else {} - } + } } fn_signatures.sort() return fn_signatures @@ -113,7 +112,7 @@ fn is_pub_function(node ast.FnDecl) bool { } // TODO it's probably better to keep using AST, not `table` -fn (d mut Doc) print_enums() { +fn (mut d Doc) print_enums() { for typ in d.table.types { if typ.kind != .enum_ { continue @@ -127,7 +126,7 @@ fn (d mut Doc) print_enums() { } } -fn (d mut Doc) print_structs() { +fn (mut d Doc) print_structs() { for typ in d.table.types { if typ.kind != .struct_ || !typ.name.starts_with(d.mod + '.') { // !typ.name[0].is_capital() || typ.name.starts_with('C.') { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index bf6bf04d13..6f1a5daa8c 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -375,6 +375,44 @@ fn (mut f Fmt) type_decl(node ast.TypeDecl) { ptype := f.type_to_str(it.parent_type) f.write('type $it.name $ptype') } + ast.FnTypeDecl { + if it.is_pub { + f.write('pub ') + } + typ_sym := f.table.get_type_symbol(it.typ) + fn_typ_info := typ_sym.info as table.FnType + fn_info := fn_typ_info.func + fn_name := it.name.replace(f.cur_mod + '.', '') + f.write('type $fn_name = fn (') + for i, arg in fn_info.args { + f.write(arg.name) + mut s := f.table.type_to_str(arg.typ) + if arg.is_mut { + f.write('mut ') + if s.starts_with('&') { + s = s[1..] + } + } + is_last_arg := i == fn_info.args.len - 1 + should_add_type := is_last_arg || fn_info.args[i + 1].typ != arg.typ || (fn_info.is_variadic && + i == fn_info.args.len - 2) + if should_add_type { + if fn_info.is_variadic && is_last_arg { + f.write(' ...' + s) + } else { + f.write(' ' + s) + } + } + if !is_last_arg { + f.write(', ') + } + } + f.write(')') + if fn_info.return_type.idx() != table.void_type_idx { + ret_str := f.table.type_to_str(fn_info.return_type) + f.write(' ' + ret_str) + } + } ast.SumTypeDecl { if it.is_pub { f.write('pub ') @@ -384,11 +422,9 @@ fn (mut f Fmt) type_decl(node ast.TypeDecl) { for t in it.sub_types { sum_type_names << f.type_to_str(t) } + sum_type_names.sort() f.write(sum_type_names.join(' | ')) } - else { - eprintln('fmt type_decl: unknown ' + typeof(node)) - } } f.writeln('\n') } diff --git a/vlib/v/fmt/tests/types_expected.vv b/vlib/v/fmt/tests/types_expected.vv index a6ef5d4a2b..ef09bd4587 100644 --- a/vlib/v/fmt/tests/types_expected.vv +++ b/vlib/v/fmt/tests/types_expected.vv @@ -1,9 +1,26 @@ // Sumtype -type FooBar = Foo | Bar +type FooBar = Bar | Foo -pub type PublicBar = Foo | Bar | FooBar +pub type PublicBar = Bar | Foo | FooBar + +type Uint = byte | u16 | u32 | u64 + +type Float = f32 | f64 // Alias type type MyInt int pub type Abc f32 + +// Fn type decl +type EmptyFn = fn () + +type OneArgFn = fn (i int) + +type TwoDiffArgs = fn (i int, s string) bool + +type TwoSameArgs = fn (i, j int) string + +type VarArgs = fn (s ...string) int + +type NOVarArgs = fn (i int, s ...string) f64 diff --git a/vlib/v/fmt/tests/types_input.vv b/vlib/v/fmt/tests/types_input.vv index 3293566bd7..4feee90157 100644 --- a/vlib/v/fmt/tests/types_input.vv +++ b/vlib/v/fmt/tests/types_input.vv @@ -4,7 +4,32 @@ type FooBar= Foo | Bar pub type PublicBar = Foo | Bar | FooBar +type Uint = u16 | u64 + | u32 + | byte +type +Float = + f32 | + f64 + // Alias type type MyInt int - + pub type Abc f32 + + +// Fn type decl + + type EmptyFn = fn() +type OneArgFn = + fn (i int) +type TwoDiffArgs += fn (i int, s string) bool + + + type TwoSameArgs = fn(i int, j int) string + +type VarArgs = fn +(s ...string) int + +type NOVarArgs = fn(i int, s ...string) f64 diff --git a/vlib/v/gen/json.v b/vlib/v/gen/json.v index 296a173a8e..eab7ccdbfb 100644 --- a/vlib/v/gen/json.v +++ b/vlib/v/gen/json.v @@ -3,10 +3,8 @@ // that can be found in the LICENSE file. module gen -import ( - v.table - strings -) +import v.table +import strings // TODO replace with comptime code generation. // TODO remove cJSON dependency. @@ -19,7 +17,7 @@ import ( // return res; // } // Codegen json_decode/encode funcs -fn (g mut Gen) gen_json_for_type(typ table.Type) { +fn (mut g Gen) gen_json_for_type(typ table.Type) { mut dec := strings.new_builder(100) mut enc := strings.new_builder(100) sym := g.table.get_type_symbol(typ) @@ -73,7 +71,7 @@ Option ${dec_fn.name}(cJSON* root, $t* res) { } } ' -*/ + */ // Code gen encoder enc_fn_name := js_enc_name(sym.name) enc.writeln(' diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 7d5f8b9ee6..d571760c47 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -16,7 +16,7 @@ import v.ast pub type Type int -pub type TypeInfo = Array | ArrayFixed | Map | Struct | Interface | MultiReturn | Alias | Enum | SumType | FnType +pub type TypeInfo = Alias | Array | ArrayFixed | Enum | FnType | Interface | Map | MultiReturn | Struct | SumType pub struct TypeSymbol { pub: