diff --git a/compiler/fn.v b/compiler/fn.v index b535581038..6cb0f2c944 100644 --- a/compiler/fn.v +++ b/compiler/fn.v @@ -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 diff --git a/compiler/parser.v b/compiler/parser.v index 4308645b81..c70bbf8253 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -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) - // Not Found? Return 'void*' - if cfn.name == '' { + cfn := p.table.find_fn(name) or { + // Not Found? Return 'void*' //return 'cvoid' //'void*' return 'void*' } @@ -1605,42 +1604,41 @@ 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 != '' { - p.error('undefined: `$name`. did you mean:$suggested') + // check for misspelled function / variable / module + suggested := p.table.identify_typo(name, p.cur_fn, p.import_table) + if suggested != '' { + p.error('undefined: `$name`. did you mean:$suggested') + } + // If orig_name is a mod, then printing undefined: `mod` tells us nothing + // if p.table.known_mod(orig_name) { + if p.table.known_mod(orig_name) || p.import_table.known_alias(orig_name) { + name = name.replace('__', '.').replace('_dot_', '.') + p.error('undefined: `$name`') + } + else { + if orig_name == 'i32' { + println('`i32` alias was removed, use `int` instead') } - // If orig_name is a mod, then printing undefined: `mod` tells us nothing - // if p.table.known_mod(orig_name) { - if p.table.known_mod(orig_name) || p.import_table.known_alias(orig_name) { - name = name.replace('__', '.').replace('_dot_', '.') - p.error('undefined: `$name`') - } - else { - if orig_name == 'i32' { - println('`i32` alias was removed, use `int` instead') - } - if orig_name == 'u8' { - println('`u8` alias was removed, use `byte` instead') - } - p.error('undefined: `$orig_name`') + if orig_name == 'u8' { + println('`u8` alias was removed, use `byte` instead') } + 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, '', '') } } diff --git a/compiler/table.v b/compiler/table.v index 8c2ad64b7f..5ada992053 100644 --- a/compiler/table.v +++ b/compiler/table.v @@ -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 {