diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 8101ea6bbc..25df82703d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -127,19 +127,12 @@ pub: // expr Expr } -pub struct Arg { -pub: - name string - is_mut bool - typ table.Type -} - pub struct FnDecl { pub: name string stmts []Stmt return_type table.Type - args []Arg + args []table.Arg is_deprecated bool is_pub bool is_variadic bool diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index e70bdf39be..e8fecbeebe 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -106,6 +106,9 @@ pub fn (g mut Gen) write_typedef_types() { styp := typ.name.replace('.', '__') g.definitions.writeln('typedef map $styp;') } + .function { + // TODO: + } else { 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' - for i, arg in it.args { + g.fn_args(it.args, it.is_variadic) + 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) 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 { g.varaidic_args[int(arg.typ).str()] = 0 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 g.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.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.fn_args(func.args, func.is_variadic) g.write(')') g.definitions.write(')') } @@ -484,24 +497,11 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { g.write(s) g.definitions.write(s) } - if i < it.args.len - 1 { + if i < args.len - 1 { g.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) { diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index e543a7e9c3..f1cf122460 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -73,8 +73,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { mut is_method := false mut rec_type := table.void_type mut rec_mut := false - mut args := []table.Var - mut ast_args := []ast.Arg + mut args := []table.Arg if p.tok.kind == .lpar { is_method = true 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? // or should it be a property of the arg, like this ptr/mut becomes indistinguishable rec_type = p.parse_type() - ast_args << ast.Arg{ + args << table.Arg{ name: rec_name is_mut: rec_mut typ: rec_type @@ -110,20 +109,13 @@ fn (p mut Parser) fn_decl() ast.FnDecl { } // println('fn decl $name') // Args - ast_args2,is_variadic := p.fn_args() - ast_args << ast_args2 - for ast_arg in ast_args { - var := table.Var{ - name: ast_arg.name - is_mut: ast_arg.is_mut - typ: ast_arg.typ - } - args << var + args2,is_variadic := p.fn_args() + args << args2 + for arg in args { p.scope.register_var(ast.Var{ - name: ast_arg.name - typ: ast_arg.typ + name: arg.name + typ: arg.typ }) - // p.table.register_var(var) } // Return type mut return_type := table.void_type @@ -166,7 +158,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { name: name stmts: stmts return_type: return_type - args: ast_args + args: args is_deprecated: is_deprecated is_pub: is_pub 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) - mut args := []ast.Arg + mut args := []table.Arg mut is_variadic := false // `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 @@ -210,7 +202,7 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { } p.next() } - args << ast.Arg{ + args << table.Arg{ name: arg_name is_mut: is_mut typ: arg_type @@ -239,7 +231,7 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { typ = table.type_to_variadic(typ) } for arg_name in arg_names { - args << ast.Arg{ + args << table.Arg{ name: arg_name is_mut: is_mut typ: typ diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index d432f04649..619d1abd9a 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -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 { // p.warn('parse fn') p.check(.key_fn) - ast_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 - } + args, is_variadic := p.fn_args() mut return_type := table.void_type if p.tok.kind.is_start_of_type() { return_type = p.parse_type() diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 6ed3ffcf02..fbad26f24c 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -21,20 +21,25 @@ pub mut: pub struct Fn { pub: name string - args []Var + args []Arg return_type Type is_variadic bool is_c bool } +pub struct Arg { +pub: + name string + is_mut bool + typ Type +} + pub struct Var { pub: name string - idx int is_mut bool is_const bool is_global bool - scope_level int mut: typ Type }