checker/cgen: interface match
							parent
							
								
									c4241f90e6
								
							
						
					
					
						commit
						f87e872fa2
					
				|  | @ -439,6 +439,7 @@ pub mut: | |||
| 	cond_type     table.Type // type of `x` in `match x {`
 | ||||
| 	expected_type table.Type // for debugging only
 | ||||
| 	is_sum_type   bool | ||||
| 	is_interface  bool | ||||
| } | ||||
| 
 | ||||
| pub struct MatchBranch { | ||||
|  | @ -657,7 +658,7 @@ pub: | |||
| pub struct ArrayInit { | ||||
| pub: | ||||
| 	pos             token.Position | ||||
| 	elem_type_pos	token.Position | ||||
| 	elem_type_pos   token.Position | ||||
| 	exprs           []Expr | ||||
| 	is_fixed        bool | ||||
| 	has_val         bool | ||||
|  |  | |||
|  | @ -1039,7 +1039,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { | |||
| 	return f.return_type | ||||
| } | ||||
| 
 | ||||
| fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position) { | ||||
| fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position) bool { | ||||
| 	typ_sym := c.table.get_type_symbol(typ) | ||||
| 	inter_sym := c.table.get_type_symbol(inter_typ) | ||||
| 	styp := c.table.type_to_str(typ) | ||||
|  | @ -1048,6 +1048,7 @@ fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position | |||
| 			if !imethod.is_same_method_as(method) { | ||||
| 				c.error('`$styp` incorrectly implements method `$imethod.name` of interface `$inter_sym.name`, expected `${c.table.fn_to_str(imethod)}`', | ||||
| 					pos) | ||||
| 				return false | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | @ -1057,6 +1058,7 @@ fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position | |||
| 	if typ !in inter_info.types && typ_sym.kind != .interface_ { | ||||
| 		inter_info.types << typ | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // return the actual type of the expression, once the optional is handled
 | ||||
|  | @ -2037,11 +2039,11 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { | |||
| 	if cond_type == 0 { | ||||
| 		c.error('match 0 cond type', node.pos) | ||||
| 	} | ||||
| 	type_sym := c.table.get_type_symbol(cond_type) | ||||
| 	if type_sym.kind != .sum_type { | ||||
| 	cond_type_sym := c.table.get_type_symbol(cond_type) | ||||
| 	if cond_type_sym.kind !in [.sum_type, .interface_] { | ||||
| 		node.is_sum_type = false | ||||
| 	} | ||||
| 	c.match_exprs(mut node, type_sym) | ||||
| 	c.match_exprs(mut node, cond_type_sym) | ||||
| 	c.expected_type = cond_type | ||||
| 	mut ret_type := table.void_type | ||||
| 	for branch in node.branches { | ||||
|  | @ -2049,12 +2051,17 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) table.Type { | |||
| 			c.expected_type = cond_type | ||||
| 			typ := c.expr(expr) | ||||
| 			typ_sym := c.table.get_type_symbol(typ) | ||||
| 			if !node.is_sum_type && !c.check_types(typ, cond_type) { | ||||
| 				exp_sym := c.table.get_type_symbol(cond_type) | ||||
| 				c.error('cannot use `$typ_sym.name` as `$exp_sym.name` in `match`', node.pos) | ||||
| 			} | ||||
| 			// TODO:
 | ||||
| 			if typ_sym.kind == .sum_type { | ||||
| 			if node.is_sum_type || node.is_interface { | ||||
| 				ok := if cond_type_sym.kind == .sum_type { | ||||
| 					// TODO verify sum type
 | ||||
| 					true // c.check_types(typ, cond_type)
 | ||||
| 				} else { | ||||
| 					c.type_implements(typ, cond_type, node.pos) | ||||
| 				} | ||||
| 				if !ok { | ||||
| 					c.error('cannot use `$typ_sym.name` as `$cond_type_sym.name` in `match`', | ||||
| 						node.pos) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		c.stmts(branch.stmts) | ||||
|  |  | |||
|  | @ -1888,9 +1888,14 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) { | |||
| 			for i, expr in branch.exprs { | ||||
| 				if node.is_sum_type { | ||||
| 					g.expr(node.cond) | ||||
| 					g.write('.typ == ') | ||||
| 					// g.write('${tmp}.typ == ')
 | ||||
| 					// sum_type_str
 | ||||
| 					sym := g.table.get_type_symbol(node.cond_type) | ||||
| 					// branch_sym := g.table.get_type_symbol(branch.typ)
 | ||||
| 					if sym.kind == .sum_type { | ||||
| 						g.write('.typ == ') | ||||
| 					} else if sym.kind == .interface_ { | ||||
| 						// g.write('._interface_idx == _${sym.name}_${branch_sym} ')
 | ||||
| 						g.write('._interface_idx == ') | ||||
| 					} | ||||
| 				} else if type_sym.kind == .string { | ||||
| 					g.write('string_eq(') | ||||
| 					//
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ import v.util | |||
| import v.errors | ||||
| import os | ||||
| import runtime | ||||
| import sync | ||||
| //import sync
 | ||||
| import time | ||||
| 
 | ||||
| pub struct Parser { | ||||
|  | @ -140,6 +140,7 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| struct Queue { | ||||
| mut: | ||||
| 	idx              int | ||||
|  | @ -171,10 +172,12 @@ fn (mut q Queue) run() { | |||
| 		println('run done(idx=$idx)') | ||||
| 	} | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, global_scope &ast.Scope) []ast.File { | ||||
| 	// println('nr_cpus= $nr_cpus')
 | ||||
| 	$if macos { | ||||
| 		/* | ||||
| 		if pref.is_parallel && paths[0].contains('/array.v') { | ||||
| 			println('\n\n\nparse_files() nr_files=$paths.len') | ||||
| 			println(paths) | ||||
|  | @ -194,6 +197,7 @@ pub fn parse_files(paths []string, table &table.Table, pref &pref.Preferences, g | |||
| 			println('all done') | ||||
| 			return q.parsed_ast_files | ||||
| 		} | ||||
| 		*/ | ||||
| 	} | ||||
| 	if false { | ||||
| 		// TODO: remove this; it just prevents warnings about unused time and runtime
 | ||||
|  |  | |||
|  | @ -247,3 +247,13 @@ fn new_animal() Animal { | |||
| fn new_animal2() Animal { | ||||
| 	return new_animal() | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| fn animal_match(a Animal) { | ||||
| 	match a { | ||||
| 		Dog { println('(dog)') } | ||||
| 		Cat { println('(cat)') } | ||||
| 		else {} | ||||
| 	} | ||||
| } | ||||
| */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue