cgen: add gen_alias_equlity_fn (#8514)
parent
c818ad97eb
commit
7875164d91
|
@ -32,6 +32,9 @@ fn (mut g Gen) gen_struct_equality_fn(left table.Type) string {
|
||||||
} else if sym.kind == .map && !field.typ.is_ptr() {
|
} else if sym.kind == .map && !field.typ.is_ptr() {
|
||||||
eq_fn := g.gen_map_equality_fn(field.typ)
|
eq_fn := g.gen_map_equality_fn(field.typ)
|
||||||
fn_builder.writeln('\tif (!${eq_fn}_map_eq(a.$field.name, b.$field.name)) {')
|
fn_builder.writeln('\tif (!${eq_fn}_map_eq(a.$field.name, b.$field.name)) {')
|
||||||
|
} else if sym.kind == .alias && !field.typ.is_ptr() {
|
||||||
|
eq_fn := g.gen_alias_equality_fn(field.typ)
|
||||||
|
fn_builder.writeln('\tif (!${eq_fn}_alias_eq(a.$field.name, b.$field.name)) {')
|
||||||
} else if sym.kind == .function {
|
} else if sym.kind == .function {
|
||||||
fn_builder.writeln('\tif (*((voidptr*)(a.$field.name)) != *((voidptr*)(b.$field.name))) {')
|
fn_builder.writeln('\tif (*((voidptr*)(a.$field.name)) != *((voidptr*)(b.$field.name))) {')
|
||||||
} else {
|
} else {
|
||||||
|
@ -46,6 +49,45 @@ fn (mut g Gen) gen_struct_equality_fn(left table.Type) string {
|
||||||
return ptr_typ
|
return ptr_typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) gen_alias_equality_fn(left table.Type) string {
|
||||||
|
ptr_typ := g.typ(left).trim('*')
|
||||||
|
if ptr_typ in g.alias_fn_definitions {
|
||||||
|
return ptr_typ
|
||||||
|
}
|
||||||
|
g.alias_fn_definitions << ptr_typ
|
||||||
|
left_sym := g.table.get_type_symbol(left)
|
||||||
|
info := left_sym.info as table.Alias
|
||||||
|
g.type_definitions.writeln('static bool ${ptr_typ}_alias_eq($ptr_typ a, $ptr_typ b); // auto')
|
||||||
|
mut fn_builder := strings.new_builder(512)
|
||||||
|
fn_builder.writeln('static bool ${ptr_typ}_alias_eq($ptr_typ a, $ptr_typ b) {')
|
||||||
|
sym := g.table.get_type_symbol(info.parent_type)
|
||||||
|
if sym.kind == .string {
|
||||||
|
fn_builder.writeln('\tif (string_ne(a, b)) {')
|
||||||
|
} else if sym.kind == .struct_ && !left.is_ptr() {
|
||||||
|
eq_fn := g.gen_struct_equality_fn(info.parent_type)
|
||||||
|
fn_builder.writeln('\tif (!${eq_fn}_struct_eq(a, b)) {')
|
||||||
|
} else if sym.kind == .array && !left.is_ptr() {
|
||||||
|
eq_fn := g.gen_array_equality_fn(info.parent_type)
|
||||||
|
fn_builder.writeln('\tif (!${eq_fn}_arr_eq(a, b)) {')
|
||||||
|
} else if sym.kind == .array_fixed && !left.is_ptr() {
|
||||||
|
eq_fn := g.gen_fixed_array_equality_fn(info.parent_type)
|
||||||
|
fn_builder.writeln('\tif (!${eq_fn}_arr_eq(a, b)) {')
|
||||||
|
} else if sym.kind == .map && !left.is_ptr() {
|
||||||
|
eq_fn := g.gen_map_equality_fn(info.parent_type)
|
||||||
|
fn_builder.writeln('\tif (!${eq_fn}_map_eq(a, b)) {')
|
||||||
|
} else if sym.kind == .function {
|
||||||
|
fn_builder.writeln('\tif (*((voidptr*)(a)) != *((voidptr*)(b))) {')
|
||||||
|
} else {
|
||||||
|
fn_builder.writeln('\tif (a != b) {')
|
||||||
|
}
|
||||||
|
fn_builder.writeln('\t\treturn false;')
|
||||||
|
fn_builder.writeln('\t}')
|
||||||
|
fn_builder.writeln('\treturn true;')
|
||||||
|
fn_builder.writeln('}')
|
||||||
|
g.auto_fn_definitions << fn_builder.str()
|
||||||
|
return ptr_typ
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
|
fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
|
||||||
ptr_typ := g.typ(left).trim('*')
|
ptr_typ := g.typ(left).trim('*')
|
||||||
if ptr_typ in g.array_fn_definitions {
|
if ptr_typ in g.array_fn_definitions {
|
||||||
|
@ -78,6 +120,9 @@ fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
|
||||||
} else if elem_sym.kind == .map && !elem_typ.is_ptr() {
|
} else if elem_sym.kind == .map && !elem_typ.is_ptr() {
|
||||||
eq_fn := g.gen_map_equality_fn(elem_typ)
|
eq_fn := g.gen_map_equality_fn(elem_typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq((($ptr_elem_typ*)a.data)[i], (($ptr_elem_typ*)b.data)[i])) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq((($ptr_elem_typ*)a.data)[i], (($ptr_elem_typ*)b.data)[i])) {')
|
||||||
|
} else if elem_sym.kind == .alias && !elem_typ.is_ptr() {
|
||||||
|
eq_fn := g.gen_alias_equality_fn(elem_typ)
|
||||||
|
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq((($ptr_elem_typ*)a.data)[i], (($ptr_elem_typ*)b.data)[i])) {')
|
||||||
} else if elem_sym.kind == .function {
|
} else if elem_sym.kind == .function {
|
||||||
fn_builder.writeln('\t\tif (*((voidptr*)((byte*)a.data+(i*a.element_size))) != *((voidptr*)((byte*)b.data+(i*b.element_size)))) {')
|
fn_builder.writeln('\t\tif (*((voidptr*)((byte*)a.data+(i*a.element_size))) != *((voidptr*)((byte*)b.data+(i*b.element_size)))) {')
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,6 +167,9 @@ fn (mut g Gen) gen_fixed_array_equality_fn(left table.Type) string {
|
||||||
} else if elem_sym.kind == .map && !elem_typ.is_ptr() {
|
} else if elem_sym.kind == .map && !elem_typ.is_ptr() {
|
||||||
eq_fn := g.gen_map_equality_fn(elem_typ)
|
eq_fn := g.gen_map_equality_fn(elem_typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(a[i], b[i])) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(a[i], b[i])) {')
|
||||||
|
} else if elem_sym.kind == .alias && !elem_typ.is_ptr() {
|
||||||
|
eq_fn := g.gen_alias_equality_fn(elem_typ)
|
||||||
|
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(a[i], b[i])) {')
|
||||||
} else if elem_sym.kind == .function {
|
} else if elem_sym.kind == .function {
|
||||||
fn_builder.writeln('\t\tif (a[i] != b[i]) {')
|
fn_builder.writeln('\t\tif (a[i] != b[i]) {')
|
||||||
} else {
|
} else {
|
||||||
|
@ -193,6 +241,10 @@ fn (mut g Gen) gen_map_equality_fn(left table.Type) string {
|
||||||
eq_fn := g.gen_map_equality_fn(value_typ)
|
eq_fn := g.gen_map_equality_fn(value_typ)
|
||||||
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(*($ptr_value_typ*)map_get_1(&b, k, &($ptr_value_typ[]){ 0 }), v)) {')
|
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(*($ptr_value_typ*)map_get_1(&b, k, &($ptr_value_typ[]){ 0 }), v)) {')
|
||||||
}
|
}
|
||||||
|
.alias {
|
||||||
|
eq_fn := g.gen_alias_equality_fn(value_typ)
|
||||||
|
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(*($ptr_value_typ*)map_get_1(&b, k, &($ptr_value_typ[]){ 0 }), v)) {')
|
||||||
|
}
|
||||||
.function {
|
.function {
|
||||||
fn_builder.writeln('\t\tif (*(voidptr*)map_get_1(&b, k, &(voidptr[]){ 0 }) != v) {')
|
fn_builder.writeln('\t\tif (*(voidptr*)map_get_1(&b, k, &(voidptr[]){ 0 }) != v) {')
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ mut:
|
||||||
array_fn_definitions []string // array equality functions that have been defined
|
array_fn_definitions []string // array equality functions that have been defined
|
||||||
map_fn_definitions []string // map equality functions that have been defined
|
map_fn_definitions []string // map equality functions that have been defined
|
||||||
struct_fn_definitions []string // struct equality functions that have been defined
|
struct_fn_definitions []string // struct equality functions that have been defined
|
||||||
|
alias_fn_definitions []string // alias equality functions that have been defined
|
||||||
auto_fn_definitions []string // auto generated functions defination list
|
auto_fn_definitions []string // auto generated functions defination list
|
||||||
anon_fn_definitions []string // anon generated functions defination list
|
anon_fn_definitions []string // anon generated functions defination list
|
||||||
is_json_fn bool // inside json.encode()
|
is_json_fn bool // inside json.encode()
|
||||||
|
@ -3138,6 +3139,23 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
}
|
}
|
||||||
g.expr(node.right)
|
g.expr(node.right)
|
||||||
g.write(')')
|
g.write(')')
|
||||||
|
} else if node.op in [.eq, .ne] && left_sym.kind == .alias && right_sym.kind == .alias {
|
||||||
|
ptr_typ := g.gen_alias_equality_fn(left_type)
|
||||||
|
if node.op == .eq {
|
||||||
|
g.write('${ptr_typ}_alias_eq(')
|
||||||
|
} else if node.op == .ne {
|
||||||
|
g.write('!${ptr_typ}_alias_eq(')
|
||||||
|
}
|
||||||
|
if node.left_type.is_ptr() {
|
||||||
|
g.write('*')
|
||||||
|
}
|
||||||
|
g.expr(node.left)
|
||||||
|
g.write(', ')
|
||||||
|
if node.right_type.is_ptr() {
|
||||||
|
g.write('*')
|
||||||
|
}
|
||||||
|
g.expr(node.right)
|
||||||
|
g.write(')')
|
||||||
} else if node.op in [.eq, .ne] && left_sym.kind == .map && right_sym.kind == .map {
|
} else if node.op in [.eq, .ne] && left_sym.kind == .map && right_sym.kind == .map {
|
||||||
ptr_typ := g.gen_map_equality_fn(left_type)
|
ptr_typ := g.gen_map_equality_fn(left_type)
|
||||||
if node.op == .eq {
|
if node.op == .eq {
|
||||||
|
|
|
@ -74,3 +74,17 @@ fn test_nested_array_equality() {
|
||||||
assert a9 == [[[u16(22), 11]]]
|
assert a9 == [[[u16(22), 11]]]
|
||||||
assert a9 != [[[u16(20), 10]]]
|
assert a9 != [[[u16(20), 10]]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Literal = string
|
||||||
|
type Literals = []Literal
|
||||||
|
|
||||||
|
fn (l1 Literal) concat(l2 Literal) Literals {
|
||||||
|
return Literals([l1, l2])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_array_of_alias_equality() {
|
||||||
|
mut literals := Literals([]Literal{})
|
||||||
|
literals = Literal('hello').concat(Literal('World'))
|
||||||
|
println(literals)
|
||||||
|
assert literals == Literals([Literal('hello'), Literal('World')])
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue