parser/checker/gen: update call args to use ast.CallArg

pull/4024/head
Joe Conigliaro 2020-03-14 21:11:43 +11:00
parent 6752fed9f2
commit cc338df77f
8 changed files with 53 additions and 62 deletions

View File

@ -162,9 +162,7 @@ pub:
mut:
// func Expr
name string
args []Expr
arg_types []table.Type
expr_types []table.Type
args []CallArg
is_c bool
muts []bool
or_block OrExpr
@ -177,15 +175,21 @@ pub:
pos token.Position
expr Expr // `user` in `user.register()`
name string
args []Expr
muts []bool
args []CallArg
or_block OrExpr
mut:
expr_type table.Type // type of `user`
receiver_type table.Type // User
return_type table.Type
arg_types []table.Type
expr_types []table.Type
}
pub struct CallArg {
pub:
is_mut bool
expr Expr
mut:
typ table.Type
expected_type table.Type
}
pub struct Return {

View File

@ -229,8 +229,8 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
}
call_expr.return_type = f.return_type
if f.is_c || call_expr.is_c {
for expr in call_expr.args {
c.expr(expr)
for arg in call_expr.args {
c.expr(arg.expr)
}
return f.return_type
}
@ -242,18 +242,15 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
}
// println can print anything
if fn_name == 'println' {
call_expr.arg_types = [c.expr(call_expr.args[0])]
call_expr.args[0].typ = c.expr(call_expr.args[0].expr)
return f.return_type
}
mut arg_types := []table.Type
mut expr_types := []table.Type
for i, arg_expr in call_expr.args {
for i, call_arg 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)
expr_types << typ
// arg_types << typ // arg.typ
arg_types << arg.typ
typ := c.expr(call_arg.expr)
call_expr.args[i].typ = typ
call_expr.args[i].expected_type = arg.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) {
@ -270,8 +267,6 @@ 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
call_expr.expr_types = expr_types
return f.return_type
}
@ -281,8 +276,6 @@ 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
mut expr_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' {
@ -294,7 +287,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
})
}
else if name == 'repeat' {
c.expr(method_call_expr.args[0])
c.expr(method_call_expr.args[0].expr)
}
// need to return `array_xxx` instead of `array`
method_call_expr.return_type = typ
@ -316,15 +309,13 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
// if name == 'clone' {
// println('CLONE nr args=$method.args.len')
// }
for i, arg_expr in method_call_expr.args {
for i, arg in method_call_expr.args {
c.expected_type = method.args[i + 1].typ
arg_types << c.expected_type
expr_types << c.expr(arg_expr)
method_call_expr.args[i].expected_type = c.expected_type
method_call_expr.args[i].typ = c.expr(arg.expr)
}
method_call_expr.receiver_type = method.args[0].typ
method_call_expr.return_type = method.return_type
method_call_expr.arg_types = arg_types
method_call_expr.expr_types = expr_types
return method.return_type
}
c.error('type `$typ_sym.name` has no method `$name`', method_call_expr.pos)

View File

@ -364,7 +364,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
}
ast.CallExpr {
f.write('${it.name}(')
f.call_args(it.args, it.muts)
f.call_args(it.args)
f.write(')')
f.or_expr(it.or_block)
}
@ -490,7 +490,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
ast.MethodCallExpr {
f.expr(it.expr)
f.write('.' + it.name + '(')
f.call_args(it.args, it.muts)
f.call_args(it.args)
f.write(')')
f.or_expr(it.or_block)
}
@ -561,15 +561,15 @@ fn (f mut Fmt) wrap_long_line() {
}
}
fn (f mut Fmt) call_args(args []ast.Expr, muts []bool) {
fn (f mut Fmt) call_args(args []ast.CallArg) {
for i, arg in args {
if muts[i] {
if arg.is_mut {
f.write('mut ')
}
if i > 0 {
f.wrap_long_line()
}
f.expr(arg)
f.expr(arg.expr)
if i < args.len - 1 {
f.write(', ')
}

View File

@ -548,15 +548,15 @@ fn (g mut Gen) expr(node ast.Expr) {
name = name[3..]
}
g.write('${name}(')
if name == 'println' && it.arg_types[0] != table.string_type_idx {
if name == 'println' && it.args[0].typ != table.string_type_idx {
// `println(int_str(10))`
sym := g.table.get_type_symbol(it.arg_types[0])
sym := g.table.get_type_symbol(it.args[0].typ)
g.write('${sym.name}_str(')
g.expr(it.args[0])
g.expr(it.args[0].expr)
g.write('))')
}
else {
g.call_args(it.args, it.muts, it.arg_types, it.expr_types)
g.call_args(it.args)
g.write(')')
}
g.is_c_call = false
@ -778,7 +778,7 @@ fn (g mut Gen) expr(node ast.Expr) {
}
*/
// ///////
g.call_args(it.args, it.muts, it.arg_types, it.expr_types)
g.call_args(it.args)
g.write(')')
}
ast.None {
@ -1125,13 +1125,12 @@ fn (g mut Gen) const_decl(node ast.ConstDecl) {
}
}
fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type, expr_types []table.Type) {
for i, expr in args {
if arg_types.len > 0 {
// typ := arg_types[i]
arg_is_ptr := table.type_is_ptr(arg_types[i]) || arg_types[i] == table.voidptr_type_idx
expr_is_ptr := i < expr_types.len && table.type_is_ptr(expr_types[i])
if muts[i] && !arg_is_ptr {
fn (g mut Gen) call_args(args []ast.CallArg) {
for i, arg in args {
if arg.expected_type != 0 {
arg_is_ptr := table.type_is_ptr(arg.expected_type) || arg.expected_type == table.voidptr_type_idx
expr_is_ptr := table.type_is_ptr(arg.typ)
if arg.is_mut && !arg_is_ptr {
g.write('&/*mut*/')
}
else if arg_is_ptr && !expr_is_ptr {
@ -1142,7 +1141,7 @@ fn (g mut Gen) call_args(args []ast.Expr, muts []bool, arg_types []table.Type, e
g.write('*/*d*/')
}
}
g.expr(expr)
g.expr(arg.expr)
if i != args.len - 1 {
g.write(', ')
}

View File

@ -141,8 +141,8 @@ fn (g mut JsGen) expr(node ast.Expr) {
}
ast.CallExpr {
g.write('${it.name}(')
for i, expr in it.args {
g.expr(expr)
for i, arg in it.args {
g.expr(arg.expr)
if i != it.args.len - 1 {
g.write(', ')
}

View File

@ -361,7 +361,7 @@ fn (g mut Gen) expr(node ast.Expr) {
ast.StructInit {}
ast.CallExpr {
if it.name == 'println' || it.name == 'print' {
expr := it.args[0]
expr := it.args[0].expr
g.gen_print_from_expr(expr)
}
/*

View File

@ -13,7 +13,7 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
name := p.check_name()
fn_name := if is_c { 'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name }
p.check(.lpar)
args,muts := p.call_args()
args := p.call_args()
mut or_stmts := []ast.Stmt
if p.tok.kind == .key_orelse {
p.next()
@ -22,9 +22,7 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
node := ast.CallExpr{
name: fn_name
args: args
muts: muts
// tok: tok
pos: tok.position()
is_c: is_c
or_block: ast.OrExpr{
@ -34,25 +32,25 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
return node
}
pub fn (p mut Parser) call_args() ([]ast.Expr,[]bool) {
mut args := []ast.Expr
mut muts := []bool
pub fn (p mut Parser) call_args() []ast.CallArg {
mut args := []ast.CallArg
for p.tok.kind != .rpar {
mut is_mut := false
if p.tok.kind == .key_mut {
p.check(.key_mut)
muts << true
}
else {
muts << false
is_mut = true
}
e := p.expr(0)
args << e
args << ast.CallArg{
is_mut: is_mut
expr: e
}
if p.tok.kind != .rpar {
p.check(.comma)
}
}
p.check(.rpar)
return args,muts
return args
}
fn (p mut Parser) fn_decl() ast.FnDecl {

View File

@ -891,7 +891,7 @@ fn (p mut Parser) dot_expr(left ast.Expr) ast.Expr {
pos := p.tok.position()
if p.tok.kind == .lpar {
p.next()
args,muts := p.call_args()
args := p.call_args()
mut or_stmts := []ast.Stmt
if p.tok.kind == .key_orelse {
p.next()
@ -901,7 +901,6 @@ fn (p mut Parser) dot_expr(left ast.Expr) ast.Expr {
expr: left
name: field_name
args: args
muts: muts
pos: pos
or_block: ast.OrExpr{
stmts: or_stmts