table: use an optional for find_fn()

pull/2023/head
Alexander Medvednikov 2019-09-18 15:06:34 +03:00
parent 1c6cbdace5
commit 040d03912b
3 changed files with 39 additions and 40 deletions

View File

@ -238,12 +238,15 @@ fn (p mut Parser) fn_decl() {
if !is_c && !p.builtin_mod && p.mod != 'main' && receiver_typ.len == 0 {
f.name = p.prepend_mod(f.name)
}
if p.first_pass() && p.table.known_fn(f.name) && receiver_typ.len == 0 {
existing_fn := p.table.find_fn(f.name)
if p.first_pass() && receiver_typ.len == 0 {
for {
existing_fn := p.table.find_fn(f.name) or { break }
// This existing function could be defined as C decl before (no body), then we don't need to throw an erro
if !existing_fn.is_decl {
p.error('redefinition of `$f.name`')
}
break
}
}
// Generic?
mut is_generic := false

View File

@ -1488,7 +1488,7 @@ fn (p mut Parser) name_expr() string {
for { // TODO remove
mut v := p.find_var_check_new_var(name) or { break }
if ptr {
p.gen('& /*vvar*/ ')
p.gen('& /*v*/ ')
}
else if deref {
p.gen('*')
@ -1569,9 +1569,9 @@ fn (p mut Parser) name_expr() string {
p.next()
return 'int'
}
// C fn
// C function
f := Fn {
name: name// .replace('c_', '')
name: name
is_c: true
}
p.is_c_fn_call = true
@ -1579,9 +1579,8 @@ fn (p mut Parser) name_expr() string {
p.is_c_fn_call = false
// Try looking it up. Maybe its defined with "C.fn_name() fn_type",
// then we know what type it returns
cfn := p.table.find_fn(name)
cfn := p.table.find_fn(name) or {
// Not Found? Return 'void*'
if cfn.name == '' {
//return 'cvoid' //'void*'
return 'void*'
}
@ -1605,16 +1604,15 @@ fn (p mut Parser) name_expr() string {
return typ
}
// Function (not method btw, methods are handled in dot())
mut f := p.table.find_fn(name)
if f.name == '' {
// We are in a second pass, that means this function was not defined, throw an error.
mut f := p.table.find_fn(name) or {
// We are in the second pass, that means this function was not defined, throw an error.
if !p.first_pass() {
// V script? Try os module.
// TODO
if p.v_script {
name = name.replace('main__', 'os__')
f = p.table.find_fn(name)
//name = name.replace('main__', 'os__')
//f = p.table.find_fn(name)
}
if f.name == '' {
// check for misspelled function / variable / module
suggested := p.table.identify_typo(name, p.cur_fn, p.import_table)
if suggested != '' {
@ -1635,12 +1633,12 @@ fn (p mut Parser) name_expr() string {
}
p.error('undefined: `$orig_name`')
}
}
} else {
p.next()
// First pass, the function can be defined later.
return 'void'
}
return 'void'
}
// no () after func, so func is an argument, just gen its name
// TODO verify this and handle errors
@ -3550,11 +3548,10 @@ fn (p mut Parser) go_statement() {
}
// Normal function
else {
f := p.table.find_fn(p.lit)
f := p.table.find_fn(p.lit) or { panic('fn') }
if f.name == 'println' {
p.error('`go` cannot be used with `println`')
}
// println(f.name)
p.async_fn_call(f, 0, '', '')
}
}

View File

@ -169,7 +169,7 @@ const (
)
// This is used in generated C code
// This is used for debugging only
fn (f Fn) str() string {
t := Table{}
str_args := f.str_args(t)
@ -318,18 +318,17 @@ fn (table &Table) known_type_fast(t &Type) bool {
return t.name.len > 0 && !t.is_placeholder
}
fn (t &Table) find_fn(name string) Fn {
fn (t &Table) find_fn(name string) ?Fn {
f := t.fns[name]
if !isnil(f.name.str) {
return f
}
//println('ret find fn')
return Fn{}
return none
}
fn (t &Table) known_fn(name string) bool {
f := t.find_fn(name)
return f.name != ''
_ := t.find_fn(name) or { return false }
return true
}
fn (t &Table) known_const(name string) bool {