diff --git a/cmd/tools/vpm.v b/cmd/tools/vpm.v index e591526e1b..4d9983a2df 100644 --- a/cmd/tools/vpm.v +++ b/cmd/tools/vpm.v @@ -141,7 +141,7 @@ fn vpm_install(module_names []string) { if vcs == '' { vcs = supported_vcs_systems[0] } - if !vcs in supported_vcs_systems { + if vcs !in supported_vcs_systems { errors++ println('Skipping module "$name", since it uses an unsupported VCS {$vcs} .') continue diff --git a/vlib/json/json_primitives.v b/vlib/json/json_primitives.v index 5adb206b6a..ad274daa21 100644 --- a/vlib/json/json_primitives.v +++ b/vlib/json/json_primitives.v @@ -13,11 +13,12 @@ struct C.cJSON { } pub fn decode() voidptr { - + return 0 } -pub fn encode() voidptr { - +pub fn encode(x voidptr) string { + // compiler implementation + return '' } fn jsdecode_int(root &C.cJSON) int { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2e16ac247a..7b0093dae1 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -890,6 +890,9 @@ fn (c mut Checker) stmt(node ast.Stmt) { // c.warn('duplicate method `$it.name`', it.pos) // } // } + if f := c.table.find_fn(it.name) { + c.warn('redefinition of `$it.name`', it.pos) + } c.expected_type = table.void_type c.fn_return_type = it.return_type c.stmts(it.stmts) @@ -1551,7 +1554,7 @@ pub fn (c mut Checker) error(message string, pos token.Position) { fn (c mut Checker) warn_or_error(message string, pos token.Position, warn bool) { // add backtrace to issue struct, how? // if c.pref.is_verbose { - // print_backtrace() + // print_backtrace() // } if !warn { c.nr_errors++ @@ -1571,7 +1574,6 @@ fn (c mut Checker) warn_or_error(message string, pos token.Position, warn bool) file_path: c.file.path message: message } - } } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 572a0d1bfa..b4469c5c93 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -111,7 +111,8 @@ fn (f mut Fmt) imports(imports []ast.Import) { // f.indent++ for imp in imports { if !(imp.mod in f.used_imports) { - continue + // TODO bring back once only unused imports are removed + // continue } f.out_imports.write('\t') f.out_imports.writeln(f.imp_stmt_str(imp)) @@ -529,7 +530,7 @@ fn (f mut Fmt) expr(node ast.Expr) { f.write('_') } else { name := short_module(it.name) - //f.write('<$it.name => $name>') + // f.write('<$it.name => $name>') f.write(name) if name.contains('.') { f.mark_module_as_used(name) @@ -673,7 +674,7 @@ fn (f mut Fmt) expr(node ast.Expr) { } ast.StructInit { type_sym := f.table.get_type_symbol(it.typ) - //f.write('') + // f.write('') mut name := short_module(type_sym.name).replace(f.cur_mod + '.', '') // TODO f.type_to_str? if name == 'void' { name = '' diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 3c12c81abf..eba5508e4b 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -7,11 +7,11 @@ import ( strings v.ast v.table - v.depgraph - v.token v.pref - term + v.token v.util + v.depgraph + term ) const ( @@ -21,6 +21,10 @@ const ( 'void', 'volatile', 'while'] ) +fn foo(t token.Token) { + util.full_hash() +} + struct Gen { out strings.Builder typedefs strings.Builder @@ -809,109 +813,6 @@ fn (g mut Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, ad return true } -fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { - if it.is_c { - // || it.no_body { - return - } - g.reset_tmp_count() - is_main := it.name == 'main' - if is_main { - if g.pref.os == .windows { - g.write('int wmain(int ___argc, wchar_t *___argv[], wchar_t *___envp[]') - } else { - g.write('int ${it.name}(int ___argc, char** ___argv') - } - } else { - mut name := it.name - c := name[0] - if c in [`+`, `-`, `*`, `/`, `%`] { - name = util.replace_op(name) - } - if it.is_method { - name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name - } - if it.is_c { - name = name.replace('.', '__') - } else { - name = c_name(name) - } - // if g.pref.show_cc && it.is_builtin { - // println(name) - // } - // type_name := g.table.Type_to_str(it.return_type) - type_name := g.typ(it.return_type) - g.write('$type_name ${name}(') - g.definitions.write('$type_name ${name}(') - } - // Receiver is the first argument - /* - if it.is_method { - mut styp := g.typ(it.receiver.typ) - // if table.type_nr_muls(it.receiver.typ) > 0 { - // if it.rec_mut { - // styp += '*' - // } - g.write('$styp $it.receiver.name ') - // TODO mut - g.definitions.write('$styp $it.receiver.name') - if it.args.len > 0 { - g.write(', ') - g.definitions.write(', ') - } - } -*/ - // - g.fn_args(it.args, it.is_variadic) - if it.no_body || (g.pref.is_cache && it.is_builtin) { - // Just a function header. - // Builtin function bodies are defined in builtin.o - g.definitions.writeln(');') - g.writeln(');') - return - } - g.writeln(') {') - if !is_main { - g.definitions.writeln(');') - } - if is_main { - g.writeln('\t_vinit();') - if g.is_importing_os() { - if g.autofree { - g.writeln('free(_const_os__args.data); // empty, inited in _vinit()') - } - if g.pref.os == .windows { - g.writeln('\t_const_os__args = os__init_os_args_wide(___argc, ___argv);') - } else { - g.writeln('\t_const_os__args = os__init_os_args(___argc, (byteptr*)___argv);') - } - } - } - g.stmts(it.stmts) - // //////////// - if g.autofree { - g.free_scope_vars(it.pos.pos - 1) - } - // ///////// - if is_main { - if g.autofree { - g.writeln('\t_vcleanup();') - } - if g.is_test { - verror('test files cannot have function `main`') - } - } - if g.defer_stmts.len > 0 { - g.write_defer_stmts() - } - if is_main { - g.writeln('\treturn 0;') - } - g.writeln('}') - g.defer_stmts = [] - g.fn_decl = 0 -} - fn (g mut Gen) free_scope_vars(pos int) { scope := g.file.scope.innermost(pos) for _, obj in scope.objects { @@ -953,55 +854,6 @@ fn (g mut Gen) free_scope_vars(pos int) { } } -fn (g mut Gen) fn_args(args []table.Arg, is_variadic bool) { - no_names := args.len > 0 && args[0].name == 'arg_1' - for i, arg in args { - arg_type_sym := g.table.get_type_symbol(arg.typ) - mut arg_type_name := g.typ(arg.typ) // arg_type_sym.name.replace('.', '__') - is_varg := i == args.len - 1 && is_variadic - if is_varg { - varg_type_str := int(arg.typ).str() - if !(varg_type_str in g.variadic_args) { - g.variadic_args[varg_type_str] = 0 - } - arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr') - } - if arg_type_sym.kind == .function { - info := arg_type_sym.info as table.FnType - func := info.func - if !info.is_anon { - g.write(arg_type_name + ' ' + arg.name) - g.definitions.write(arg_type_name + ' ' + arg.name) - } else { - g.write('${g.typ(func.return_type)} (*$arg.name)(') - g.definitions.write('${g.typ(func.return_type)} (*$arg.name)(') - g.fn_args(func.args, func.is_variadic) - g.write(')') - g.definitions.write(')') - } - } else if no_names { - g.write(arg_type_name) - g.definitions.write(arg_type_name) - } else { - mut nr_muls := table.type_nr_muls(arg.typ) - s := arg_type_name + ' ' + arg.name - if arg.is_mut { - // mut arg needs one * - nr_muls = 1 - } - // if nr_muls > 0 && !is_varg { - // s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name - // } - g.write(s) - g.definitions.write(s) - } - if i < args.len - 1 { - g.write(', ') - g.definitions.write(', ') - } - } -} - fn (g mut Gen) expr(node ast.Expr) { // println('cgen expr() line_nr=$node.pos.line_nr') match node { @@ -2406,7 +2258,7 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { } g.write('%' + sfmt[1..]) } else if node.expr_types[i] in [table.string_type, table.bool_type, table.f32_type, - table.f64_type] || sym.kind in [.enum_, .array, .array_fixed] { + table.f64_type] || sym.kind in [.enum_, .array, .array_fixed] { g.write('%.*s') } else { g.write('%d') @@ -2421,25 +2273,21 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { if fspec == `s` && node.expr_types[i] == table.string_type { g.expr(expr) g.write('.str') - } - else { + } else { g.expr(expr) } - } - else if node.expr_types[i] == table.string_type { + } else if node.expr_types[i] == table.string_type { // `name.str, name.len,` g.expr(expr) g.write('.len, ') g.expr(expr) g.write('.str') - } - else if node.expr_types[i] == table.bool_type { + } else if node.expr_types[i] == table.bool_type { g.expr(expr) g.write(' ? 4 : 5, ') g.expr(expr) g.write(' ? "true" : "false"') - } - else { + } else { sym := g.table.get_type_symbol(node.expr_types[i]) if sym.kind == .enum_ { is_var := match node.exprs[i] { @@ -2472,9 +2320,8 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { g.enum_expr(expr) g.write('"') } - } - else if node.expr_types[i] in [table.f32_type, table.f64_type, table.array_type, - table.map_type] || sym.kind in [.array, .array_fixed] { + } else if node.expr_types[i] in [table.f32_type, table.f64_type, table.array_type, + table.map_type] || sym.kind in [.array, .array_fixed] { styp := g.typ(node.expr_types[i]) g.write('${styp}_str(') g.expr(expr) @@ -2483,8 +2330,7 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) { g.write('${styp}_str(') g.expr(expr) g.write(').str') - } - else { + } else { g.expr(expr) } } diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v new file mode 100644 index 0000000000..8ba6e4a830 --- /dev/null +++ b/vlib/v/gen/fn.v @@ -0,0 +1,162 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module gen + +import ( + v.ast + v.table + v.util +) + +fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { + if it.is_c { + // || it.no_body { + return + } + g.reset_tmp_count() + is_main := it.name == 'main' + if is_main { + if g.pref.os == .windows { + g.write('int wmain(int ___argc, wchar_t *___argv[], wchar_t *___envp[]') + } else { + g.write('int ${it.name}(int ___argc, char** ___argv') + } + } else { + mut name := it.name + c := name[0] + if c in [`+`, `-`, `*`, `/`, `%`] { + name = util.replace_op(name) + } + if it.is_method { + name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name + } + if it.is_c { + name = name.replace('.', '__') + } else { + name = c_name(name) + } + // if g.pref.show_cc && it.is_builtin { + // println(name) + // } + // type_name := g.table.Type_to_str(it.return_type) + type_name := g.typ(it.return_type) + g.write('$type_name ${name}(') + g.definitions.write('$type_name ${name}(') + } + // Receiver is the first argument + /* + if it.is_method { + mut styp := g.typ(it.receiver.typ) + // if table.type_nr_muls(it.receiver.typ) > 0 { + // if it.rec_mut { + // styp += '*' + // } + g.write('$styp $it.receiver.name ') + // TODO mut + g.definitions.write('$styp $it.receiver.name') + if it.args.len > 0 { + g.write(', ') + g.definitions.write(', ') + } + } +*/ + // + g.fn_args(it.args, it.is_variadic) + if it.no_body || (g.pref.is_cache && it.is_builtin) { + // Just a function header. + // Builtin function bodies are defined in builtin.o + g.definitions.writeln(');') + g.writeln(');') + return + } + g.writeln(') {') + if !is_main { + g.definitions.writeln(');') + } + if is_main { + g.writeln('\t_vinit();') + if g.is_importing_os() { + if g.autofree { + g.writeln('free(_const_os__args.data); // empty, inited in _vinit()') + } + if g.pref.os == .windows { + g.writeln('\t_const_os__args = os__init_os_args_wide(___argc, ___argv);') + } else { + g.writeln('\t_const_os__args = os__init_os_args(___argc, (byteptr*)___argv);') + } + } + } + g.stmts(it.stmts) + // //////////// + if g.autofree { + g.free_scope_vars(it.pos.pos - 1) + } + // ///////// + if is_main { + if g.autofree { + g.writeln('\t_vcleanup();') + } + if g.is_test { + verror('test files cannot have function `main`') + } + } + if g.defer_stmts.len > 0 { + g.write_defer_stmts() + } + if is_main { + g.writeln('\treturn 0;') + } + g.writeln('}') + g.defer_stmts = [] + g.fn_decl = 0 +} + +fn (g mut Gen) fn_args(args []table.Arg, is_variadic bool) { + no_names := args.len > 0 && args[0].name == 'arg_1' + for i, arg in args { + arg_type_sym := g.table.get_type_symbol(arg.typ) + mut arg_type_name := g.typ(arg.typ) // arg_type_sym.name.replace('.', '__') + is_varg := i == args.len - 1 && is_variadic + if is_varg { + varg_type_str := int(arg.typ).str() + if !(varg_type_str in g.variadic_args) { + g.variadic_args[varg_type_str] = 0 + } + arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr') + } + if arg_type_sym.kind == .function { + info := arg_type_sym.info as table.FnType + func := info.func + if !info.is_anon { + g.write(arg_type_name + ' ' + arg.name) + g.definitions.write(arg_type_name + ' ' + arg.name) + } else { + g.write('${g.typ(func.return_type)} (*$arg.name)(') + g.definitions.write('${g.typ(func.return_type)} (*$arg.name)(') + g.fn_args(func.args, func.is_variadic) + g.write(')') + g.definitions.write(')') + } + } else if no_names { + g.write(arg_type_name) + g.definitions.write(arg_type_name) + } else { + mut nr_muls := table.type_nr_muls(arg.typ) + s := arg_type_name + ' ' + arg.name + if arg.is_mut { + // mut arg needs one * + nr_muls = 1 + } + // if nr_muls > 0 && !is_varg { + // s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name + // } + g.write(s) + g.definitions.write(s) + } + if i < args.len - 1 { + g.write(', ') + g.definitions.write(', ') + } + } +} diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index e9bb340d3c..d6a1b7ae2c 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -176,6 +176,9 @@ fn (p mut Parser) fn_decl() ast.FnDecl { } else { name = p.prepend_mod(name) } + if _ := p.table.find_fn(name) { + p.error('redefinition of `$name`') + } p.table.register_fn(table.Fn{ name: name args: args