cgen: args fixes

pull/3996/head
Alexander Medvednikov 2020-03-11 21:11:27 +01:00
parent aada19f574
commit e0c85f87ae
9 changed files with 42 additions and 28 deletions

View File

@ -136,6 +136,10 @@ jobs:
ls ls
# ./1m # ./1m
#run: echo "TODO" #cd examples/x64 && ../../v -x64 hello_world.v && ./hello_world #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: ubuntu-prebuilt:

View File

@ -178,7 +178,7 @@ fn (m SortedMap) exists(key string) bool {
return false return false
} }
fn (n mapnode) find_key(k string) int { fn (n &mapnode) find_key(k string) int {
mut idx := 0 mut idx := 0
for idx < n.size && n.keys[idx] < k { for idx < n.size && n.keys[idx] < k {
idx++ idx++
@ -353,7 +353,7 @@ pub fn (m mut SortedMap) delete(key string) {
// Insert all keys of the subtree into array `keys` // Insert all keys of the subtree into array `keys`
// starting at `at`. Keys are inserted in order. // 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 mut position := at
if !isnil(n.children) { if !isnil(n.children) {
// Traverse children and insert // Traverse children and insert

View File

@ -396,7 +396,7 @@ fn (s string) add(a string) string {
for j in 0..a.len { for j in 0..a.len {
res[s.len + j] = a[j] 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 return res
} }

View File

@ -182,6 +182,7 @@ mut:
expr_type table.Type // type of `user` expr_type table.Type // type of `user`
receiver_type table.Type // User receiver_type table.Type // User
return_type table.Type return_type table.Type
arg_types []table.Type
} }
pub struct Return { pub struct Return {

View File

@ -238,10 +238,12 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
c.expr(call_expr.args[0]) c.expr(call_expr.args[0])
return f.return_type return f.return_type
} }
mut arg_types := []table.Type
for i, arg_expr in call_expr.args { 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] } 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 c.expected_type = arg.typ
typ := c.expr(arg_expr) typ := c.expr(arg_expr)
arg_types << typ
typ_sym := c.table.get_type_symbol(typ) typ_sym := c.table.get_type_symbol(typ)
arg_typ_sym := c.table.get_type_symbol(arg.typ) arg_typ_sym := c.table.get_type_symbol(arg.typ)
if !c.table.check(typ, 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) 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 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 method_call_expr.expr_type = typ
typ_sym := c.table.get_type_symbol(typ) typ_sym := c.table.get_type_symbol(typ)
name := method_call_expr.name name := method_call_expr.name
mut arg_types := []table.Type
// println('method call $name $method_call_expr.pos.line_nr') // println('method call $name $method_call_expr.pos.line_nr')
if typ_sym.kind == .array && name in ['filter', 'clone', 'repeat'] { if typ_sym.kind == .array && name in ['filter', 'clone', 'repeat'] {
if name == 'filter' { 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 { for i, arg_expr in method_call_expr.args {
c.expected_type = method.args[i + 1].typ c.expected_type = method.args[i + 1].typ
arg_types << c.expected_type
c.expr(arg_expr) c.expr(arg_expr)
} }
method_call_expr.receiver_type = method.args[0].typ method_call_expr.receiver_type = method.args[0].typ

View File

@ -410,8 +410,12 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
g.definitions.write(arg_type_name) g.definitions.write(arg_type_name)
} }
else { 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 mut s := arg_type_name + ' ' + arg.name
if arg.is_mut {
// mut arg needs one *
nr_muls = 1
}
if nr_muls > 0 { if nr_muls > 0 {
s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name 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) g.expr(it.val)
if g.is_array_set { if g.is_array_set {
g.write(')') g.write(' })')
g.is_array_set = false g.is_array_set = false
} }
g.is_assign_expr = false g.is_assign_expr = false
@ -483,7 +487,7 @@ fn (g mut Gen) expr(node ast.Expr) {
name = name[3..] name = name[3..]
} }
g.write('${name}(') g.write('${name}(')
g.call_args(it.args, it.muts) g.call_args(it.args, it.muts, it.arg_types)
g.write(')') g.write(')')
g.is_c_call = false g.is_c_call = false
} }
@ -689,7 +693,7 @@ fn (g mut Gen) expr(node ast.Expr) {
if it.args.len > 0 { if it.args.len > 0 {
g.write(', ') g.write(', ')
} }
g.call_args(it.args, it.muts) g.call_args(it.args, it.muts, it.arg_types)
g.write(')') g.write(')')
} }
ast.None { ast.None {
@ -895,18 +899,18 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) {
if !is_range && node.container_type != 0 { if !is_range && node.container_type != 0 {
sym := g.table.get_type_symbol(node.container_type) sym := g.table.get_type_symbol(node.container_type)
if sym.kind == .array { if sym.kind == .array {
info := sym.info as table.Array
elem_type_str := g.typ(info.elem_type)
if g.is_assign_expr { if g.is_assign_expr {
g.is_array_set = true g.is_array_set = true
g.write('array_set(&') g.write('array_set(&')
g.expr(node.left) g.expr(node.left)
g.write(', ') g.write(', ')
g.expr(node.index) g.expr(node.index)
g.write(', ') g.write(', &($elem_type_str[]) { ')
} }
else { else {
info := sym.info as table.Array g.write('(*($elem_type_str*)array_get(')
styp := g.typ(info.elem_type)
g.write('(*($styp*)array_get(')
g.expr(node.left) g.expr(node.left)
g.write(', ') g.write(', ')
g.expr(node.index) 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 { for i, expr in args {
if muts[i] { if arg_types.len > 0 {
g.write('&/*mut*/') // 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) g.expr(expr)
if i != args.len - 1 { if i != args.len - 1 {
@ -977,6 +988,7 @@ fn verror(s string) {
} }
const ( const (
// TODO all builtin types must be lowercase
builtins = ['string', 'array', 'KeyValue', 'map', 'Option'] builtins = ['string', 'array', 'KeyValue', 'map', 'Option']
) )

View File

@ -76,7 +76,7 @@ i < 10; i++) {
array_int nums3 = array_slice(nums, 1, 2); array_int nums3 = array_slice(nums, 1, 2);
array_int nums4 = array_slice(nums, 1, nums.len); array_int nums4 = array_slice(nums, 1, nums.len);
int number = (*(int*)array_get(nums, 0)); 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[]){ array_bool bools = new_array_from_c_array(2, 2, sizeof(array_bool), (bool[]){
true, false, true, false,
}); });

View File

@ -83,7 +83,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
rec_name = p.check_name() rec_name = p.check_name()
rec_mut = p.tok.kind == .key_mut rec_mut = p.tok.kind == .key_mut
// if rec_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? // 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 // 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 := '' mut name := ''
if p.tok.kind == .name { if p.tok.kind == .name {
// TODO high // TODO high order fn
name = p.check_name() name = p.check_name()
} }
if p.tok.kind in [.plus, .minus, .mul, .div, .mod] { 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() arg_names << p.check_name()
} }
is_mut := p.tok.kind == .key_mut is_mut := p.tok.kind == .key_mut
if is_mut { // if is_mut {
p.check(.key_mut) // p.check(.key_mut)
} // }
if p.tok.kind == .ellipsis { if p.tok.kind == .ellipsis {
p.check(.ellipsis) p.check(.ellipsis)
is_variadic = true is_variadic = true

View File

@ -16,14 +16,6 @@ import (
const ( const (
colored_output = term.can_show_color_on_stderr() 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 { struct Parser {
scanner &scanner.Scanner scanner &scanner.Scanner