parser/checker/gen: update call args to use ast.CallArg
parent
6752fed9f2
commit
cc338df77f
|
@ -162,9 +162,7 @@ pub:
|
||||||
mut:
|
mut:
|
||||||
// func Expr
|
// func Expr
|
||||||
name string
|
name string
|
||||||
args []Expr
|
args []CallArg
|
||||||
arg_types []table.Type
|
|
||||||
expr_types []table.Type
|
|
||||||
is_c bool
|
is_c bool
|
||||||
muts []bool
|
muts []bool
|
||||||
or_block OrExpr
|
or_block OrExpr
|
||||||
|
@ -177,15 +175,21 @@ pub:
|
||||||
pos token.Position
|
pos token.Position
|
||||||
expr Expr // `user` in `user.register()`
|
expr Expr // `user` in `user.register()`
|
||||||
name string
|
name string
|
||||||
args []Expr
|
args []CallArg
|
||||||
muts []bool
|
|
||||||
or_block OrExpr
|
or_block OrExpr
|
||||||
mut:
|
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
|
}
|
||||||
expr_types []table.Type
|
|
||||||
|
pub struct CallArg {
|
||||||
|
pub:
|
||||||
|
is_mut bool
|
||||||
|
expr Expr
|
||||||
|
mut:
|
||||||
|
typ table.Type
|
||||||
|
expected_type table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Return {
|
pub struct Return {
|
||||||
|
|
|
@ -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
|
call_expr.return_type = f.return_type
|
||||||
if f.is_c || call_expr.is_c {
|
if f.is_c || call_expr.is_c {
|
||||||
for expr in call_expr.args {
|
for arg in call_expr.args {
|
||||||
c.expr(expr)
|
c.expr(arg.expr)
|
||||||
}
|
}
|
||||||
return f.return_type
|
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
|
// println can print anything
|
||||||
if fn_name == 'println' {
|
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
|
return f.return_type
|
||||||
}
|
}
|
||||||
mut arg_types := []table.Type
|
for i, call_arg in call_expr.args {
|
||||||
mut expr_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] }
|
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(call_arg.expr)
|
||||||
expr_types << typ
|
call_expr.args[i].typ = typ
|
||||||
// arg_types << typ // arg.typ
|
call_expr.args[i].expected_type = arg.typ
|
||||||
arg_types << arg.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) {
|
||||||
|
@ -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)
|
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
|
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
|
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
|
|
||||||
mut expr_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' {
|
||||||
|
@ -294,7 +287,7 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else if name == 'repeat' {
|
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`
|
// need to return `array_xxx` instead of `array`
|
||||||
method_call_expr.return_type = typ
|
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' {
|
// if name == 'clone' {
|
||||||
// println('CLONE nr args=$method.args.len')
|
// 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
|
c.expected_type = method.args[i + 1].typ
|
||||||
arg_types << c.expected_type
|
method_call_expr.args[i].expected_type = c.expected_type
|
||||||
expr_types << c.expr(arg_expr)
|
method_call_expr.args[i].typ = c.expr(arg.expr)
|
||||||
}
|
}
|
||||||
method_call_expr.receiver_type = method.args[0].typ
|
method_call_expr.receiver_type = method.args[0].typ
|
||||||
method_call_expr.return_type = method.return_type
|
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
|
return method.return_type
|
||||||
}
|
}
|
||||||
c.error('type `$typ_sym.name` has no method `$name`', method_call_expr.pos)
|
c.error('type `$typ_sym.name` has no method `$name`', method_call_expr.pos)
|
||||||
|
|
|
@ -364,7 +364,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
f.write('${it.name}(')
|
f.write('${it.name}(')
|
||||||
f.call_args(it.args, it.muts)
|
f.call_args(it.args)
|
||||||
f.write(')')
|
f.write(')')
|
||||||
f.or_expr(it.or_block)
|
f.or_expr(it.or_block)
|
||||||
}
|
}
|
||||||
|
@ -490,7 +490,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
ast.MethodCallExpr {
|
ast.MethodCallExpr {
|
||||||
f.expr(it.expr)
|
f.expr(it.expr)
|
||||||
f.write('.' + it.name + '(')
|
f.write('.' + it.name + '(')
|
||||||
f.call_args(it.args, it.muts)
|
f.call_args(it.args)
|
||||||
f.write(')')
|
f.write(')')
|
||||||
f.or_expr(it.or_block)
|
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 {
|
for i, arg in args {
|
||||||
if muts[i] {
|
if arg.is_mut {
|
||||||
f.write('mut ')
|
f.write('mut ')
|
||||||
}
|
}
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
f.wrap_long_line()
|
f.wrap_long_line()
|
||||||
}
|
}
|
||||||
f.expr(arg)
|
f.expr(arg.expr)
|
||||||
if i < args.len - 1 {
|
if i < args.len - 1 {
|
||||||
f.write(', ')
|
f.write(', ')
|
||||||
}
|
}
|
||||||
|
|
|
@ -548,15 +548,15 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
name = name[3..]
|
name = name[3..]
|
||||||
}
|
}
|
||||||
g.write('${name}(')
|
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))`
|
// `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.write('${sym.name}_str(')
|
||||||
g.expr(it.args[0])
|
g.expr(it.args[0].expr)
|
||||||
g.write('))')
|
g.write('))')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.call_args(it.args, it.muts, it.arg_types, it.expr_types)
|
g.call_args(it.args)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
g.is_c_call = false
|
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(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
ast.None {
|
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) {
|
fn (g mut Gen) call_args(args []ast.CallArg) {
|
||||||
for i, expr in args {
|
for i, arg in args {
|
||||||
if arg_types.len > 0 {
|
if arg.expected_type != 0 {
|
||||||
// typ := arg_types[i]
|
arg_is_ptr := table.type_is_ptr(arg.expected_type) || arg.expected_type == table.voidptr_type_idx
|
||||||
arg_is_ptr := table.type_is_ptr(arg_types[i]) || arg_types[i] == table.voidptr_type_idx
|
expr_is_ptr := table.type_is_ptr(arg.typ)
|
||||||
expr_is_ptr := i < expr_types.len && table.type_is_ptr(expr_types[i])
|
if arg.is_mut && !arg_is_ptr {
|
||||||
if muts[i] && !arg_is_ptr {
|
|
||||||
g.write('&/*mut*/')
|
g.write('&/*mut*/')
|
||||||
}
|
}
|
||||||
else if arg_is_ptr && !expr_is_ptr {
|
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.write('*/*d*/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.expr(expr)
|
g.expr(arg.expr)
|
||||||
if i != args.len - 1 {
|
if i != args.len - 1 {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,8 +141,8 @@ fn (g mut JsGen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
g.write('${it.name}(')
|
g.write('${it.name}(')
|
||||||
for i, expr in it.args {
|
for i, arg in it.args {
|
||||||
g.expr(expr)
|
g.expr(arg.expr)
|
||||||
if i != it.args.len - 1 {
|
if i != it.args.len - 1 {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,7 +361,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
ast.StructInit {}
|
ast.StructInit {}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
if it.name == 'println' || it.name == 'print' {
|
if it.name == 'println' || it.name == 'print' {
|
||||||
expr := it.args[0]
|
expr := it.args[0].expr
|
||||||
g.gen_print_from_expr(expr)
|
g.gen_print_from_expr(expr)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
|
||||||
name := p.check_name()
|
name := p.check_name()
|
||||||
fn_name := if is_c { 'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name }
|
fn_name := if is_c { 'C.$name' } else if mod.len > 0 { '${mod}.$name' } else { name }
|
||||||
p.check(.lpar)
|
p.check(.lpar)
|
||||||
args,muts := p.call_args()
|
args := p.call_args()
|
||||||
mut or_stmts := []ast.Stmt
|
mut or_stmts := []ast.Stmt
|
||||||
if p.tok.kind == .key_orelse {
|
if p.tok.kind == .key_orelse {
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -22,9 +22,7 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
|
||||||
node := ast.CallExpr{
|
node := ast.CallExpr{
|
||||||
name: fn_name
|
name: fn_name
|
||||||
args: args
|
args: args
|
||||||
muts: muts
|
|
||||||
// tok: tok
|
// tok: tok
|
||||||
|
|
||||||
pos: tok.position()
|
pos: tok.position()
|
||||||
is_c: is_c
|
is_c: is_c
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
|
@ -34,25 +32,25 @@ pub fn (p mut Parser) call_expr(is_c bool, mod string) ast.CallExpr {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (p mut Parser) call_args() ([]ast.Expr,[]bool) {
|
pub fn (p mut Parser) call_args() []ast.CallArg {
|
||||||
mut args := []ast.Expr
|
mut args := []ast.CallArg
|
||||||
mut muts := []bool
|
|
||||||
for p.tok.kind != .rpar {
|
for p.tok.kind != .rpar {
|
||||||
|
mut is_mut := false
|
||||||
if p.tok.kind == .key_mut {
|
if p.tok.kind == .key_mut {
|
||||||
p.check(.key_mut)
|
p.check(.key_mut)
|
||||||
muts << true
|
is_mut = true
|
||||||
}
|
|
||||||
else {
|
|
||||||
muts << false
|
|
||||||
}
|
}
|
||||||
e := p.expr(0)
|
e := p.expr(0)
|
||||||
args << e
|
args << ast.CallArg{
|
||||||
|
is_mut: is_mut
|
||||||
|
expr: e
|
||||||
|
}
|
||||||
if p.tok.kind != .rpar {
|
if p.tok.kind != .rpar {
|
||||||
p.check(.comma)
|
p.check(.comma)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.check(.rpar)
|
p.check(.rpar)
|
||||||
return args,muts
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) fn_decl() ast.FnDecl {
|
fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
|
|
|
@ -891,7 +891,7 @@ fn (p mut Parser) dot_expr(left ast.Expr) ast.Expr {
|
||||||
pos := p.tok.position()
|
pos := p.tok.position()
|
||||||
if p.tok.kind == .lpar {
|
if p.tok.kind == .lpar {
|
||||||
p.next()
|
p.next()
|
||||||
args,muts := p.call_args()
|
args := p.call_args()
|
||||||
mut or_stmts := []ast.Stmt
|
mut or_stmts := []ast.Stmt
|
||||||
if p.tok.kind == .key_orelse {
|
if p.tok.kind == .key_orelse {
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -901,7 +901,6 @@ fn (p mut Parser) dot_expr(left ast.Expr) ast.Expr {
|
||||||
expr: left
|
expr: left
|
||||||
name: field_name
|
name: field_name
|
||||||
args: args
|
args: args
|
||||||
muts: muts
|
|
||||||
pos: pos
|
pos: pos
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
|
|
Loading…
Reference in New Issue