table: use an optional for find_fn()
							parent
							
								
									1c6cbdace5
								
							
						
					
					
						commit
						040d03912b
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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, '', '')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue