cgen: fix several sort declarations (#10919)

pull/10872/head
Daniel Däschle 2021-07-23 07:55:55 +02:00 committed by GitHub
parent a2de3ffcdb
commit 091ce6cc08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 1 deletions

View File

@ -65,3 +65,20 @@ fn test_sorting_u64s() {
eprintln(' a: $a') eprintln(' a: $a')
assert a == [u64(9), 8, 3, 2, 1, 0] assert a == [u64(9), 8, 3, 2, 1, 0]
} }
struct User {
age int
name string
}
fn g(mut users []User) {
users.sort(a.name > b.name)
}
fn f(mut users []User) {
users.sort(a.name < b.name)
}
fn z(mut users []User) {
users.sort(a.name < b.name)
}

View File

@ -244,13 +244,14 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
if compare_fn == '' { if compare_fn == '' {
// `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_global_tmp_var()
styp := g.typ(typ).trim('*') styp := g.typ(typ).trim('*')
compare_fn = 'compare_${tmp_name}_$styp' 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()
// TODO: move to checker
g.table.register_fn(name: compare_fn, return_type: ast.int_type) g.table.register_fn(name: compare_fn, return_type: ast.int_type)
if node.args.len == 0 { if node.args.len == 0 {

View File

@ -71,6 +71,7 @@ mut:
tmp_count int // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn. tmp_count int // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn.
tmp_count2 int // a separate tmp var counter for autofree fn calls tmp_count2 int // a separate tmp var counter for autofree fn calls
tmp_count_declarations int // counter for unique tmp names (_d1, _d2 etc); does NOT reset, used for C declarations tmp_count_declarations int // counter for unique tmp names (_d1, _d2 etc); does NOT reset, used for C declarations
global_tmp_count int // like tmp_count but global and not resetted in each function
is_assign_lhs bool // inside left part of assign expr (for array_set(), etc) is_assign_lhs bool // inside left part of assign expr (for array_set(), etc)
discard_or_result bool // do not safe last ExprStmt of `or` block in tmp variable to defer ongoing expr usage discard_or_result bool // do not safe last ExprStmt of `or` block in tmp variable to defer ongoing expr usage
is_void_expr_stmt bool // ExprStmt whos result is discarded is_void_expr_stmt bool // ExprStmt whos result is discarded
@ -1004,6 +1005,11 @@ pub fn (mut g Gen) new_tmp_var() string {
return '_t$g.tmp_count' return '_t$g.tmp_count'
} }
pub fn (mut g Gen) new_global_tmp_var() string {
g.global_tmp_count++
return '_t$g.global_tmp_count'
}
pub fn (mut g Gen) new_tmp_declaration_name() string { pub fn (mut g Gen) new_tmp_declaration_name() string {
g.tmp_count_declarations++ g.tmp_count_declarations++
return '_d$g.tmp_count_declarations' return '_d$g.tmp_count_declarations'