1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: gen fn type declerations

This commit is contained in:
Joe Conigliaro 2020-03-16 20:12:03 +11:00
parent 0f160707a4
commit cf094c6265
5 changed files with 40 additions and 13 deletions

View File

@ -220,7 +220,8 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type {
if var.typ != 0 {
vts := c.table.get_type_symbol(var.typ)
if vts.kind == .function {
f = vts.info as table.Fn
info := vts.info as table.FnType
f = info.func
found = true
}
}
@ -769,7 +770,7 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
}
// Function object (not a call), e.g. `onclick(my_click)`
if func := c.table.find_fn(name) {
fn_type := c.table.find_or_register_fn_type(func)
fn_type := table.new_type(c.table.find_or_register_fn_type(func, true))
ident.name = name
ident.kind = .function
ident.info = ast.IdentFn{

View File

@ -110,8 +110,21 @@ pub fn (g mut Gen) write_typedef_types() {
styp := typ.name.replace('.', '__')
g.definitions.writeln('typedef map $styp;')
}
// TODO:
.function {}
.function {
info := typ.info as table.FnType
func := info.func
if !info.has_decl && !info.is_anon {
fn_name := func.name.replace('.', '__')
g.definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(')
for i,arg in func.args {
g.definitions.write(g.typ(arg.typ))
if i < func.args.len - 1 {
g.definitions.write(',')
}
}
g.definitions.writeln(');')
}
}
else {
continue
}
@ -509,7 +522,8 @@ fn (g mut Gen) fn_args(args []table.Arg, is_variadic bool) {
arg_type_name = 'varg_' + g.typ(arg.typ).replace('*', '_ptr')
}
if arg_type_sym.kind == .function {
func := arg_type_sym.info as table.Fn
info := arg_type_sym.info as table.FnType
func := info.func
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)

View File

@ -81,7 +81,7 @@ pub fn (p mut Parser) parse_fn_type(name string) table.Type {
is_variadic: is_variadic
return_type: return_type
}
idx := p.table.find_or_register_fn_type(func)
idx := p.table.find_or_register_fn_type(func, false)
return table.new_type(idx)
}

View File

@ -7,7 +7,7 @@ import (
pub type Type int
pub type TypeInfo = Array | ArrayFixed | Map | Struct |
MultiReturn | Alias | Enum | SumType | Fn
MultiReturn | Alias | Enum | SumType | FnType
pub struct TypeSymbol {
pub:
@ -214,6 +214,13 @@ mut:
types []Type
}
pub struct FnType {
pub:
is_anon bool
has_decl bool
func Fn
}
pub enum Kind {
placeholder
void

View File

@ -388,12 +388,17 @@ pub fn (t mut Table) find_or_register_multi_return(mr_typs []Type) int {
return t.register_type_symbol(mr_type)
}
pub fn (t mut Table) find_or_register_fn_type(f Fn) int {
name := if f.name.len > 0 { f.name } else { 'anon_$f.signature()' }
pub fn (t mut Table) find_or_register_fn_type(f Fn, has_decl bool) int {
is_anon := f.name.len == 0
name := if is_anon { 'anon_fn_$f.signature()' } else { f.name }
return t.register_type_symbol(TypeSymbol{
kind: .function
name: name
info: f
info: FnType{
is_anon: is_anon
has_decl: has_decl
func: f
}
})
}
@ -485,9 +490,9 @@ pub fn (t &Table) check(got, expected Type) bool {
}
// fn type
if got_type_sym.kind == .function && exp_type_sym.kind == .function {
got_fn := got_type_sym.info as Fn
exp_fn := exp_type_sym.info as Fn
if got_fn.signature() == exp_fn.signature() {
got_info := got_type_sym.info as FnType
exp_info := exp_type_sym.info as FnType
if got_info.func.signature() == exp_info.func.signature() {
return true
}
}