parser/cgen: anon fn var & calling (#4534)
							parent
							
								
									ee2e83fef0
								
							
						
					
					
						commit
						abf5942433
					
				|  | @ -1341,6 +1341,7 @@ pub fn (c mut Checker) expr(node ast.Expr) table.Type { | |||
| 			return table.string_type | ||||
| 		} | ||||
| 		ast.AnonFn { | ||||
| 			c.stmts(it.decl.stmts) | ||||
| 			return it.typ | ||||
| 		} | ||||
| 		else { | ||||
|  | @ -1441,7 +1442,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 := table.new_type(c.table.find_or_register_fn_type(func, true)) | ||||
| 			fn_type := table.new_type(c.table.find_or_register_fn_type(func, false, true)) | ||||
| 			ident.name = name | ||||
| 			ident.kind = .function | ||||
| 			ident.info = ast.IdentFn{ | ||||
|  |  | |||
|  | @ -269,7 +269,7 @@ pub fn (mut g Gen) write_typedef_types() { | |||
| 			.function { | ||||
| 				info := typ.info as table.FnType | ||||
| 				func := info.func | ||||
| 				if !info.has_decl { | ||||
| 				if !info.has_decl && !info.is_anon { | ||||
| 					fn_name := if func.is_c { | ||||
| 						func.name.replace('.', '__') | ||||
| 					} else if info.is_anon { | ||||
|  | @ -762,6 +762,18 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | |||
| 					or_stmts = it.or_block.stmts | ||||
| 					return_type = it.return_type | ||||
| 				} | ||||
| 				ast.AnonFn { | ||||
| 					g.expr(*it) | ||||
| 					// TODO: no buffer fiddling
 | ||||
| 					fsym := g.table.get_type_symbol(it.typ) | ||||
| 					ret_styp := g.typ(it.decl.return_type) | ||||
| 					g.write('$ret_styp (*$ident.name) (') | ||||
| 					def_pos := g.definitions.len | ||||
| 					g.fn_args(it.decl.args, it.decl.is_variadic) | ||||
| 					g.definitions.go_back(g.definitions.len - def_pos) | ||||
| 					g.writeln(') = &${fsym.name};') | ||||
| 					continue | ||||
| 				} | ||||
| 				else {} | ||||
| 			} | ||||
| 			gen_or := is_call && table.type_is(return_type, .optional) | ||||
|  | @ -1104,28 +1116,14 @@ fn (mut g Gen) expr(node ast.Expr) { | |||
| 			g.typeof_expr(it) | ||||
| 		} | ||||
| 		ast.AnonFn { | ||||
| 			sym := g.table.get_type_symbol(it.typ) | ||||
| 			func := it.decl | ||||
| 			// TODO: Fix hack and write function implementation directly to definitions
 | ||||
| 			// TODO: dont fiddle with buffers
 | ||||
| 			pos := g.out.len | ||||
| 			type_name := g.typ(func.return_type) | ||||
| 			g.write('$type_name ${sym.name}_impl(') | ||||
| 			g.fn_args(func.args, func.is_variadic) | ||||
| 			g.writeln(') {') | ||||
| 			g.stmts(func.stmts) | ||||
| 			if g.autofree { | ||||
| 				g.free_scope_vars(func.pos.pos - 1) | ||||
| 			} | ||||
| 			if g.defer_stmts.len > 0 { | ||||
| 				g.write_defer_stmts() | ||||
| 			} | ||||
| 			g.out.writeln('}') | ||||
| 			g.defer_stmts = [] | ||||
| 			g.fn_decl = 0 | ||||
| 			def_pos := g.definitions.len | ||||
| 			g.stmt(it.decl) | ||||
| 			fn_body := g.out.after(pos) | ||||
| 			g.definitions.go_back(g.definitions.len - def_pos) | ||||
| 			g.definitions.write(fn_body) | ||||
| 			g.out.go_back(fn_body.len) | ||||
| 			g.out.write('&${sym.name}_impl') | ||||
| 		} | ||||
| 		else { | ||||
| 			// #printf("node=%d\n", node.typ);
 | ||||
|  |  | |||
|  | @ -238,7 +238,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { | |||
| 
 | ||||
| fn (mut p Parser) anon_fn() ast.AnonFn { | ||||
| 	pos := p.tok.position() | ||||
| 	p.open_scope() | ||||
| 	// p.open_scope()
 | ||||
| 	p.check(.key_fn) | ||||
| 	// TODO generics
 | ||||
| 	args, is_variadic := p.fn_args() | ||||
|  | @ -257,15 +257,17 @@ fn (mut p Parser) anon_fn() ast.AnonFn { | |||
| 	if p.tok.kind == .lcbr { | ||||
| 		stmts = p.parse_block() | ||||
| 	} | ||||
| 	p.close_scope() | ||||
| 	// p.close_scope()
 | ||||
| 	func := table.Fn{ | ||||
| 		args: args | ||||
| 		is_variadic: is_variadic | ||||
| 		return_type: return_type | ||||
| 	} | ||||
| 	idx := p.table.find_or_register_fn_type(func, false) | ||||
| 	name := 'anon_${p.tok.pos}_$func.signature()' | ||||
| 	func.name = name | ||||
| 	idx := p.table.find_or_register_fn_type(func, true, false) | ||||
| 	typ := table.new_type(idx) | ||||
| 	name := p.table.get_type_name(typ) | ||||
| 	//name := p.table.get_type_name(typ)
 | ||||
| 	return ast.AnonFn{ | ||||
| 		decl: ast.FnDecl{ | ||||
| 			name: name | ||||
|  |  | |||
|  | @ -80,7 +80,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, false) | ||||
| 	idx := p.table.find_or_register_fn_type(func, false, false) | ||||
| 	return table.new_type(idx) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -390,14 +390,13 @@ pub fn (var t Table) find_or_register_multi_return(mr_typs []Type) int { | |||
| 	return t.register_type_symbol(mr_type) | ||||
| } | ||||
| 
 | ||||
| pub fn (var t 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 } | ||||
| pub fn (var t Table) find_or_register_fn_type(f Fn, is_anon bool, has_decl bool) int { | ||||
| 	name := if f.name.len == 0 { 'anon_fn_$f.signature()' } else { f.name } | ||||
| 	return t.register_type_symbol(TypeSymbol{ | ||||
| 		kind: .function | ||||
| 		name: name | ||||
| 		info: FnType{ | ||||
| 			is_anon: is_anon | ||||
| 			is_anon: f.name.len == 0 || is_anon | ||||
| 			has_decl: has_decl | ||||
| 			func: f | ||||
| 		} | ||||
|  |  | |||
|  | @ -125,6 +125,16 @@ fn test_fns() { | |||
| } | ||||
| 
 | ||||
| fn test_anon_fn() { | ||||
| 	f1 := fn(a int){ | ||||
| 		println('hello from f1') | ||||
| 	} | ||||
| 
 | ||||
| 	f1(1) | ||||
| 	f2 := fn(a int){ | ||||
| 		println('hello from f2') | ||||
| 	} | ||||
| 
 | ||||
| 	f2(1) | ||||
| 	/* | ||||
| 	high_fn(fn (x int) int { | ||||
| 		println('hello') | ||||
|  | @ -165,3 +175,4 @@ fn test_fn_type_call() { | |||
| 	st1 := &MySt{f:test} | ||||
|     assert st1.f(10) == 1010 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue