From e0c85f87aec7362b6c5f72bfe4644bf73621c843 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 11 Mar 2020 21:11:27 +0100 Subject: [PATCH] cgen: args fixes --- .github/workflows/ci.yml | 4 ++++ vlib/builtin/sorted_map.v | 4 ++-- vlib/builtin/string.v | 2 +- vlib/v/ast/ast.v | 1 + vlib/v/checker/checker.v | 5 +++++ vlib/v/gen/cgen.v | 34 +++++++++++++++++++++++----------- vlib/v/gen/tests/1.c | 2 +- vlib/v/parser/fn.v | 10 +++++----- vlib/v/parser/parser.v | 8 -------- 9 files changed, 42 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad1082aec2..63e88b1fba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,6 +136,10 @@ jobs: ls # ./1m #run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world +# - name: Coveralls GitHub Action +# uses: coverallsapp/github-action@v1.0.1 +# with: +# github-token: ${{ secrets.GITHUB_TOKEN }} ubuntu-prebuilt: diff --git a/vlib/builtin/sorted_map.v b/vlib/builtin/sorted_map.v index f1dd745ee4..49db24a6c4 100644 --- a/vlib/builtin/sorted_map.v +++ b/vlib/builtin/sorted_map.v @@ -178,7 +178,7 @@ fn (m SortedMap) exists(key string) bool { return false } -fn (n mapnode) find_key(k string) int { +fn (n &mapnode) find_key(k string) int { mut idx := 0 for idx < n.size && n.keys[idx] < k { idx++ @@ -353,7 +353,7 @@ pub fn (m mut SortedMap) delete(key string) { // Insert all keys of the subtree into array `keys` // starting at `at`. Keys are inserted in order. -fn (n mapnode) subkeys(keys mut []string, at int) int { +fn (n &mapnode) subkeys(keys mut []string, at int) int { mut position := at if !isnil(n.children) { // Traverse children and insert diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index a784405780..4b8a1f4d48 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -396,7 +396,7 @@ fn (s string) add(a string) string { for j in 0..a.len { res[s.len + j] = a[j] } - res[new_len] = `\0` // V strings are not null terminated, but just in case + res.str[new_len] = `\0` // V strings are not null terminated, but just in case return res } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 7ce5e9f4d6..7abe349870 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -182,6 +182,7 @@ mut: expr_type table.Type // type of `user` receiver_type table.Type // User return_type table.Type + arg_types []table.Type } pub struct Return { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 99033a1970..03fcd54efb 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -238,10 +238,12 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { c.expr(call_expr.args[0]) return f.return_type } + mut arg_types := []table.Type for i, arg_expr in call_expr.args { arg := if f.is_variadic && i >= f.args.len - 1 { f.args[f.args.len - 1] } else { f.args[i] } c.expected_type = arg.typ typ := c.expr(arg_expr) + arg_types << typ typ_sym := c.table.get_type_symbol(typ) arg_typ_sym := c.table.get_type_symbol(arg.typ) if !c.table.check(typ, arg.typ) { @@ -258,6 +260,7 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { c.error('!cannot use type `$typ_sym.str()` as type `$arg_typ_sym.str()` in argument ${i+1} to `$fn_name`', call_expr.pos) } } + call_expr.arg_types = arg_types return f.return_type } @@ -267,6 +270,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) method_call_expr.expr_type = typ typ_sym := c.table.get_type_symbol(typ) name := method_call_expr.name + mut arg_types := []table.Type // println('method call $name $method_call_expr.pos.line_nr') if typ_sym.kind == .array && name in ['filter', 'clone', 'repeat'] { if name == 'filter' { @@ -301,6 +305,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) // } for i, arg_expr in method_call_expr.args { c.expected_type = method.args[i + 1].typ + arg_types << c.expected_type c.expr(arg_expr) } method_call_expr.receiver_type = method.args[0].typ diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 1bcc65e4a3..e12fa082f1 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -410,8 +410,12 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { g.definitions.write(arg_type_name) } else { - nr_muls := table.type_nr_muls(arg.typ) + mut nr_muls := table.type_nr_muls(arg.typ) mut s := arg_type_name + ' ' + arg.name + if arg.is_mut { + // mut arg needs one * + nr_muls = 1 + } if nr_muls > 0 { s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name } @@ -464,7 +468,7 @@ fn (g mut Gen) expr(node ast.Expr) { } g.expr(it.val) if g.is_array_set { - g.write(')') + g.write(' })') g.is_array_set = false } g.is_assign_expr = false @@ -483,7 +487,7 @@ fn (g mut Gen) expr(node ast.Expr) { name = name[3..] } g.write('${name}(') - g.call_args(it.args, it.muts) + g.call_args(it.args, it.muts, it.arg_types) g.write(')') g.is_c_call = false } @@ -689,7 +693,7 @@ fn (g mut Gen) expr(node ast.Expr) { if it.args.len > 0 { g.write(', ') } - g.call_args(it.args, it.muts) + g.call_args(it.args, it.muts, it.arg_types) g.write(')') } ast.None { @@ -895,18 +899,18 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) { if !is_range && node.container_type != 0 { sym := g.table.get_type_symbol(node.container_type) if sym.kind == .array { + info := sym.info as table.Array + elem_type_str := g.typ(info.elem_type) if g.is_assign_expr { g.is_array_set = true g.write('array_set(&') g.expr(node.left) g.write(', ') g.expr(node.index) - g.write(', ') + g.write(', &($elem_type_str[]) { ') } else { - info := sym.info as table.Array - styp := g.typ(info.elem_type) - g.write('(*($styp*)array_get(') + g.write('(*($elem_type_str*)array_get(') g.expr(node.left) g.write(', ') g.expr(node.index) @@ -959,10 +963,17 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) { } } -fn (g mut Gen) call_args(args []ast.Expr, muts []bool) { +fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type) { for i, expr in args { - if muts[i] { - g.write('&/*mut*/') + if arg_types.len > 0 { + // typ := arg_types[i] + arg_is_ptr := table.type_is_ptr(arg_types[i]) + if muts[i] && !arg_is_ptr { + g.write('&/*mut*/') + } + else if arg_is_ptr { + g.write('&/*q*/') + } } g.expr(expr) if i != args.len - 1 { @@ -977,6 +988,7 @@ fn verror(s string) { } const ( +// TODO all builtin types must be lowercase builtins = ['string', 'array', 'KeyValue', 'map', 'Option'] ) diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 97bc2e2f13..0b48e2087e 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -76,7 +76,7 @@ i < 10; i++) { array_int nums3 = array_slice(nums, 1, 2); array_int nums4 = array_slice(nums, 1, nums.len); int number = (*(int*)array_get(nums, 0)); - array_set(&nums, 1, 10); + array_set(&nums, 1, &(int[]) { 10 }); array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (bool[]){ true, false, }); diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index fe0e2a5e03..23ebf97786 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -83,7 +83,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { rec_name = p.check_name() rec_mut = p.tok.kind == .key_mut // if rec_mut { - // p.check(.key_mut) + // p.check(.key_mut) // } // TODO: talk to alex, should mut be parsed with the type like this? // or should it be a property of the arg, like this ptr/mut becomes indistinguishable @@ -97,7 +97,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { } mut name := '' if p.tok.kind == .name { - // TODO high + // TODO high order fn name = p.check_name() } if p.tok.kind in [.plus, .minus, .mul, .div, .mod] { @@ -229,9 +229,9 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { arg_names << p.check_name() } is_mut := p.tok.kind == .key_mut - if is_mut { - p.check(.key_mut) - } + // if is_mut { + // p.check(.key_mut) + // } if p.tok.kind == .ellipsis { p.check(.ellipsis) is_variadic = true diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 0d13464794..1fab2dc3d9 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -16,14 +16,6 @@ import ( const ( colored_output = term.can_show_color_on_stderr() ) -/* -type PrefixParseFn fn()ast.Expr - -type InfixParseFn fn(e ast.Expr)ast.Expr - -type PostfixParseFn fn()ast.Expr -*/ - struct Parser { scanner &scanner.Scanner