v2: lots of small fixes parent method/field resolution
							parent
							
								
									ea9961a8fb
								
							
						
					
					
						commit
						9e9bdc32ea
					
				|  | @ -111,12 +111,13 @@ pub: | ||||||
| 
 | 
 | ||||||
| pub struct FnDecl { | pub struct FnDecl { | ||||||
| pub: | pub: | ||||||
| 	name     string | 	name        string | ||||||
| 	stmts    []Stmt | 	stmts       []Stmt | ||||||
| 	typ      table.TypeRef | 	typ         table.TypeRef | ||||||
| 	args     []Arg | 	args        []Arg | ||||||
| 	is_pub   bool | 	is_pub      bool | ||||||
| 	receiver Field | 	is_variadic bool | ||||||
|  | 	receiver    Field | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct BranchStmt { | pub struct BranchStmt { | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ pub fn (c mut Checker) check(ast_file ast.File) { | ||||||
| 	// if ast_file.unresolved.len != c.resolved.len {
 | 	// if ast_file.unresolved.len != c.resolved.len {
 | ||||||
| 	// c.resolve_exprs(file)
 | 	// c.resolve_exprs(file)
 | ||||||
| 	// }
 | 	// }
 | ||||||
| 	c.complete_types(ast_file) | 	c.complete_types() | ||||||
| 	for stmt in ast_file.stmts { | 	for stmt in ast_file.stmts { | ||||||
| 		c.stmt(stmt) | 		c.stmt(stmt) | ||||||
| 	} | 	} | ||||||
|  | @ -39,7 +39,7 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) { | ||||||
| 	// files this muse be done first. TODO: optimize
 | 	// files this muse be done first. TODO: optimize
 | ||||||
| 	for file in ast_files { | 	for file in ast_files { | ||||||
| 		c.file_name = file.path | 		c.file_name = file.path | ||||||
| 		c.resolve_expr_types(file) | 		c.resolve_expr_types(file.unresolved) | ||||||
| 	} | 	} | ||||||
| 	for file in ast_files { | 	for file in ast_files { | ||||||
| 		c.check(file) | 		c.check(file) | ||||||
|  | @ -47,14 +47,14 @@ pub fn (c mut Checker) check_files(ast_files []ast.File) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // resolve type of unresolved expressions
 | // resolve type of unresolved expressions
 | ||||||
| fn (c mut Checker) resolve_expr_types(f ast.File) { | fn (c mut Checker) resolve_expr_types(exprs []ast.Expr) { | ||||||
| 	for x in f.unresolved { | 	for x in exprs { | ||||||
| 		c.resolved << c.expr(x) | 		c.resolved << c.expr(x) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // update any types chich contain unresolved sub types
 | // update any types chich contain unresolved sub types
 | ||||||
| fn (c &Checker) complete_types(f ast.File) { | fn (c &Checker) complete_types() { | ||||||
| 	for idx, t in c.table.types { | 	for idx, t in c.table.types { | ||||||
| 		// println('Resolve type: $t.name')
 | 		// println('Resolve type: $t.name')
 | ||||||
| 		if t.kind == .array { | 		if t.kind == .array { | ||||||
|  | @ -160,6 +160,16 @@ pub fn (c &Checker) call_expr(call_expr ast.CallExpr) table.TypeRef { | ||||||
| 				c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.args.len)', call_expr.pos) | 				c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.args.len)', call_expr.pos) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		// for debugging
 | ||||||
|  | 		if f.name == 'backtrace_symbols_fd' { | ||||||
|  | 			println('ARGS FOR: backtrace_symbols_fd:') | ||||||
|  | 			for i, arg_expr in  call_expr.args { | ||||||
|  | 				typ := c.expr(arg_expr) | ||||||
|  | 				println(' -- $i - $typ.typ.name') | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		// TODO: variadic
 | ||||||
|  | 		if fn_name != 'printf' && f.args.len > 0 { | ||||||
| 		for i, arg in f.args { | 		for i, arg in f.args { | ||||||
| 			arg_expr := call_expr.args[i] | 			arg_expr := call_expr.args[i] | ||||||
| 			typ := c.expr(arg_expr) | 			typ := c.expr(arg_expr) | ||||||
|  | @ -167,6 +177,7 @@ pub fn (c &Checker) call_expr(call_expr ast.CallExpr) table.TypeRef { | ||||||
| 				c.error('!cannot use type `$typ.typ.name` as type `$arg.typ.typ.name` in argument to `$fn_name`', call_expr.pos) | 				c.error('!cannot use type `$typ.typ.name` as type `$arg.typ.typ.name` in argument to `$fn_name`', call_expr.pos) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		} | ||||||
| 		return f.return_type | 		return f.return_type | ||||||
| 	} | 	} | ||||||
| 	c.error('unknown fn: $fn_name', call_expr.pos) | 	c.error('unknown fn: $fn_name', call_expr.pos) | ||||||
|  | @ -178,11 +189,9 @@ pub fn (c &Checker) check_method_call_expr(method_call_expr ast.MethodCallExpr) | ||||||
| 	if method := typ.typ.find_method(method_call_expr.name) { | 	if method := typ.typ.find_method(method_call_expr.name) { | ||||||
| 		return method.return_type | 		return method.return_type | ||||||
| 	} | 	} | ||||||
| 	if typ.typ.kind == .array { | 	// check parent
 | ||||||
| 		a := c.table.find_type('array') or { | 	if !isnil(typ.typ.parent) { | ||||||
| 			exit(1) | 		if method := typ.typ.parent.find_method(method_call_expr.name) { | ||||||
| 		} |  | ||||||
| 		if method := a.find_method(method_call_expr.name) { |  | ||||||
| 			return method.return_type | 			return method.return_type | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -201,13 +210,17 @@ pub fn (c &Checker) selector_expr(selector_expr ast.SelectorExpr) table.TypeRef | ||||||
| 			} | 			} | ||||||
| 			return field.typ | 			return field.typ | ||||||
| 		} | 		} | ||||||
| 		.array { |  | ||||||
| 			if field_name == 'len' { |  | ||||||
| 				return c.table.type_ref(table.int_type_idx) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		.string {} |  | ||||||
| 		else { | 		else { | ||||||
|  | 			// types with parent struct (array/maps) handled here
 | ||||||
|  | 			if !isnil(typ.typ.parent) && typ.typ.parent.kind == .struct_ { | ||||||
|  | 				parent := typ.typ.parent | ||||||
|  | 				if field := c.table.struct_find_field(parent, field_name) { | ||||||
|  | 					if field.typ.typ.kind == .unresolved { | ||||||
|  | 						return c.resolved[field.typ.idx] | ||||||
|  | 					} | ||||||
|  | 					return field.typ | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 			c.error('`$typ.typ.name` is not a struct', selector_expr.pos) | 			c.error('`$typ.typ.name` is not a struct', selector_expr.pos) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -439,6 +452,8 @@ pub fn (c &Checker) error(s string, pos token.Position) { | ||||||
| 		path = path.replace(workdir, '') | 		path = path.replace(workdir, '') | ||||||
| 	} | 	} | ||||||
| 	final_msg_line := '$path:$pos.line_nr: checker error: $s' | 	final_msg_line := '$path:$pos.line_nr: checker error: $s' | ||||||
|  | 	// sometimes eprintln wasnt working?
 | ||||||
|  | 	println(final_msg_line) | ||||||
| 	eprintln(final_msg_line) | 	eprintln(final_msg_line) | ||||||
| 	/* | 	/* | ||||||
| 	if colored_output { | 	if colored_output { | ||||||
|  |  | ||||||
|  | @ -72,8 +72,12 @@ fn (g mut Gen) stmt(node ast.Stmt) { | ||||||
| 				g.definitions.write('$it.typ.typ.name ${it.name}(') | 				g.definitions.write('$it.typ.typ.name ${it.name}(') | ||||||
| 			} | 			} | ||||||
| 			for i, arg in it.args { | 			for i, arg in it.args { | ||||||
| 				g.write(arg.typ.typ.name + ' ' + arg.name) | 				mut arg_type := arg.typ.typ.name | ||||||
| 				g.definitions.write(arg.typ.typ.name + ' ' + arg.name) | 				if i == it.args.len-1 && it.is_variadic { | ||||||
|  | 					arg_type = 'variadic_$arg.typ.typ.name' | ||||||
|  | 				} | ||||||
|  | 				g.write(arg_type + ' ' + arg.name) | ||||||
|  | 				g.definitions.write(arg_type + ' ' + arg.name) | ||||||
| 				if i < it.args.len - 1 { | 				if i < it.args.len - 1 { | ||||||
| 					g.write(', ') | 					g.write(', ') | ||||||
| 					g.definitions.write(', ') | 					g.definitions.write(', ') | ||||||
|  |  | ||||||
|  | @ -18,7 +18,6 @@ pub fn (p mut Parser) call_expr() (ast.CallExpr,table.TypeRef) { | ||||||
| 		name: fn_name | 		name: fn_name | ||||||
| 		args: args | 		args: args | ||||||
| 		// tok: tok
 | 		// tok: tok
 | ||||||
| 		 |  | ||||||
| 		pos: tok.position() | 		pos: tok.position() | ||||||
| 	} | 	} | ||||||
| 	if p.tok.kind == .key_orelse { | 	if p.tok.kind == .key_orelse { | ||||||
|  | @ -93,6 +92,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 	} | 	} | ||||||
| 	// println('fn decl $name')
 | 	// println('fn decl $name')
 | ||||||
| 	p.check(.lpar) | 	p.check(.lpar) | ||||||
|  | 	mut is_variadic := false | ||||||
| 	// Args
 | 	// Args
 | ||||||
| 	mut args := []table.Var | 	mut args := []table.Var | ||||||
| 	mut ast_args := []ast.Arg | 	mut ast_args := []ast.Arg | ||||||
|  | @ -102,12 +102,32 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 	p.peek_tok.kind == .rpar | 	p.peek_tok.kind == .rpar | ||||||
| 	if types_only { | 	if types_only { | ||||||
| 		p.warn('types only') | 		p.warn('types only') | ||||||
|  | 		mut arg_no := 1 | ||||||
| 		for p.tok.kind != .rpar { | 		for p.tok.kind != .rpar { | ||||||
| 			p.parse_type() | 			arg_name := 'arg_$arg_no' | ||||||
|  | 			if p.tok.kind == .ellipsis { | ||||||
|  | 				p.check(.ellipsis) | ||||||
|  | 				is_variadic = true | ||||||
|  | 			} | ||||||
|  | 			arg_type := p.parse_type() | ||||||
| 			if p.tok.kind == .comma { | 			if p.tok.kind == .comma { | ||||||
|  | 				if is_variadic { | ||||||
|  | 					p.error('cannot use ...(variadic) with non-final parameter no $arg_no') | ||||||
|  | 				} | ||||||
| 				p.next() | 				p.next() | ||||||
| 			} | 			} | ||||||
|  | 			arg := table.Var{ | ||||||
|  | 				name: arg_name | ||||||
|  | 				typ: arg_type | ||||||
|  | 			} | ||||||
|  | 			args << arg | ||||||
|  | 			//p.table.register_var(arg)
 | ||||||
|  | 			ast_args << ast.Arg{ | ||||||
|  | 				name: arg_name | ||||||
|  | 				typ: arg_type | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
|  | 		arg_no++ | ||||||
| 	} | 	} | ||||||
| 	else { | 	else { | ||||||
| 		for p.tok.kind != .rpar { | 		for p.tok.kind != .rpar { | ||||||
|  | @ -120,6 +140,10 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 			if p.tok.kind == .key_mut { | 			if p.tok.kind == .key_mut { | ||||||
| 				p.check(.key_mut) | 				p.check(.key_mut) | ||||||
| 			} | 			} | ||||||
|  | 			if p.tok.kind == .ellipsis { | ||||||
|  | 				p.check(.ellipsis) | ||||||
|  | 				is_variadic = true | ||||||
|  | 			} | ||||||
| 			typ := p.parse_type() | 			typ := p.parse_type() | ||||||
| 			for arg_name in arg_names { | 			for arg_name in arg_names { | ||||||
| 				arg := table.Var{ | 				arg := table.Var{ | ||||||
|  | @ -129,10 +153,11 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 				args << arg | 				args << arg | ||||||
| 				p.table.register_var(arg) | 				p.table.register_var(arg) | ||||||
| 				ast_args << ast.Arg{ | 				ast_args << ast.Arg{ | ||||||
| 					typ: typ |  | ||||||
| 					name: arg_name | 					name: arg_name | ||||||
|  | 					typ: typ | ||||||
| 				} | 				} | ||||||
| 				if typ.typ.kind == .variadic && p.tok.kind == .comma { | 				//if typ.typ.kind == .variadic && p.tok.kind == .comma {
 | ||||||
|  | 				if is_variadic && p.tok.kind == .comma { | ||||||
| 					p.error('cannot use ...(variadic) with non-final parameter $arg_name') | 					p.error('cannot use ...(variadic) with non-final parameter $arg_name') | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -167,6 +192,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 			name: name | 			name: name | ||||||
| 			args: args | 			args: args | ||||||
| 			return_type: typ | 			return_type: typ | ||||||
|  | 			is_variadic: is_variadic | ||||||
| 			is_c: is_c | 			is_c: is_c | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
|  | @ -180,6 +206,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl { | ||||||
| 		typ: typ | 		typ: typ | ||||||
| 		args: ast_args | 		args: ast_args | ||||||
| 		is_pub: is_pub | 		is_pub: is_pub | ||||||
|  | 		is_variadic: is_variadic | ||||||
| 		receiver: ast.Field{ | 		receiver: ast.Field{ | ||||||
| 			name: rec_name | 			name: rec_name | ||||||
| 			typ: rec_type | 			typ: rec_type | ||||||
|  |  | ||||||
|  | @ -62,13 +62,6 @@ pub fn (p mut Parser) parse_multi_return_ti() table.TypeRef { | ||||||
| 	return p.table.type_ref(idx) | 	return p.table.type_ref(idx) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (p mut Parser) parse_variadic_ti() table.TypeRef { |  | ||||||
| 	p.check(.ellipsis) |  | ||||||
| 	variadic_type := p.parse_type() |  | ||||||
| 	idx := p.table.find_or_register_variadic(variadic_type) |  | ||||||
| 	return p.table.type_ref(idx) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub fn (p mut Parser) parse_fn_type() table.TypeRef { | pub fn (p mut Parser) parse_fn_type() table.TypeRef { | ||||||
| 	// p.check(.key_fn)
 | 	// p.check(.key_fn)
 | ||||||
| 	p.fn_decl() | 	p.fn_decl() | ||||||
|  | @ -105,13 +98,6 @@ pub fn (p mut Parser) parse_type() table.TypeRef { | ||||||
| 			} | 			} | ||||||
| 			return p.parse_multi_return_ti() | 			return p.parse_multi_return_ti() | ||||||
| 		} | 		} | ||||||
| 		// variadic
 |  | ||||||
| 		.ellipsis { |  | ||||||
| 			if nr_muls > 0 { |  | ||||||
| 				p.error('parse_ti: unexpected `&` before variadic') |  | ||||||
| 			} |  | ||||||
| 			return p.parse_variadic_ti() |  | ||||||
| 		} |  | ||||||
| 		else { | 		else { | ||||||
| 			defer { | 			defer { | ||||||
| 				p.next() | 				p.next() | ||||||
|  |  | ||||||
|  | @ -71,12 +71,13 @@ pub fn parse_file(path string, table &table.Table) ast.File { | ||||||
| 		table: table | 		table: table | ||||||
| 		file_name: path | 		file_name: path | ||||||
| 		pref: &pref.Preferences{} | 		pref: &pref.Preferences{} | ||||||
| 		builtin_mod: true |  | ||||||
| 	} | 	} | ||||||
| 	p.read_first_token() | 	p.read_first_token() | ||||||
| 	// module decl
 | 	// module decl
 | ||||||
| 	module_decl := if p.tok.kind == .key_module { p.module_decl() } else { ast.Module{name: 'main' | 	module_decl := if p.tok.kind == .key_module { p.module_decl() } else { ast.Module{name: 'main' | ||||||
| 	} } | 	} } | ||||||
|  | 	p.mod = module_decl.name | ||||||
|  | 	p.builtin_mod = p.mod == 'builtin' | ||||||
| 	// imports
 | 	// imports
 | ||||||
| 	mut imports := []ast.Import | 	mut imports := []ast.Import | ||||||
| 	for p.tok.kind == .key_import { | 	for p.tok.kind == .key_import { | ||||||
|  | @ -471,7 +472,7 @@ pub fn (p mut Parser) name_expr() (ast.Expr,table.TypeRef) { | ||||||
| 	if p.peek_tok.kind == .lpar { | 	if p.peek_tok.kind == .lpar { | ||||||
| 		name := p.tok.lit | 		name := p.tok.lit | ||||||
| 		// type cast. TODO: finish
 | 		// type cast. TODO: finish
 | ||||||
| 		if name in p.table.type_idxs { | 		if name in table.builtin_type_names { | ||||||
| 			// ['byte', 'string', 'int']
 | 			// ['byte', 'string', 'int']
 | ||||||
| 			// SKIP FOR NOW
 | 			// SKIP FOR NOW
 | ||||||
| 			mut par_d := 0 | 			mut par_d := 0 | ||||||
|  | @ -1054,26 +1055,30 @@ fn (p mut Parser) struct_decl() ast.StructDecl { | ||||||
| 		} | 		} | ||||||
| 		fields << table.Field{ | 		fields << table.Field{ | ||||||
| 			name: field_name | 			name: field_name | ||||||
| 			// type_idx: ti.idx
 |  | ||||||
| 			 |  | ||||||
| 			typ: typ | 			typ: typ | ||||||
| 		} | 		} | ||||||
| 		// println('struct field $ti.name $field_name')
 | 		// println('struct field $ti.name $field_name')
 | ||||||
| 	} | 	} | ||||||
| 	p.check(.rcbr) | 	p.check(.rcbr) | ||||||
| 	if name != 'string' { | 	t := table.Type{ | ||||||
| 		ret := p.table.register_type(table.Type{ | 		parent: 0 | ||||||
| 			parent: 0 | 		kind: .struct_ | ||||||
| 			kind: .struct_ | 		name: name | ||||||
| 			name: name | 		info: table.Struct{ | ||||||
| 			info: table.Struct{ | 			fields: fields | ||||||
| 				fields: fields |  | ||||||
| 			} |  | ||||||
| 		}) |  | ||||||
| 		if ret == -1 { |  | ||||||
| 			p.error('cannot register type `$name`, another type with this name exists') |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	mut ret := 0 | ||||||
|  | 	if p.builtin_mod && t.name in table.builtin_type_names { | ||||||
|  | 		// this allows overiding the builtins type
 | ||||||
|  | 		// with the real struct type info parsed from builtin
 | ||||||
|  | 		ret = p.table.register_builtin_type(t) | ||||||
|  | 	} else { | ||||||
|  | 		ret = p.table.register_type(t) | ||||||
|  | 	} | ||||||
|  | 	if ret == -1 { | ||||||
|  | 		p.error('cannot register type `$name`, another type with this name exists') | ||||||
|  | 	} | ||||||
| 	return ast.StructDecl{ | 	return ast.StructDecl{ | ||||||
| 		name: name | 		name: name | ||||||
| 		is_pub: is_pub | 		is_pub: is_pub | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| // that can be found in the LICENSE file.
 | // that can be found in the LICENSE file.
 | ||||||
| module table | module table | ||||||
| 
 | 
 | ||||||
| pub type TypeInfo = Array | ArrayFixed | Map | Struct | MultiReturn | Variadic | pub type TypeInfo = Array | ArrayFixed | Map | Struct | MultiReturn | ||||||
| 
 | 
 | ||||||
| pub struct Type { | pub struct Type { | ||||||
| pub: | pub: | ||||||
|  | @ -47,6 +47,13 @@ pub const ( | ||||||
| 	// map_type_idx = 18
 | 	// map_type_idx = 18
 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | pub const ( | ||||||
|  | 	builtin_type_names = [ | ||||||
|  | 		'void', 'voidptr', 'charptr', 'byteptr', 'i8', 'i16', 'int', 'i64', 'u16', 'u32', 'u64', | ||||||
|  | 		'f32' ,'f64', 'string', 'char', 'byte' ,'bool', 'struct', 'array', 'array_fixed', 'map' | ||||||
|  | 	] | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| pub enum Kind { | pub enum Kind { | ||||||
| 	placeholder | 	placeholder | ||||||
| 	void | 	void | ||||||
|  | @ -66,14 +73,13 @@ pub enum Kind { | ||||||
| 	char | 	char | ||||||
| 	byte | 	byte | ||||||
| 	bool | 	bool | ||||||
| 	const_ | 	//const_
 | ||||||
| 	enum_ | 	//enum_
 | ||||||
| 	struct_ | 	struct_ | ||||||
| 	array | 	array | ||||||
| 	array_fixed | 	array_fixed | ||||||
| 	map | 	map | ||||||
| 	multi_return | 	multi_return | ||||||
| 	variadic |  | ||||||
| 	unresolved | 	unresolved | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -371,9 +377,6 @@ pub fn (k Kind) str() string { | ||||||
| 		.multi_return{ | 		.multi_return{ | ||||||
| 			'multi_return' | 			'multi_return' | ||||||
| 		} | 		} | ||||||
| 		.variadic{ |  | ||||||
| 			'variadic' |  | ||||||
| 		} |  | ||||||
| 		else { | 		else { | ||||||
| 			'unknown'} | 			'unknown'} | ||||||
| 	} | 	} | ||||||
|  | @ -407,6 +410,7 @@ pub mut: | ||||||
| pub struct Field { | pub struct Field { | ||||||
| pub: | pub: | ||||||
| 	name string | 	name string | ||||||
|  | mut: | ||||||
| 	typ  TypeRef | 	typ  TypeRef | ||||||
| 	// type_idx int
 | 	// type_idx int
 | ||||||
| } | } | ||||||
|  | @ -447,11 +451,6 @@ mut: | ||||||
| 	types []TypeRef | 	types []TypeRef | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct Variadic { |  | ||||||
| pub: |  | ||||||
| 	typ TypeRef |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| [inline] | [inline] | ||||||
| pub fn (t &Table) get_type(idx int) &Type { | pub fn (t &Table) get_type(idx int) &Type { | ||||||
| 	if idx == 0 { | 	if idx == 0 { | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ pub: | ||||||
| 	name        string | 	name        string | ||||||
| 	args        []Var | 	args        []Var | ||||||
| 	return_type TypeRef | 	return_type TypeRef | ||||||
|  | 	is_variadic bool | ||||||
| 	is_c        bool | 	is_c        bool | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -279,6 +280,19 @@ pub fn (t &Table) find_type(name string) ?Type { | ||||||
| 	return none | 	return none | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // this will override or register builtin type
 | ||||||
|  | // allows prexisitng types added in register_builtins
 | ||||||
|  | // to be overriden with their real type info
 | ||||||
|  | [inline] | ||||||
|  | pub fn (t mut Table) register_builtin_type(typ Type) int { | ||||||
|  | 	existing_idx := t.type_idxs[typ.name] | ||||||
|  | 	if existing_idx > 0 { | ||||||
|  | 		t.types[existing_idx] = typ | ||||||
|  | 		return existing_idx | ||||||
|  | 	} | ||||||
|  | 	return t.register_type(typ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| [inline] | [inline] | ||||||
| pub fn (t mut Table) register_type(typ Type) int { | pub fn (t mut Table) register_type(typ Type) int { | ||||||
| 	existing_idx := t.type_idxs[typ.name] | 	existing_idx := t.type_idxs[typ.name] | ||||||
|  | @ -399,25 +413,6 @@ pub fn (t mut Table) find_or_register_multi_return(mr_typs []TypeRef) int { | ||||||
| 	return t.register_type(mr_type) | 	return t.register_type(mr_type) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (t mut Table) find_or_register_variadic(variadic_typ TypeRef) int { |  | ||||||
| 	name := 'variadic_$variadic_typ.typ.name' |  | ||||||
| 	// existing
 |  | ||||||
| 	existing_idx := t.type_idxs[name] |  | ||||||
| 	if existing_idx > 0 { |  | ||||||
| 		return existing_idx |  | ||||||
| 	} |  | ||||||
| 	// register
 |  | ||||||
| 	variadic_type := Type{ |  | ||||||
| 		parent: 0 |  | ||||||
| 		kind: .variadic |  | ||||||
| 		name: name |  | ||||||
| 		info: Variadic{ |  | ||||||
| 			typ: variadic_typ |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return t.register_type(variadic_type) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub fn (t mut Table) add_placeholder_type(name string) int { | pub fn (t mut Table) add_placeholder_type(name string) int { | ||||||
| 	ph_type := Type{ | 	ph_type := Type{ | ||||||
| 		parent: 0 | 		parent: 0 | ||||||
|  | @ -433,6 +428,9 @@ pub fn (t &Table) check(got, expected &TypeRef) bool { | ||||||
| 	if expected.typ.kind == .voidptr { | 	if expected.typ.kind == .voidptr { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
|  | 	if expected.typ.kind in [.voidptr, .byteptr, .charptr] && got.typ.kind == .int { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
| 	if expected.typ.kind == .byteptr && got.typ.kind == .voidptr { | 	if expected.typ.kind == .byteptr && got.typ.kind == .voidptr { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue