parent
e47c13903b
commit
ddcbc4440b
|
@ -253,17 +253,18 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
|
||||||
// `users.sort(a.age > b.age)`
|
// `users.sort(a.age > b.age)`
|
||||||
// Generate a comparison function for a custom type
|
// Generate a comparison function for a custom type
|
||||||
tmp_name := g.new_tmp_var()
|
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 {
|
if is_reverse {
|
||||||
compare_fn += '_reverse'
|
compare_fn += '_reverse'
|
||||||
}
|
}
|
||||||
// Register a new custom `compare_xxx` function for qsort()
|
// Register a new custom `compare_xxx` function for qsort()
|
||||||
g.table.register_fn(name: compare_fn, return_type: table.int_type)
|
g.table.register_fn(name: compare_fn, return_type: table.int_type)
|
||||||
infix_expr := node.args[0].expr as ast.InfixExpr
|
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
|
// 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.
|
// 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)
|
sym := g.table.get_type_symbol(typ)
|
||||||
if !is_reverse && sym.has_method('<') && infix_expr.left.str().len == 1 {
|
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; }}')
|
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; }}')
|
g.definitions.writeln('\tif (${styp}__gt(*a, *b)) { return -1; } else { return 1; }}')
|
||||||
} else {
|
} else {
|
||||||
field_type := g.typ(infix_expr.left_type)
|
field_type := g.typ(infix_expr.left_type)
|
||||||
left_expr_str := g.write_expr_to_string(infix_expr.left)
|
mut left_expr_str := g.write_expr_to_string(infix_expr.left)
|
||||||
right_expr_str := g.write_expr_to_string(infix_expr.right)
|
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 a_ = $left_expr_str;')
|
||||||
g.definitions.writeln('$field_type b_ = $right_expr_str;')
|
g.definitions.writeln('$field_type b_ = $right_expr_str;')
|
||||||
mut op1, mut op2 := '', ''
|
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