ast/table: use common struct fn decl arguments

pull/4027/head
Joe Conigliaro 2020-03-15 09:21:36 +11:00
parent 395bb61cf3
commit 50ed4004f4
5 changed files with 47 additions and 66 deletions

View File

@ -127,19 +127,12 @@ pub:
// expr Expr // expr Expr
} }
pub struct Arg {
pub:
name string
is_mut bool
typ table.Type
}
pub struct FnDecl { pub struct FnDecl {
pub: pub:
name string name string
stmts []Stmt stmts []Stmt
return_type table.Type return_type table.Type
args []Arg args []table.Arg
is_deprecated bool is_deprecated bool
is_pub bool is_pub bool
is_variadic bool is_variadic bool

View File

@ -106,6 +106,9 @@ pub fn (g mut Gen) write_typedef_types() {
styp := typ.name.replace('.', '__') styp := typ.name.replace('.', '__')
g.definitions.writeln('typedef map $styp;') g.definitions.writeln('typedef map $styp;')
} }
.function {
// TODO:
}
else { else {
continue continue
} }
@ -443,11 +446,28 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
} }
*/ */
// //
no_names := it.args.len > 0 && it.args[0].name == 'arg_1' g.fn_args(it.args, it.is_variadic)
for i, arg in it.args { g.writeln(') { ')
if !is_main {
g.definitions.writeln(');')
}
for stmt in it.stmts {
// g.write('\t')
g.stmt(stmt)
}
if is_main {
g.writeln('return 0;')
}
g.writeln('}')
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) arg_type_sym := g.table.get_type_symbol(arg.typ)
mut arg_type_name := arg_type_sym.name.replace('.', '__') mut arg_type_name := arg_type_sym.name.replace('.', '__')
is_varg := i == it.args.len - 1 && it.is_variadic is_varg := i == args.len - 1 && is_variadic
if is_varg { if is_varg {
g.varaidic_args[int(arg.typ).str()] = 0 g.varaidic_args[int(arg.typ).str()] = 0
arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr') arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr')
@ -456,14 +476,7 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
func := arg_type_sym.info as table.Fn func := arg_type_sym.info as table.Fn
g.write('${g.typ(func.return_type)} (*$arg.name)(') g.write('${g.typ(func.return_type)} (*$arg.name)(')
g.definitions.write('${g.typ(func.return_type)} (*$arg.name)(') g.definitions.write('${g.typ(func.return_type)} (*$arg.name)(')
for j, a in func.args { g.fn_args(func.args, func.is_variadic)
g.write('${g.typ(a.typ)} $a.name')
g.definitions.write('${g.typ(a.typ)} $a.name')
if j < func.args.len - 1 {
g.write(',')
g.definitions.write(',')
}
}
g.write(')') g.write(')')
g.definitions.write(')') g.definitions.write(')')
} }
@ -484,24 +497,11 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
g.write(s) g.write(s)
g.definitions.write(s) g.definitions.write(s)
} }
if i < it.args.len - 1 { if i < args.len - 1 {
g.write(', ') g.write(', ')
g.definitions.write(', ') g.definitions.write(', ')
} }
} }
g.writeln(') { ')
if !is_main {
g.definitions.writeln(');')
}
for stmt in it.stmts {
// g.write('\t')
g.stmt(stmt)
}
if is_main {
g.writeln('return 0;')
}
g.writeln('}')
g.fn_decl = 0
} }
fn (g mut Gen) expr(node ast.Expr) { fn (g mut Gen) expr(node ast.Expr) {

View File

@ -73,8 +73,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
mut is_method := false mut is_method := false
mut rec_type := table.void_type mut rec_type := table.void_type
mut rec_mut := false mut rec_mut := false
mut args := []table.Var mut args := []table.Arg
mut ast_args := []ast.Arg
if p.tok.kind == .lpar { if p.tok.kind == .lpar {
is_method = true is_method = true
p.next() p.next()
@ -86,7 +85,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
// 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
rec_type = p.parse_type() rec_type = p.parse_type()
ast_args << ast.Arg{ args << table.Arg{
name: rec_name name: rec_name
is_mut: rec_mut is_mut: rec_mut
typ: rec_type typ: rec_type
@ -110,20 +109,13 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
} }
// println('fn decl $name') // println('fn decl $name')
// Args // Args
ast_args2,is_variadic := p.fn_args() args2,is_variadic := p.fn_args()
ast_args << ast_args2 args << args2
for ast_arg in ast_args { for arg in args {
var := table.Var{
name: ast_arg.name
is_mut: ast_arg.is_mut
typ: ast_arg.typ
}
args << var
p.scope.register_var(ast.Var{ p.scope.register_var(ast.Var{
name: ast_arg.name name: arg.name
typ: ast_arg.typ typ: arg.typ
}) })
// p.table.register_var(var)
} }
// Return type // Return type
mut return_type := table.void_type mut return_type := table.void_type
@ -166,7 +158,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
name: name name: name
stmts: stmts stmts: stmts
return_type: return_type return_type: return_type
args: ast_args args: args
is_deprecated: is_deprecated is_deprecated: is_deprecated
is_pub: is_pub is_pub: is_pub
is_variadic: is_variadic is_variadic: is_variadic
@ -181,9 +173,9 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
} }
} }
fn (p mut Parser) fn_args() ([]ast.Arg,bool) { fn (p mut Parser) fn_args() ([]table.Arg,bool) {
p.check(.lpar) p.check(.lpar)
mut args := []ast.Arg mut args := []table.Arg
mut is_variadic := false mut is_variadic := false
// `int, int, string` (no names, just types) // `int, int, string` (no names, just types)
types_only := p.tok.kind in [.amp] || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) || p.peek_tok.kind == .rpar types_only := p.tok.kind in [.amp] || (p.peek_tok.kind == .comma && p.table.known_type(p.tok.lit)) || p.peek_tok.kind == .rpar
@ -210,7 +202,7 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) {
} }
p.next() p.next()
} }
args << ast.Arg{ args << table.Arg{
name: arg_name name: arg_name
is_mut: is_mut is_mut: is_mut
typ: arg_type typ: arg_type
@ -239,7 +231,7 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) {
typ = table.type_to_variadic(typ) typ = table.type_to_variadic(typ)
} }
for arg_name in arg_names { for arg_name in arg_names {
args << ast.Arg{ args << table.Arg{
name: arg_name name: arg_name
is_mut: is_mut is_mut: is_mut
typ: typ typ: typ

View File

@ -70,16 +70,7 @@ pub fn (p mut Parser) parse_multi_return_type() table.Type {
pub fn (p mut Parser) parse_fn_type(name string) table.Type { pub fn (p mut Parser) parse_fn_type(name string) table.Type {
// p.warn('parse fn') // p.warn('parse fn')
p.check(.key_fn) p.check(.key_fn)
ast_args, is_variadic := p.fn_args() args, is_variadic := p.fn_args()
mut args := []table.Var
for ast_arg in ast_args {
arg := table.Var{
name: ast_arg.name
is_mut: ast_arg.is_mut
typ: ast_arg.typ
}
args << arg
}
mut return_type := table.void_type mut return_type := table.void_type
if p.tok.kind.is_start_of_type() { if p.tok.kind.is_start_of_type() {
return_type = p.parse_type() return_type = p.parse_type()

View File

@ -21,20 +21,25 @@ pub mut:
pub struct Fn { pub struct Fn {
pub: pub:
name string name string
args []Var args []Arg
return_type Type return_type Type
is_variadic bool is_variadic bool
is_c bool is_c bool
} }
pub struct Arg {
pub:
name string
is_mut bool
typ Type
}
pub struct Var { pub struct Var {
pub: pub:
name string name string
idx int
is_mut bool is_mut bool
is_const bool is_const bool
is_global bool is_global bool
scope_level int
mut: mut:
typ Type typ Type
} }