cgen: allow sort with`<` and `>` op overloading (#8042)
parent
5a1699dec2
commit
82a5300044
|
@ -10,6 +10,7 @@
|
||||||
- Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]`
|
- Array decompose: `[1, 2, 3]...` is now `...[1, 2, 3]`
|
||||||
- Treating `enum` as `int` and operations on `enum` except `==` and `!=` are removed for strict type checking.
|
- Treating `enum` as `int` and operations on `enum` except `==` and `!=` are removed for strict type checking.
|
||||||
- Support `[manualfree] fn f1(){}` and `[manualfree] module m1`, for functions doing their own memory management.
|
- Support `[manualfree] fn f1(){}` and `[manualfree] module m1`, for functions doing their own memory management.
|
||||||
|
- Allow usage of `<` and `>` operators for struct in `.sort` method for arrays, i.e. `arr.sort(a < b)`.
|
||||||
|
|
||||||
## V 0.2.1
|
## V 0.2.1
|
||||||
*30 Dec 2020*
|
*30 Dec 2020*
|
||||||
|
|
|
@ -252,33 +252,40 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
|
||||||
// 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) {')
|
g.definitions.writeln('int $compare_fn ($styp* a, $styp* b) {')
|
||||||
field_type := g.typ(infix_expr.left_type)
|
sym := g.table.get_type_symbol(typ)
|
||||||
left_expr_str := g.write_expr_to_string(infix_expr.left).replace_once('.',
|
if sym.has_method('<') && infix_expr.left.str().len == 1 {
|
||||||
'->')
|
g.definitions.writeln('\tif (${styp}__lt(*a, *b)) { return -1; } else { return 1; }}')
|
||||||
right_expr_str := g.write_expr_to_string(infix_expr.right).replace_once('.',
|
} else if sym.has_method('>') && infix_expr.left.str().len == 1 {
|
||||||
'->')
|
g.definitions.writeln('\tif (${styp}__gt(*a, *b)) { return -1; } else { return 1; }}')
|
||||||
g.definitions.writeln('$field_type a_ = $left_expr_str;')
|
|
||||||
g.definitions.writeln('$field_type b_ = $right_expr_str;')
|
|
||||||
mut op1, mut op2 := '', ''
|
|
||||||
if infix_expr.left_type == table.string_type {
|
|
||||||
if is_reverse {
|
|
||||||
op1 = 'string_gt(a_, b_)'
|
|
||||||
op2 = 'string_lt(a_, b_)'
|
|
||||||
} else {
|
|
||||||
op1 = 'string_lt(a_, b_)'
|
|
||||||
op2 = 'string_gt(a_, b_)'
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if is_reverse {
|
field_type := g.typ(infix_expr.left_type)
|
||||||
op1 = 'a_ > b_'
|
left_expr_str := g.write_expr_to_string(infix_expr.left).replace_once('.',
|
||||||
op2 = 'a_ < b_'
|
'->')
|
||||||
|
right_expr_str := g.write_expr_to_string(infix_expr.right).replace_once('.',
|
||||||
|
'->')
|
||||||
|
g.definitions.writeln('$field_type a_ = $left_expr_str;')
|
||||||
|
g.definitions.writeln('$field_type b_ = $right_expr_str;')
|
||||||
|
mut op1, mut op2 := '', ''
|
||||||
|
if infix_expr.left_type == table.string_type {
|
||||||
|
if is_reverse {
|
||||||
|
op1 = 'string_gt(a_, b_)'
|
||||||
|
op2 = 'string_lt(a_, b_)'
|
||||||
|
} else {
|
||||||
|
op1 = 'string_lt(a_, b_)'
|
||||||
|
op2 = 'string_gt(a_, b_)'
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
op1 = 'a_ < b_'
|
if is_reverse {
|
||||||
op2 = 'a_ > b_'
|
op1 = 'a_ > b_'
|
||||||
|
op2 = 'a_ < b_'
|
||||||
|
} else {
|
||||||
|
op1 = 'a_ < b_'
|
||||||
|
op2 = 'a_ > b_'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
g.definitions.writeln('if ($op1) return -1;')
|
||||||
|
g.definitions.writeln('if ($op2) return 1; return 0; }\n')
|
||||||
}
|
}
|
||||||
g.definitions.writeln('if ($op1) return -1;')
|
|
||||||
g.definitions.writeln('if ($op2) return 1; return 0; }\n')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if is_reverse && !compare_fn.ends_with('_reverse') {
|
if is_reverse && !compare_fn.ends_with('_reverse') {
|
||||||
|
|
|
@ -7,6 +7,10 @@ struct Parent {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (p Parent) < (p1 Parent) bool {
|
||||||
|
return p.name < p1.name
|
||||||
|
}
|
||||||
|
|
||||||
fn test_sorting_by_different_criteria_in_same_function() {
|
fn test_sorting_by_different_criteria_in_same_function() {
|
||||||
mut arr := [
|
mut arr := [
|
||||||
Parent{Child{0.2}, 'def'},
|
Parent{Child{0.2}, 'def'},
|
||||||
|
@ -20,4 +24,6 @@ fn test_sorting_by_different_criteria_in_same_function() {
|
||||||
// println(arr)
|
// println(arr)
|
||||||
arr.sort(a.child.f < b.child.f)
|
arr.sort(a.child.f < b.child.f)
|
||||||
assert arr[0].name == 'xyz'
|
assert arr[0].name == 'xyz'
|
||||||
|
arr.sort(a < b)
|
||||||
|
assert arr[0].name == 'abc'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue