parent
							
								
									e47c13903b
								
							
						
					
					
						commit
						ddcbc4440b
					
				|  | @ -253,17 +253,18 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { | |||
| 		// `users.sort(a.age > b.age)`
 | ||||
| 		// Generate a comparison function for a custom type
 | ||||
| 		tmp_name := g.new_tmp_var() | ||||
| 		compare_fn = 'compare_${tmp_name}_' + g.typ(typ) | ||||
| 		styp := g.typ(typ).trim('*') | ||||
| 		compare_fn = 'compare_${tmp_name}_$styp' | ||||
| 		if is_reverse { | ||||
| 			compare_fn += '_reverse' | ||||
| 		} | ||||
| 		// Register a new custom `compare_xxx` function for qsort()
 | ||||
| 		g.table.register_fn(name: compare_fn, return_type: table.int_type) | ||||
| 		infix_expr := node.args[0].expr as ast.InfixExpr | ||||
| 		styp := g.typ(typ) | ||||
| 		// Variables `a` and `b` are used in the `.sort(a < b)` syntax, so we can reuse them
 | ||||
| 		// when generating the function as long as the args are named the same.
 | ||||
| 		g.definitions.writeln('int $compare_fn ($styp* a, $styp* b) {') | ||||
| 		styp_arg := g.typ(typ) | ||||
| 		g.definitions.writeln('int $compare_fn ($styp_arg* a, $styp_arg* b) {') | ||||
| 		sym := g.table.get_type_symbol(typ) | ||||
| 		if !is_reverse && sym.has_method('<') && infix_expr.left.str().len == 1 { | ||||
| 			g.definitions.writeln('\tif (${styp}__lt(*a, *b)) { return -1; } else { return 1; }}') | ||||
|  | @ -271,8 +272,12 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) { | |||
| 			g.definitions.writeln('\tif (${styp}__gt(*a, *b)) { return -1; } else { return 1; }}') | ||||
| 		} else { | ||||
| 			field_type := g.typ(infix_expr.left_type) | ||||
| 			left_expr_str := g.write_expr_to_string(infix_expr.left) | ||||
| 			right_expr_str := g.write_expr_to_string(infix_expr.right) | ||||
| 			mut left_expr_str := g.write_expr_to_string(infix_expr.left) | ||||
| 			mut right_expr_str := g.write_expr_to_string(infix_expr.right) | ||||
| 			if typ.is_ptr() { | ||||
| 				left_expr_str = left_expr_str.replace_once('a', '(*a)') | ||||
| 				right_expr_str = right_expr_str.replace_once('b', '(*b)') | ||||
| 			} | ||||
| 			g.definitions.writeln('$field_type a_ = $left_expr_str;') | ||||
| 			g.definitions.writeln('$field_type b_ = $right_expr_str;') | ||||
| 			mut op1, mut op2 := '', '' | ||||
|  |  | |||
|  | @ -0,0 +1,22 @@ | |||
| struct Container { | ||||
| mut: | ||||
| 	name string | ||||
| } | ||||
| 
 | ||||
| fn test_array_sort_by_references() { | ||||
| 	mut a := []&Container{} | ||||
| 
 | ||||
| 	a << &Container{ name: 'a' } | ||||
| 	a << &Container{ name: 'b' } | ||||
| 	a << &Container{ name: 'c' } | ||||
| 	a << &Container{ name: 'd' } | ||||
| 	a << &Container{ name: 'e' } | ||||
| 
 | ||||
| 	a.sort(a.name > b.name) | ||||
| 	println(a) | ||||
| 	assert a[0].name == 'e' | ||||
| 	assert a[1].name == 'd' | ||||
| 	assert a[2].name == 'c' | ||||
| 	assert a[3].name == 'b' | ||||
| 	assert a[4].name == 'a' | ||||
| } | ||||
		Loading…
	
		Reference in New Issue