parser: do not allow duplicate fns; cgen: move fn code to fn.v
parent
fb4cfa72cd
commit
24958df565
|
@ -141,7 +141,7 @@ fn vpm_install(module_names []string) {
|
||||||
if vcs == '' {
|
if vcs == '' {
|
||||||
vcs = supported_vcs_systems[0]
|
vcs = supported_vcs_systems[0]
|
||||||
}
|
}
|
||||||
if !vcs in supported_vcs_systems {
|
if vcs !in supported_vcs_systems {
|
||||||
errors++
|
errors++
|
||||||
println('Skipping module "$name", since it uses an unsupported VCS {$vcs} .')
|
println('Skipping module "$name", since it uses an unsupported VCS {$vcs} .')
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -13,11 +13,12 @@ struct C.cJSON {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode() voidptr {
|
pub fn decode() voidptr {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encode() voidptr {
|
pub fn encode(x voidptr) string {
|
||||||
|
// compiler implementation
|
||||||
|
return ''
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jsdecode_int(root &C.cJSON) int {
|
fn jsdecode_int(root &C.cJSON) int {
|
||||||
|
|
|
@ -890,6 +890,9 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
// c.warn('duplicate method `$it.name`', it.pos)
|
// c.warn('duplicate method `$it.name`', it.pos)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
if f := c.table.find_fn(it.name) {
|
||||||
|
c.warn('redefinition of `$it.name`', it.pos)
|
||||||
|
}
|
||||||
c.expected_type = table.void_type
|
c.expected_type = table.void_type
|
||||||
c.fn_return_type = it.return_type
|
c.fn_return_type = it.return_type
|
||||||
c.stmts(it.stmts)
|
c.stmts(it.stmts)
|
||||||
|
@ -1551,7 +1554,7 @@ pub fn (c mut Checker) error(message string, pos token.Position) {
|
||||||
fn (c mut Checker) warn_or_error(message string, pos token.Position, warn bool) {
|
fn (c mut Checker) warn_or_error(message string, pos token.Position, warn bool) {
|
||||||
// add backtrace to issue struct, how?
|
// add backtrace to issue struct, how?
|
||||||
// if c.pref.is_verbose {
|
// if c.pref.is_verbose {
|
||||||
// print_backtrace()
|
// print_backtrace()
|
||||||
// }
|
// }
|
||||||
if !warn {
|
if !warn {
|
||||||
c.nr_errors++
|
c.nr_errors++
|
||||||
|
@ -1571,7 +1574,6 @@ fn (c mut Checker) warn_or_error(message string, pos token.Position, warn bool)
|
||||||
file_path: c.file.path
|
file_path: c.file.path
|
||||||
message: message
|
message: message
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,8 @@ fn (f mut Fmt) imports(imports []ast.Import) {
|
||||||
// f.indent++
|
// f.indent++
|
||||||
for imp in imports {
|
for imp in imports {
|
||||||
if !(imp.mod in f.used_imports) {
|
if !(imp.mod in f.used_imports) {
|
||||||
continue
|
// TODO bring back once only unused imports are removed
|
||||||
|
// continue
|
||||||
}
|
}
|
||||||
f.out_imports.write('\t')
|
f.out_imports.write('\t')
|
||||||
f.out_imports.writeln(f.imp_stmt_str(imp))
|
f.out_imports.writeln(f.imp_stmt_str(imp))
|
||||||
|
@ -529,7 +530,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
f.write('_')
|
f.write('_')
|
||||||
} else {
|
} else {
|
||||||
name := short_module(it.name)
|
name := short_module(it.name)
|
||||||
//f.write('<$it.name => $name>')
|
// f.write('<$it.name => $name>')
|
||||||
f.write(name)
|
f.write(name)
|
||||||
if name.contains('.') {
|
if name.contains('.') {
|
||||||
f.mark_module_as_used(name)
|
f.mark_module_as_used(name)
|
||||||
|
@ -673,7 +674,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
ast.StructInit {
|
ast.StructInit {
|
||||||
type_sym := f.table.get_type_symbol(it.typ)
|
type_sym := f.table.get_type_symbol(it.typ)
|
||||||
//f.write('<old name: $type_sym.name>')
|
// f.write('<old name: $type_sym.name>')
|
||||||
mut name := short_module(type_sym.name).replace(f.cur_mod + '.', '') // TODO f.type_to_str?
|
mut name := short_module(type_sym.name).replace(f.cur_mod + '.', '') // TODO f.type_to_str?
|
||||||
if name == 'void' {
|
if name == 'void' {
|
||||||
name = ''
|
name = ''
|
||||||
|
|
|
@ -7,11 +7,11 @@ import (
|
||||||
strings
|
strings
|
||||||
v.ast
|
v.ast
|
||||||
v.table
|
v.table
|
||||||
v.depgraph
|
|
||||||
v.token
|
|
||||||
v.pref
|
v.pref
|
||||||
term
|
v.token
|
||||||
v.util
|
v.util
|
||||||
|
v.depgraph
|
||||||
|
term
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -21,6 +21,10 @@ const (
|
||||||
'void', 'volatile', 'while']
|
'void', 'volatile', 'while']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fn foo(t token.Token) {
|
||||||
|
util.full_hash()
|
||||||
|
}
|
||||||
|
|
||||||
struct Gen {
|
struct Gen {
|
||||||
out strings.Builder
|
out strings.Builder
|
||||||
typedefs strings.Builder
|
typedefs strings.Builder
|
||||||
|
@ -809,109 +813,6 @@ fn (g mut Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, ad
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
|
||||||
if it.is_c {
|
|
||||||
// || it.no_body {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
g.reset_tmp_count()
|
|
||||||
is_main := it.name == 'main'
|
|
||||||
if is_main {
|
|
||||||
if g.pref.os == .windows {
|
|
||||||
g.write('int wmain(int ___argc, wchar_t *___argv[], wchar_t *___envp[]')
|
|
||||||
} else {
|
|
||||||
g.write('int ${it.name}(int ___argc, char** ___argv')
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mut name := it.name
|
|
||||||
c := name[0]
|
|
||||||
if c in [`+`, `-`, `*`, `/`, `%`] {
|
|
||||||
name = util.replace_op(name)
|
|
||||||
}
|
|
||||||
if it.is_method {
|
|
||||||
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
|
||||||
}
|
|
||||||
if it.is_c {
|
|
||||||
name = name.replace('.', '__')
|
|
||||||
} else {
|
|
||||||
name = c_name(name)
|
|
||||||
}
|
|
||||||
// if g.pref.show_cc && it.is_builtin {
|
|
||||||
// println(name)
|
|
||||||
// }
|
|
||||||
// type_name := g.table.Type_to_str(it.return_type)
|
|
||||||
type_name := g.typ(it.return_type)
|
|
||||||
g.write('$type_name ${name}(')
|
|
||||||
g.definitions.write('$type_name ${name}(')
|
|
||||||
}
|
|
||||||
// Receiver is the first argument
|
|
||||||
/*
|
|
||||||
if it.is_method {
|
|
||||||
mut styp := g.typ(it.receiver.typ)
|
|
||||||
// if table.type_nr_muls(it.receiver.typ) > 0 {
|
|
||||||
// if it.rec_mut {
|
|
||||||
// styp += '*'
|
|
||||||
// }
|
|
||||||
g.write('$styp $it.receiver.name ')
|
|
||||||
// TODO mut
|
|
||||||
g.definitions.write('$styp $it.receiver.name')
|
|
||||||
if it.args.len > 0 {
|
|
||||||
g.write(', ')
|
|
||||||
g.definitions.write(', ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
//
|
|
||||||
g.fn_args(it.args, it.is_variadic)
|
|
||||||
if it.no_body || (g.pref.is_cache && it.is_builtin) {
|
|
||||||
// Just a function header.
|
|
||||||
// Builtin function bodies are defined in builtin.o
|
|
||||||
g.definitions.writeln(');')
|
|
||||||
g.writeln(');')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
g.writeln(') {')
|
|
||||||
if !is_main {
|
|
||||||
g.definitions.writeln(');')
|
|
||||||
}
|
|
||||||
if is_main {
|
|
||||||
g.writeln('\t_vinit();')
|
|
||||||
if g.is_importing_os() {
|
|
||||||
if g.autofree {
|
|
||||||
g.writeln('free(_const_os__args.data); // empty, inited in _vinit()')
|
|
||||||
}
|
|
||||||
if g.pref.os == .windows {
|
|
||||||
g.writeln('\t_const_os__args = os__init_os_args_wide(___argc, ___argv);')
|
|
||||||
} else {
|
|
||||||
g.writeln('\t_const_os__args = os__init_os_args(___argc, (byteptr*)___argv);')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.stmts(it.stmts)
|
|
||||||
// ////////////
|
|
||||||
if g.autofree {
|
|
||||||
g.free_scope_vars(it.pos.pos - 1)
|
|
||||||
}
|
|
||||||
// /////////
|
|
||||||
if is_main {
|
|
||||||
if g.autofree {
|
|
||||||
g.writeln('\t_vcleanup();')
|
|
||||||
}
|
|
||||||
if g.is_test {
|
|
||||||
verror('test files cannot have function `main`')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if g.defer_stmts.len > 0 {
|
|
||||||
g.write_defer_stmts()
|
|
||||||
}
|
|
||||||
if is_main {
|
|
||||||
g.writeln('\treturn 0;')
|
|
||||||
}
|
|
||||||
g.writeln('}')
|
|
||||||
g.defer_stmts = []
|
|
||||||
g.fn_decl = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (g mut Gen) free_scope_vars(pos int) {
|
fn (g mut Gen) free_scope_vars(pos int) {
|
||||||
scope := g.file.scope.innermost(pos)
|
scope := g.file.scope.innermost(pos)
|
||||||
for _, obj in scope.objects {
|
for _, obj in scope.objects {
|
||||||
|
@ -953,55 +854,6 @@ fn (g mut Gen) free_scope_vars(pos int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 := g.typ(arg.typ) // arg_type_sym.name.replace('.', '__')
|
|
||||||
is_varg := i == args.len - 1 && is_variadic
|
|
||||||
if is_varg {
|
|
||||||
varg_type_str := int(arg.typ).str()
|
|
||||||
if !(varg_type_str in g.variadic_args) {
|
|
||||||
g.variadic_args[varg_type_str] = 0
|
|
||||||
}
|
|
||||||
arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr')
|
|
||||||
}
|
|
||||||
if arg_type_sym.kind == .function {
|
|
||||||
info := arg_type_sym.info as table.FnType
|
|
||||||
func := info.func
|
|
||||||
if !info.is_anon {
|
|
||||||
g.write(arg_type_name + ' ' + arg.name)
|
|
||||||
g.definitions.write(arg_type_name + ' ' + arg.name)
|
|
||||||
} else {
|
|
||||||
g.write('${g.typ(func.return_type)} (*$arg.name)(')
|
|
||||||
g.definitions.write('${g.typ(func.return_type)} (*$arg.name)(')
|
|
||||||
g.fn_args(func.args, func.is_variadic)
|
|
||||||
g.write(')')
|
|
||||||
g.definitions.write(')')
|
|
||||||
}
|
|
||||||
} else if no_names {
|
|
||||||
g.write(arg_type_name)
|
|
||||||
g.definitions.write(arg_type_name)
|
|
||||||
} else {
|
|
||||||
mut nr_muls := table.type_nr_muls(arg.typ)
|
|
||||||
s := arg_type_name + ' ' + arg.name
|
|
||||||
if arg.is_mut {
|
|
||||||
// mut arg needs one *
|
|
||||||
nr_muls = 1
|
|
||||||
}
|
|
||||||
// if nr_muls > 0 && !is_varg {
|
|
||||||
// s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name
|
|
||||||
// }
|
|
||||||
g.write(s)
|
|
||||||
g.definitions.write(s)
|
|
||||||
}
|
|
||||||
if i < args.len - 1 {
|
|
||||||
g.write(', ')
|
|
||||||
g.definitions.write(', ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (g mut Gen) expr(node ast.Expr) {
|
fn (g mut Gen) expr(node ast.Expr) {
|
||||||
// println('cgen expr() line_nr=$node.pos.line_nr')
|
// println('cgen expr() line_nr=$node.pos.line_nr')
|
||||||
match node {
|
match node {
|
||||||
|
@ -2406,7 +2258,7 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
}
|
}
|
||||||
g.write('%' + sfmt[1..])
|
g.write('%' + sfmt[1..])
|
||||||
} else if node.expr_types[i] in [table.string_type, table.bool_type, table.f32_type,
|
} else if node.expr_types[i] in [table.string_type, table.bool_type, table.f32_type,
|
||||||
table.f64_type] || sym.kind in [.enum_, .array, .array_fixed] {
|
table.f64_type] || sym.kind in [.enum_, .array, .array_fixed] {
|
||||||
g.write('%.*s')
|
g.write('%.*s')
|
||||||
} else {
|
} else {
|
||||||
g.write('%d')
|
g.write('%d')
|
||||||
|
@ -2421,25 +2273,21 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
if fspec == `s` && node.expr_types[i] == table.string_type {
|
if fspec == `s` && node.expr_types[i] == table.string_type {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write('.str')
|
g.write('.str')
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
}
|
}
|
||||||
}
|
} else if node.expr_types[i] == table.string_type {
|
||||||
else if node.expr_types[i] == table.string_type {
|
|
||||||
// `name.str, name.len,`
|
// `name.str, name.len,`
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write('.len, ')
|
g.write('.len, ')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write('.str')
|
g.write('.str')
|
||||||
}
|
} else if node.expr_types[i] == table.bool_type {
|
||||||
else if node.expr_types[i] == table.bool_type {
|
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(' ? 4 : 5, ')
|
g.write(' ? 4 : 5, ')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(' ? "true" : "false"')
|
g.write(' ? "true" : "false"')
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
sym := g.table.get_type_symbol(node.expr_types[i])
|
sym := g.table.get_type_symbol(node.expr_types[i])
|
||||||
if sym.kind == .enum_ {
|
if sym.kind == .enum_ {
|
||||||
is_var := match node.exprs[i] {
|
is_var := match node.exprs[i] {
|
||||||
|
@ -2472,9 +2320,8 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
g.enum_expr(expr)
|
g.enum_expr(expr)
|
||||||
g.write('"')
|
g.write('"')
|
||||||
}
|
}
|
||||||
}
|
} else if node.expr_types[i] in [table.f32_type, table.f64_type, table.array_type,
|
||||||
else if node.expr_types[i] in [table.f32_type, table.f64_type, table.array_type,
|
table.map_type] || sym.kind in [.array, .array_fixed] {
|
||||||
table.map_type] || sym.kind in [.array, .array_fixed] {
|
|
||||||
styp := g.typ(node.expr_types[i])
|
styp := g.typ(node.expr_types[i])
|
||||||
g.write('${styp}_str(')
|
g.write('${styp}_str(')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
|
@ -2483,8 +2330,7 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
g.write('${styp}_str(')
|
g.write('${styp}_str(')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(').str')
|
g.write(').str')
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
||||||
|
// Use of this source code is governed by an MIT license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
module gen
|
||||||
|
|
||||||
|
import (
|
||||||
|
v.ast
|
||||||
|
v.table
|
||||||
|
v.util
|
||||||
|
)
|
||||||
|
|
||||||
|
fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
||||||
|
if it.is_c {
|
||||||
|
// || it.no_body {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.reset_tmp_count()
|
||||||
|
is_main := it.name == 'main'
|
||||||
|
if is_main {
|
||||||
|
if g.pref.os == .windows {
|
||||||
|
g.write('int wmain(int ___argc, wchar_t *___argv[], wchar_t *___envp[]')
|
||||||
|
} else {
|
||||||
|
g.write('int ${it.name}(int ___argc, char** ___argv')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mut name := it.name
|
||||||
|
c := name[0]
|
||||||
|
if c in [`+`, `-`, `*`, `/`, `%`] {
|
||||||
|
name = util.replace_op(name)
|
||||||
|
}
|
||||||
|
if it.is_method {
|
||||||
|
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
||||||
|
}
|
||||||
|
if it.is_c {
|
||||||
|
name = name.replace('.', '__')
|
||||||
|
} else {
|
||||||
|
name = c_name(name)
|
||||||
|
}
|
||||||
|
// if g.pref.show_cc && it.is_builtin {
|
||||||
|
// println(name)
|
||||||
|
// }
|
||||||
|
// type_name := g.table.Type_to_str(it.return_type)
|
||||||
|
type_name := g.typ(it.return_type)
|
||||||
|
g.write('$type_name ${name}(')
|
||||||
|
g.definitions.write('$type_name ${name}(')
|
||||||
|
}
|
||||||
|
// Receiver is the first argument
|
||||||
|
/*
|
||||||
|
if it.is_method {
|
||||||
|
mut styp := g.typ(it.receiver.typ)
|
||||||
|
// if table.type_nr_muls(it.receiver.typ) > 0 {
|
||||||
|
// if it.rec_mut {
|
||||||
|
// styp += '*'
|
||||||
|
// }
|
||||||
|
g.write('$styp $it.receiver.name ')
|
||||||
|
// TODO mut
|
||||||
|
g.definitions.write('$styp $it.receiver.name')
|
||||||
|
if it.args.len > 0 {
|
||||||
|
g.write(', ')
|
||||||
|
g.definitions.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//
|
||||||
|
g.fn_args(it.args, it.is_variadic)
|
||||||
|
if it.no_body || (g.pref.is_cache && it.is_builtin) {
|
||||||
|
// Just a function header.
|
||||||
|
// Builtin function bodies are defined in builtin.o
|
||||||
|
g.definitions.writeln(');')
|
||||||
|
g.writeln(');')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.writeln(') {')
|
||||||
|
if !is_main {
|
||||||
|
g.definitions.writeln(');')
|
||||||
|
}
|
||||||
|
if is_main {
|
||||||
|
g.writeln('\t_vinit();')
|
||||||
|
if g.is_importing_os() {
|
||||||
|
if g.autofree {
|
||||||
|
g.writeln('free(_const_os__args.data); // empty, inited in _vinit()')
|
||||||
|
}
|
||||||
|
if g.pref.os == .windows {
|
||||||
|
g.writeln('\t_const_os__args = os__init_os_args_wide(___argc, ___argv);')
|
||||||
|
} else {
|
||||||
|
g.writeln('\t_const_os__args = os__init_os_args(___argc, (byteptr*)___argv);')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.stmts(it.stmts)
|
||||||
|
// ////////////
|
||||||
|
if g.autofree {
|
||||||
|
g.free_scope_vars(it.pos.pos - 1)
|
||||||
|
}
|
||||||
|
// /////////
|
||||||
|
if is_main {
|
||||||
|
if g.autofree {
|
||||||
|
g.writeln('\t_vcleanup();')
|
||||||
|
}
|
||||||
|
if g.is_test {
|
||||||
|
verror('test files cannot have function `main`')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if g.defer_stmts.len > 0 {
|
||||||
|
g.write_defer_stmts()
|
||||||
|
}
|
||||||
|
if is_main {
|
||||||
|
g.writeln('\treturn 0;')
|
||||||
|
}
|
||||||
|
g.writeln('}')
|
||||||
|
g.defer_stmts = []
|
||||||
|
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 := g.typ(arg.typ) // arg_type_sym.name.replace('.', '__')
|
||||||
|
is_varg := i == args.len - 1 && is_variadic
|
||||||
|
if is_varg {
|
||||||
|
varg_type_str := int(arg.typ).str()
|
||||||
|
if !(varg_type_str in g.variadic_args) {
|
||||||
|
g.variadic_args[varg_type_str] = 0
|
||||||
|
}
|
||||||
|
arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr')
|
||||||
|
}
|
||||||
|
if arg_type_sym.kind == .function {
|
||||||
|
info := arg_type_sym.info as table.FnType
|
||||||
|
func := info.func
|
||||||
|
if !info.is_anon {
|
||||||
|
g.write(arg_type_name + ' ' + arg.name)
|
||||||
|
g.definitions.write(arg_type_name + ' ' + arg.name)
|
||||||
|
} else {
|
||||||
|
g.write('${g.typ(func.return_type)} (*$arg.name)(')
|
||||||
|
g.definitions.write('${g.typ(func.return_type)} (*$arg.name)(')
|
||||||
|
g.fn_args(func.args, func.is_variadic)
|
||||||
|
g.write(')')
|
||||||
|
g.definitions.write(')')
|
||||||
|
}
|
||||||
|
} else if no_names {
|
||||||
|
g.write(arg_type_name)
|
||||||
|
g.definitions.write(arg_type_name)
|
||||||
|
} else {
|
||||||
|
mut nr_muls := table.type_nr_muls(arg.typ)
|
||||||
|
s := arg_type_name + ' ' + arg.name
|
||||||
|
if arg.is_mut {
|
||||||
|
// mut arg needs one *
|
||||||
|
nr_muls = 1
|
||||||
|
}
|
||||||
|
// if nr_muls > 0 && !is_varg {
|
||||||
|
// s = arg_type_name + strings.repeat(`*`, nr_muls) + ' ' + arg.name
|
||||||
|
// }
|
||||||
|
g.write(s)
|
||||||
|
g.definitions.write(s)
|
||||||
|
}
|
||||||
|
if i < args.len - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
g.definitions.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -176,6 +176,9 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
} else {
|
} else {
|
||||||
name = p.prepend_mod(name)
|
name = p.prepend_mod(name)
|
||||||
}
|
}
|
||||||
|
if _ := p.table.find_fn(name) {
|
||||||
|
p.error('redefinition of `$name`')
|
||||||
|
}
|
||||||
p.table.register_fn(table.Fn{
|
p.table.register_fn(table.Fn{
|
||||||
name: name
|
name: name
|
||||||
args: args
|
args: args
|
||||||
|
|
Loading…
Reference in New Issue