cgen: fix gen_map_equality_fn() (#7636)
parent
dea3d0431d
commit
547df57316
|
@ -465,7 +465,7 @@ fn test_map_or() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_int_keys() {
|
fn test_int_keys() {
|
||||||
mut m := map[int]int
|
mut m := map[int]int{}
|
||||||
m[3] = 9
|
m[3] = 9
|
||||||
m[4] = 16
|
m[4] = 16
|
||||||
assert m.len == 2
|
assert m.len == 2
|
||||||
|
@ -474,7 +474,6 @@ fn test_int_keys() {
|
||||||
m[5] += 24
|
m[5] += 24
|
||||||
m[5]++
|
m[5]++
|
||||||
assert m[5] == 25
|
assert m[5] == 25
|
||||||
|
|
||||||
mc := m.clone()
|
mc := m.clone()
|
||||||
assert mc.len == 3
|
assert mc.len == 3
|
||||||
mut all := []int{}
|
mut all := []int{}
|
||||||
|
@ -483,11 +482,11 @@ fn test_int_keys() {
|
||||||
all << k
|
all << k
|
||||||
all << v
|
all << v
|
||||||
}
|
}
|
||||||
assert all == [3,9,4,16,5,25]
|
assert all == [3, 9, 4, 16, 5, 25]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_voidptr_keys() {
|
fn test_voidptr_keys() {
|
||||||
mut m := map[voidptr]string
|
mut m := map[voidptr]string{}
|
||||||
v := 5
|
v := 5
|
||||||
m[&v] = 'var'
|
m[&v] = 'var'
|
||||||
m[&m] = 'map'
|
m[&m] = 'map'
|
||||||
|
@ -495,3 +494,66 @@ fn test_voidptr_keys() {
|
||||||
assert m[&m] == 'map'
|
assert m[&m] == 'map'
|
||||||
assert m.len == 2
|
assert m.len == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_eq() {
|
||||||
|
a := {
|
||||||
|
'a': 1
|
||||||
|
'b': 2
|
||||||
|
}
|
||||||
|
assert a == {
|
||||||
|
'a': 1
|
||||||
|
'b': 2
|
||||||
|
}
|
||||||
|
b := {
|
||||||
|
'a': [[1]]
|
||||||
|
'b': [[2]]
|
||||||
|
}
|
||||||
|
assert b == {
|
||||||
|
'a': [[1]]
|
||||||
|
'b': [[2]]
|
||||||
|
}
|
||||||
|
c := {
|
||||||
|
'a': {
|
||||||
|
'11': 1
|
||||||
|
}
|
||||||
|
'b': {
|
||||||
|
'22': 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert c == {
|
||||||
|
'a': {
|
||||||
|
'11': 1
|
||||||
|
}
|
||||||
|
'b': {
|
||||||
|
'22': 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d := {
|
||||||
|
'a': MValue{
|
||||||
|
name: 'aa'
|
||||||
|
misc: {
|
||||||
|
'11': '1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'b': MValue{
|
||||||
|
name: 'bb'
|
||||||
|
misc: {
|
||||||
|
'22': '2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert d == {
|
||||||
|
'a': MValue{
|
||||||
|
name: 'aa'
|
||||||
|
misc: {
|
||||||
|
'11': '1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'b': MValue{
|
||||||
|
name: 'bb'
|
||||||
|
misc: {
|
||||||
|
'22': '2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -93,15 +93,12 @@ fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
|
||||||
fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
|
fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
|
||||||
left_sym := g.table.get_type_symbol(left)
|
left_sym := g.table.get_type_symbol(left)
|
||||||
ptr_typ := g.typ(left).trim('*')
|
ptr_typ := g.typ(left).trim('*')
|
||||||
value_sym := g.table.get_type_symbol(left_sym.map_info().value_type)
|
|
||||||
value_typ := g.typ(left_sym.map_info().value_type)
|
|
||||||
if value_sym.kind == .map {
|
|
||||||
// Recursively generate map element comparison function code if array element is map type
|
|
||||||
g.gen_map_equality_fn(left_sym.map_info().value_type)
|
|
||||||
}
|
|
||||||
if ptr_typ in g.map_fn_definitions {
|
if ptr_typ in g.map_fn_definitions {
|
||||||
return ptr_typ
|
return ptr_typ
|
||||||
}
|
}
|
||||||
|
value_typ := left_sym.map_info().value_type
|
||||||
|
value_sym := g.table.get_type_symbol(value_typ)
|
||||||
|
ptr_value_typ := g.typ(value_typ)
|
||||||
g.map_fn_definitions << ptr_typ
|
g.map_fn_definitions << ptr_typ
|
||||||
g.type_definitions.writeln('static bool ${ptr_typ}_map_eq($ptr_typ a, $ptr_typ b); // auto')
|
g.type_definitions.writeln('static bool ${ptr_typ}_map_eq($ptr_typ a, $ptr_typ b); // auto')
|
||||||
mut fn_builder := strings.new_builder(512)
|
mut fn_builder := strings.new_builder(512)
|
||||||
|
@ -110,9 +107,8 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
|
||||||
fn_builder.writeln('\t\treturn false;')
|
fn_builder.writeln('\t\treturn false;')
|
||||||
fn_builder.writeln('\t}')
|
fn_builder.writeln('\t}')
|
||||||
fn_builder.writeln('\tarray_string _keys = map_keys(&a);')
|
fn_builder.writeln('\tarray_string _keys = map_keys(&a);')
|
||||||
i := g.new_tmp_var()
|
fn_builder.writeln('\tfor (int i = 0; i < _keys.len; ++i) {')
|
||||||
fn_builder.writeln('\tfor (int $i = 0; $i < _keys.len; ++$i) {')
|
fn_builder.writeln('\t\tstring k = string_clone( ((string*)_keys.data)[i]);')
|
||||||
fn_builder.writeln('\t\tstring k = string_clone( ((string*)_keys.data)[$i]);')
|
|
||||||
if value_sym.kind == .function {
|
if value_sym.kind == .function {
|
||||||
func := value_sym.info as table.FnType
|
func := value_sym.info as table.FnType
|
||||||
ret_styp := g.typ(func.func.return_type)
|
ret_styp := g.typ(func.func.return_type)
|
||||||
|
@ -127,12 +123,30 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
|
||||||
}
|
}
|
||||||
fn_builder.writeln(') = (*(voidptr*)map_get_1(&a, &k, &(voidptr[]){ 0 }));')
|
fn_builder.writeln(') = (*(voidptr*)map_get_1(&a, &k, &(voidptr[]){ 0 }));')
|
||||||
} else {
|
} else {
|
||||||
fn_builder.writeln('\t\t$value_typ v = (*($value_typ*)map_get_1(&a, &k, &($value_typ[]){ 0 }));')
|
fn_builder.writeln('\t\t$ptr_value_typ v = (*($ptr_value_typ*)map_get_1(&a, &k, &($ptr_value_typ[]){ 0 }));')
|
||||||
}
|
}
|
||||||
match value_sym.kind {
|
match value_sym.kind {
|
||||||
.string { fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || string_ne((*(string*)map_get_1(&b, &k, &(string[]){_SLIT("")})), v)) {') }
|
.string {
|
||||||
.function { fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || (*(voidptr*)map_get_1(&b, &k, &(voidptr[]){ 0 })) != v) {') }
|
fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || string_ne((*(string*)map_get_1(&b, &k, &(string[]){_SLIT("")})), v)) {')
|
||||||
else { fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || (*($value_typ*)map_get_1(&b, &k, &($value_typ[]){ 0 })) != v) {') }
|
}
|
||||||
|
.struct_ {
|
||||||
|
eq_fn := g.gen_struct_equality_fn(value_typ)
|
||||||
|
fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || !${eq_fn}_struct_eq(*($ptr_value_typ*)map_get_1(&b, &k, &($ptr_value_typ[]){ 0 }), v)) {')
|
||||||
|
}
|
||||||
|
.array {
|
||||||
|
eq_fn := g.gen_array_equality_fn(value_typ)
|
||||||
|
fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || !${eq_fn}_arr_eq(*($ptr_value_typ*)map_get_1(&b, &k, &($ptr_value_typ[]){ 0 }), v)) {')
|
||||||
|
}
|
||||||
|
.map {
|
||||||
|
eq_fn := g.gen_map_equality_fn(value_typ)
|
||||||
|
fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || !${eq_fn}_map_eq(*($ptr_value_typ*)map_get_1(&b, &k, &($ptr_value_typ[]){ 0 }), v)) {')
|
||||||
|
}
|
||||||
|
.function {
|
||||||
|
fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || (*(voidptr*)map_get_1(&b, &k, &(voidptr[]){ 0 })) != v) {')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fn_builder.writeln('\t\tif (!map_exists_1(&b, &k) || (*($ptr_value_typ*)map_get_1(&b, &k, &($ptr_value_typ[]){ 0 })) != v) {')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn_builder.writeln('\t\t\treturn false;')
|
fn_builder.writeln('\t\t\treturn false;')
|
||||||
fn_builder.writeln('\t\t}')
|
fn_builder.writeln('\t\t}')
|
||||||
|
|
Loading…
Reference in New Issue