checker/gen/table: impl fn types & sum/other fixes & tidy
							parent
							
								
									1cea85df0c
								
							
						
					
					
						commit
						a1314bd199
					
				|  | @ -8,7 +8,7 @@ import ( | ||||||
| 	v.table | 	v.table | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| pub type TypeDecl = AliasTypeDecl | SumTypeDecl | pub type TypeDecl = AliasTypeDecl | SumTypeDecl | FnTypeDecl | ||||||
| 
 | 
 | ||||||
| pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | 	 | pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | 	 | ||||||
| FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | 	 | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | 	 | ||||||
|  | @ -128,15 +128,17 @@ pub: | ||||||
| 
 | 
 | ||||||
| pub struct Arg { | pub struct Arg { | ||||||
| pub: | pub: | ||||||
| 	typ  table.Type | 	 | ||||||
| 	name   string | 	name   string | ||||||
|  | 	is_mut bool | ||||||
|  | 	typ    table.Type | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct FnDecl { | pub struct FnDecl { | ||||||
| pub: | pub: | ||||||
| 	name          string | 	name          string | ||||||
| 	stmts         []Stmt | 	stmts         []Stmt | ||||||
| 	typ           table.Type | 	return_type   table.Type | ||||||
| 	args          []Arg | 	args          []Arg | ||||||
| 	is_deprecated bool | 	is_deprecated bool | ||||||
| 	is_pub        bool | 	is_pub        bool | ||||||
|  | @ -232,9 +234,9 @@ pub: | ||||||
| 	scope   &Scope | 	scope   &Scope | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct IdentFunc { | pub struct IdentFn { | ||||||
| pub mut: | pub mut: | ||||||
| 	return_type table.Type | 	typ table.Type | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct IdentVar { | pub struct IdentVar { | ||||||
|  | @ -244,7 +246,7 @@ pub mut: | ||||||
| 	is_static bool | 	is_static bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub type IdentInfo = IdentFunc | IdentVar | pub type IdentInfo = IdentFn | IdentVar | ||||||
| 
 | 
 | ||||||
| pub enum IdentKind { | pub enum IdentKind { | ||||||
| 	unresolved | 	unresolved | ||||||
|  | @ -459,6 +461,13 @@ pub: | ||||||
| 	sub_types []table.Type | 	sub_types []table.Type | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub struct FnTypeDecl { | ||||||
|  | pub: | ||||||
|  | 	name    string | ||||||
|  | 	is_pub  bool | ||||||
|  | 	typ     table.Type | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub struct DeferStmt { | pub struct DeferStmt { | ||||||
| pub: | pub: | ||||||
| 	stmts []Stmt | 	stmts []Stmt | ||||||
|  |  | ||||||
|  | @ -48,10 +48,10 @@ pub fn (node &FnDecl) str(t &table.Table) string { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	f.write(')') | 	f.write(')') | ||||||
| 	if node.typ != table.void_type { | 	if node.return_type != table.void_type { | ||||||
| 		// typ := t.type_to_str(node.typ)
 | 		// typ := t.type_to_str(node.typ)
 | ||||||
| 		// if typ.starts_with('
 | 		// if typ.starts_with('
 | ||||||
| 		f.write(' ' + t.type_to_str(node.typ)) | 		f.write(' ' + t.type_to_str(node.return_type)) | ||||||
| 	} | 	} | ||||||
| 	return f.str() | 	return f.str() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -204,6 +204,19 @@ pub fn (c mut Checker) call_expr(call_expr mut ast.CallExpr) table.Type { | ||||||
| 			f = f1 | 			f = f1 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	// check for arg (var) of fn type
 | ||||||
|  | 	if !found { | ||||||
|  | 		scope := c.file.scope.innermost(call_expr.pos.pos) | ||||||
|  | 		if var := scope.find_var(fn_name) { | ||||||
|  | 			if var.typ != 0 { | ||||||
|  | 				vts := c.table.get_type_symbol(var.typ) | ||||||
|  | 				if vts.kind == .function { | ||||||
|  | 					f = vts.info as table.Fn | ||||||
|  | 					found = true | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if !found { | 	if !found { | ||||||
| 		c.error('unknown fn: $fn_name', call_expr.pos) | 		c.error('unknown fn: $fn_name', call_expr.pos) | ||||||
| 	} | 	} | ||||||
|  | @ -277,11 +290,17 @@ pub fn (c mut Checker) method_call_expr(method_call_expr mut ast.MethodCallExpr) | ||||||
| 		return info.elem_type | 		return info.elem_type | ||||||
| 	} | 	} | ||||||
| 	if method := c.table.type_find_method(typ_sym, name) { | 	if method := c.table.type_find_method(typ_sym, name) { | ||||||
|  | 		if method_call_expr.args.len < method.args.len-1 { | ||||||
|  | 			c.error('too few arguments in call to `${typ_sym.name}.$name`', method_call_expr.pos) | ||||||
|  | 		} | ||||||
|  | 		else if !method.is_variadic && method_call_expr.args.len > method.args.len+1 { | ||||||
|  | 			c.error('too many arguments in call to `${typ_sym.name}.$name` ($method_call_expr.args.len instead of $method.args.len)', method_call_expr.pos) | ||||||
|  | 		} | ||||||
| 		// if name == 'clone' {
 | 		// if name == 'clone' {
 | ||||||
| 		// println('CLONE nr args=$method.args.len')
 | 		// println('CLONE nr args=$method.args.len')
 | ||||||
| 		// }
 | 		// }
 | ||||||
| 		for i, arg_expr in method_call_expr.args { | 		for i, arg_expr in method_call_expr.args { | ||||||
| 			c.expected_type = method.args[i].typ | 			c.expected_type = method.args[i+1].typ | ||||||
| 			c.expr(arg_expr) | 			c.expr(arg_expr) | ||||||
| 		} | 		} | ||||||
| 		method_call_expr.receiver_type = method.args[0].typ | 		method_call_expr.receiver_type = method.args[0].typ | ||||||
|  | @ -492,7 +511,7 @@ fn (c mut Checker) stmt(node ast.Stmt) { | ||||||
| 			c.expr(it.expr) | 			c.expr(it.expr) | ||||||
| 		} | 		} | ||||||
| 		ast.FnDecl { | 		ast.FnDecl { | ||||||
| 			c.fn_return_type = it.typ | 			c.fn_return_type = it.return_type | ||||||
| 			for stmt in it.stmts { | 			for stmt in it.stmts { | ||||||
| 				c.stmt(stmt) | 				c.stmt(stmt) | ||||||
| 			} | 			} | ||||||
|  | @ -697,8 +716,8 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type { | ||||||
| 	} | 	} | ||||||
| 	// second use, already resovled in unresovled branch
 | 	// second use, already resovled in unresovled branch
 | ||||||
| 	else if ident.kind == .function { | 	else if ident.kind == .function { | ||||||
| 		info := ident.info as ast.IdentFunc | 		info := ident.info as ast.IdentFn | ||||||
| 		return info.return_type | 		return info.typ | ||||||
| 	} | 	} | ||||||
| 	// Handle indents with unresolved types during the parsing step
 | 	// Handle indents with unresolved types during the parsing step
 | ||||||
| 	// (declared after first usage)
 | 	// (declared after first usage)
 | ||||||
|  | @ -719,12 +738,13 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type { | ||||||
| 		} | 		} | ||||||
| 		// Function object (not a call), e.g. `onclick(my_click)`
 | 		// Function object (not a call), e.g. `onclick(my_click)`
 | ||||||
| 		if func := c.table.find_fn(name) { | 		if func := c.table.find_fn(name) { | ||||||
|  | 			fn_type := c.table.find_or_register_fn_type(func) | ||||||
| 			ident.name = name			 | 			ident.name = name			 | ||||||
| 			ident.kind = .function | 			ident.kind = .function | ||||||
| 			ident.info = ast.IdentFunc{ | 			ident.info = ast.IdentFn{ | ||||||
| 				return_type: func.return_type | 				typ: fn_type | ||||||
| 			} | 			} | ||||||
| 			return func.return_type | 			return fn_type | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// TODO
 | 	// TODO
 | ||||||
|  | @ -889,6 +909,7 @@ pub fn (c mut Checker) enum_val(node ast.EnumVal) table.Type { | ||||||
| 	typ := c.table.get_type_symbol(table.Type(typ_idx)) | 	typ := c.table.get_type_symbol(table.Type(typ_idx)) | ||||||
| 	// println('tname=$typ.name')
 | 	// println('tname=$typ.name')
 | ||||||
| 	if typ.kind != .enum_ { | 	if typ.kind != .enum_ { | ||||||
|  | 		println('# $typ.kind.str()') | ||||||
| 		c.error('not an enum', node.pos) | 		c.error('not an enum', node.pos) | ||||||
| 	} | 	} | ||||||
| 	// info := typ.info as table.Enum
 | 	// info := typ.info as table.Enum
 | ||||||
|  |  | ||||||
|  | @ -245,7 +245,7 @@ fn (g mut Gen) stmt(node ast.Stmt) { | ||||||
| 			g.write('return') | 			g.write('return') | ||||||
| 			// multiple returns
 | 			// multiple returns
 | ||||||
| 			if it.exprs.len > 1 { | 			if it.exprs.len > 1 { | ||||||
| 				styp := g.typ(g.fn_decl.typ) | 				styp := g.typ(g.fn_decl.return_type) | ||||||
| 				g.write(' ($styp){') | 				g.write(' ($styp){') | ||||||
| 				for i, expr in it.exprs { | 				for i, expr in it.exprs { | ||||||
| 					g.write('.arg$i=') | 					g.write('.arg$i=') | ||||||
|  | @ -375,8 +375,8 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) { | ||||||
| 		if name.starts_with('_op_') { | 		if name.starts_with('_op_') { | ||||||
| 			name = op_to_fn_name(name) | 			name = op_to_fn_name(name) | ||||||
| 		} | 		} | ||||||
| 		// type_name := g.table.type_to_str(it.typ)
 | 		// type_name := g.table.type_to_str(it.return_type)
 | ||||||
| 		type_name := g.typ(it.typ) | 		type_name := g.typ(it.return_type) | ||||||
| 		g.write('$type_name ${name}(') | 		g.write('$type_name ${name}(') | ||||||
| 		g.definitions.write('$type_name ${name}(') | 		g.definitions.write('$type_name ${name}(') | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ pub fn (g mut JsGen) writeln(s string) { | ||||||
| fn (g mut JsGen) stmt(node ast.Stmt) { | fn (g mut JsGen) stmt(node ast.Stmt) { | ||||||
| 	match node { | 	match node { | ||||||
| 		ast.FnDecl { | 		ast.FnDecl { | ||||||
| 			type_sym := g.table.get_type_symbol(it.typ) | 			type_sym := g.table.get_type_symbol(it.return_type) | ||||||
| 			g.write('/** @return { $type_sym.name } **/\nfunction ${it.name}(') | 			g.write('/** @return { $type_sym.name } **/\nfunction ${it.name}(') | ||||||
| 			for arg in it.args { | 			for arg in it.args { | ||||||
| 				arg_type_sym := g.table.get_type_symbol(arg.typ) | 				arg_type_sym := g.table.get_type_symbol(arg.typ) | ||||||
|  |  | ||||||
|  | @ -81,27 +81,18 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 		is_method = true | 		is_method = true | ||||||
| 		p.next() | 		p.next() | ||||||
| 		rec_name = p.check_name() | 		rec_name = p.check_name() | ||||||
| 		if p.tok.kind == .key_mut { | 		rec_mut = p.tok.kind == .key_mut | ||||||
| 			rec_mut = true | 		// if rec_mut {
 | ||||||
| 		} | 		// 	p.check(.key_mut)
 | ||||||
|  | 		// }
 | ||||||
|  | 		// TODO: talk to alex, should mut be parsed with the type like this?
 | ||||||
|  | 		// or should it be a property of the arg, like this ptr/mut becomes indistinguishable
 | ||||||
| 		rec_type = p.parse_type() | 		rec_type = p.parse_type() | ||||||
| 		args << table.Var{ |  | ||||||
| 			// Receiver is the first arg
 |  | ||||||
| 			typ: rec_type |  | ||||||
| 			name: rec_name |  | ||||||
| 		} |  | ||||||
| 		ast_args << ast.Arg{ | 		ast_args << ast.Arg{ | ||||||
| 			name: rec_name | 			name: rec_name | ||||||
|  | 			is_mut: rec_mut | ||||||
| 			typ: rec_type | 			typ: rec_type | ||||||
| 		} | 		} | ||||||
| 		// p.table.register_var(table.Var{
 |  | ||||||
| 		// name: rec_name
 |  | ||||||
| 		// typ: rec_type
 |  | ||||||
| 		// })
 |  | ||||||
| 		p.scope.register_var(ast.Var{ |  | ||||||
| 			name: rec_name |  | ||||||
| 			typ: rec_type |  | ||||||
| 		}) |  | ||||||
| 		p.check(.rpar) | 		p.check(.rpar) | ||||||
| 	} | 	} | ||||||
| 	mut name := '' | 	mut name := '' | ||||||
|  | @ -126,6 +117,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 	for ast_arg in ast_args { | 	for ast_arg in ast_args { | ||||||
| 		var := table.Var{ | 		var := table.Var{ | ||||||
| 			name: ast_arg.name | 			name: ast_arg.name | ||||||
|  | 			is_mut: ast_arg.is_mut | ||||||
| 			typ: ast_arg.typ | 			typ: ast_arg.typ | ||||||
| 		} | 		} | ||||||
| 		args << var | 		args << var | ||||||
|  | @ -136,9 +128,9 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 		// p.table.register_var(var)
 | 		// p.table.register_var(var)
 | ||||||
| 	} | 	} | ||||||
| 	// Return type
 | 	// Return type
 | ||||||
| 	mut typ := table.void_type | 	mut return_type := table.void_type | ||||||
| 	if p.tok.kind.is_start_of_type() { | 	if p.tok.kind.is_start_of_type() { | ||||||
| 		typ = p.parse_type() | 		return_type = p.parse_type() | ||||||
| 	} | 	} | ||||||
| 	// Register
 | 	// Register
 | ||||||
| 	if is_method { | 	if is_method { | ||||||
|  | @ -147,7 +139,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 		type_sym.register_method(table.Fn{ | 		type_sym.register_method(table.Fn{ | ||||||
| 			name: name | 			name: name | ||||||
| 			args: args | 			args: args | ||||||
| 			return_type: typ | 			return_type: return_type | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
|  | @ -160,7 +152,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 		p.table.register_fn(table.Fn{ | 		p.table.register_fn(table.Fn{ | ||||||
| 			name: name | 			name: name | ||||||
| 			args: args | 			args: args | ||||||
| 			return_type: typ | 			return_type: return_type | ||||||
| 			is_variadic: is_variadic | 			is_variadic: is_variadic | ||||||
| 			is_c: is_c | 			is_c: is_c | ||||||
| 		}) | 		}) | ||||||
|  | @ -175,7 +167,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 	return ast.FnDecl{ | 	return ast.FnDecl{ | ||||||
| 		name: name | 		name: name | ||||||
| 		stmts: stmts | 		stmts: stmts | ||||||
| 		typ: typ | 		return_type: return_type | ||||||
| 		args: ast_args | 		args: ast_args | ||||||
| 		is_deprecated: is_deprecated | 		is_deprecated: is_deprecated | ||||||
| 		is_pub: is_pub | 		is_pub: is_pub | ||||||
|  | @ -202,6 +194,10 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { | ||||||
| 		mut arg_no := 1 | 		mut arg_no := 1 | ||||||
| 		for p.tok.kind != .rpar { | 		for p.tok.kind != .rpar { | ||||||
| 			arg_name := 'arg_$arg_no' | 			arg_name := 'arg_$arg_no' | ||||||
|  | 			is_mut := p.tok.kind == .key_mut | ||||||
|  | 			if is_mut { | ||||||
|  | 				p.check(.key_mut) | ||||||
|  | 			} | ||||||
| 			if p.tok.kind == .ellipsis { | 			if p.tok.kind == .ellipsis { | ||||||
| 				p.check(.ellipsis) | 				p.check(.ellipsis) | ||||||
| 				is_variadic = true | 				is_variadic = true | ||||||
|  | @ -218,6 +214,7 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { | ||||||
| 			} | 			} | ||||||
| 			args << ast.Arg{ | 			args << ast.Arg{ | ||||||
| 				name: arg_name | 				name: arg_name | ||||||
|  | 				is_mut: is_mut | ||||||
| 				typ: arg_type | 				typ: arg_type | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -231,7 +228,8 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { | ||||||
| 				p.check(.comma) | 				p.check(.comma) | ||||||
| 				arg_names << p.check_name() | 				arg_names << p.check_name() | ||||||
| 			} | 			} | ||||||
| 			if p.tok.kind == .key_mut { | 			is_mut := p.tok.kind == .key_mut | ||||||
|  | 			if is_mut { | ||||||
| 				p.check(.key_mut) | 				p.check(.key_mut) | ||||||
| 			} | 			} | ||||||
| 			if p.tok.kind == .ellipsis { | 			if p.tok.kind == .ellipsis { | ||||||
|  | @ -245,6 +243,7 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { | ||||||
| 			for arg_name in arg_names { | 			for arg_name in arg_names { | ||||||
| 				args << ast.Arg{ | 				args << ast.Arg{ | ||||||
| 					name: arg_name | 					name: arg_name | ||||||
|  | 					is_mut: is_mut | ||||||
| 					typ: typ | 					typ: typ | ||||||
| 				} | 				} | ||||||
| 				// if typ.typ.kind == .variadic && p.tok.kind == .comma {
 | 				// if typ.typ.kind == .variadic && p.tok.kind == .comma {
 | ||||||
|  |  | ||||||
|  | @ -66,15 +66,32 @@ pub fn (p mut Parser) parse_multi_return_type() table.Type { | ||||||
| 	return table.new_type(idx) | 	return table.new_type(idx) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (p mut Parser) parse_fn_type() table.Type { | // given anon name based off signature when `name` is blank
 | ||||||
| 	// p.warn('parrse fn')
 | pub fn (p mut Parser) parse_fn_type(name string) table.Type { | ||||||
|  | 	// p.warn('parse fn')
 | ||||||
| 	p.check(.key_fn) | 	p.check(.key_fn) | ||||||
| 	// p.fn_decl()
 | 	ast_args, is_variadic := p.fn_args() | ||||||
| 	p.fn_args() | 	mut args := []table.Var | ||||||
| 	if p.tok.kind.is_start_of_type() { | 	for ast_arg in ast_args { | ||||||
| 		p.parse_type() | 		arg := table.Var{ | ||||||
|  | 			name: ast_arg.name | ||||||
|  | 			is_mut: ast_arg.is_mut | ||||||
|  | 			typ: ast_arg.typ | ||||||
| 		} | 		} | ||||||
| 	return table.int_type | 		args << arg | ||||||
|  | 	} | ||||||
|  | 	mut return_type := table.void_type | ||||||
|  | 	if p.tok.kind.is_start_of_type() { | ||||||
|  | 		return_type = p.parse_type() | ||||||
|  | 	} | ||||||
|  | 	func := table.Fn{ | ||||||
|  | 		name: name | ||||||
|  | 		args: args | ||||||
|  | 		is_variadic: is_variadic | ||||||
|  | 		return_type: return_type | ||||||
|  | 	} | ||||||
|  | 	idx := p.table.find_or_register_fn_type(func) | ||||||
|  | 	return table.new_type(idx) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (p mut Parser) parse_type() table.Type { | pub fn (p mut Parser) parse_type() table.Type { | ||||||
|  | @ -137,7 +154,7 @@ pub fn (p mut Parser) parse_any_type(is_c, is_ptr bool) table.Type { | ||||||
| 	match p.tok.kind { | 	match p.tok.kind { | ||||||
| 		// func
 | 		// func
 | ||||||
| 		.key_fn { | 		.key_fn { | ||||||
| 			return p.parse_fn_type() | 			return p.parse_fn_type('') | ||||||
| 		} | 		} | ||||||
| 		// array
 | 		// array
 | ||||||
| 		.lsbr { | 		.lsbr { | ||||||
|  |  | ||||||
|  | @ -1727,6 +1727,16 @@ fn (p mut Parser) type_decl() ast.TypeDecl { | ||||||
| 			sub_types: sum_variants | 			sub_types: sum_variants | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	// function type: `type mycallback fn(string, int)`
 | ||||||
|  | 	if p.tok.kind == .key_fn { | ||||||
|  | 		fn_name := p.prepend_mod(name) | ||||||
|  | 		fn_type := p.parse_fn_type(fn_name) | ||||||
|  | 		return ast.FnTypeDecl{ | ||||||
|  | 			name: fn_name | ||||||
|  | 			is_pub: is_pub | ||||||
|  | 			typ: fn_type | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	// type MyType int
 | 	// type MyType int
 | ||||||
| 	parent_type := p.parse_type() | 	parent_type := p.parse_type() | ||||||
| 	pid := table.type_idx(parent_type) | 	pid := table.type_idx(parent_type) | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| pub type TypeInfo = Array | ArrayFixed | Map | Struct | | pub type TypeInfo = Array | ArrayFixed | Map | Struct | | ||||||
| MultiReturn | Alias | Enum | SumType | MultiReturn | Alias | Enum | SumType | Fn | ||||||
| 
 | 
 | ||||||
| pub struct TypeSymbol { | pub struct TypeSymbol { | ||||||
| pub: | pub: | ||||||
|  | @ -87,6 +87,7 @@ pub enum Kind { | ||||||
| 	sum_type | 	sum_type | ||||||
| 	alias | 	alias | ||||||
| 	enum_ | 	enum_ | ||||||
|  | 	function | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (t &TypeSymbol) str() string { | pub fn (t &TypeSymbol) str() string { | ||||||
|  |  | ||||||
|  | @ -60,6 +60,25 @@ pub fn (t mut Table) register_global(name string, typ Type) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // used to compare fn's & for naming anon fn's
 | ||||||
|  | pub fn (f &Fn) signature() string { | ||||||
|  | 	mut sig := '' | ||||||
|  | 	for i, arg in f.args { | ||||||
|  | 		// TODO: for now ignore mut/pts in sig for now
 | ||||||
|  | 		typ := type_set_nr_muls(arg.typ, 0) | ||||||
|  | 		// if arg.is_mut {
 | ||||||
|  | 		// 	sig += 'mut_'
 | ||||||
|  | 		// }
 | ||||||
|  | 		// sig += '$arg.typ'
 | ||||||
|  | 		sig += '$typ' | ||||||
|  | 		if i < f.args.len-1 { | ||||||
|  | 			sig += '_' | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	sig += '_$f.return_type' | ||||||
|  | 	return sig | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub fn (t &Table) find_fn(name string) ?Fn { | pub fn (t &Table) find_fn(name string) ?Fn { | ||||||
| 	f := t.fns[name] | 	f := t.fns[name] | ||||||
| 	if f.name.str != 0 { | 	if f.name.str != 0 { | ||||||
|  | @ -360,6 +379,20 @@ pub fn (t mut Table) find_or_register_multi_return(mr_typs []Type) int { | ||||||
| 	return t.register_type_symbol(mr_type) | 	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()' | ||||||
|  | 	} | ||||||
|  | 	return t.register_type_symbol(TypeSymbol{ | ||||||
|  | 		kind: .function | ||||||
|  | 		name: name | ||||||
|  | 		info: f | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub fn (t mut Table) add_placeholder_type(name string) int { | pub fn (t mut Table) add_placeholder_type(name string) int { | ||||||
| 	ph_type := TypeSymbol{ | 	ph_type := TypeSymbol{ | ||||||
| 		kind: .placeholder | 		kind: .placeholder | ||||||
|  | @ -440,12 +473,20 @@ pub fn (t &Table) check(got, expected Type) bool { | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else if exp_type_sym.kind == .sum_type { | 	if exp_type_sym.kind == .sum_type { | ||||||
| 		sum_info := exp_type_sym.info as SumType | 		sum_info := exp_type_sym.info as SumType | ||||||
| 		if got in sum_info.variants { | 		if got in sum_info.variants { | ||||||
| 			return true | 			return true | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	// 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() { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| 	if got_idx != exp_idx { | 	if got_idx != exp_idx { | ||||||
| 		// && got.typ.name != expected.typ.name*/
 | 		// && got.typ.name != expected.typ.name*/
 | ||||||
| 		return false | 		return false | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue