cgen: fix nested array equality error
parent
d478b44915
commit
23993d2264
|
@ -1066,7 +1066,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
// `a := 1` | `a,b := 1,2`
|
// `a := 1` | `a,b := 1,2`
|
||||||
for i, left in assign_stmt.left {
|
for i, left in assign_stmt.left {
|
||||||
mut var_type := assign_stmt.left_types[i]
|
mut var_type := assign_stmt.left_types[i]
|
||||||
val_type := assign_stmt.right_types[i]
|
val_type := assign_stmt.right_types[i]
|
||||||
val := assign_stmt.right[i]
|
val := assign_stmt.right[i]
|
||||||
mut is_call := false
|
mut is_call := false
|
||||||
|
@ -1759,12 +1759,7 @@ 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 == .array && right_sym.kind == .array {
|
} else if node.op in [.eq, .ne] && left_sym.kind == .array && right_sym.kind == .array {
|
||||||
styp := g.table.value_type(left_type)
|
ptr_typ := g.gen_array_equality_fn(left_type)
|
||||||
ptr_typ := g.typ(left_type).split('_')[1]
|
|
||||||
if ptr_typ !in g.array_fn_definitions {
|
|
||||||
sym := g.table.get_type_symbol(left_sym.array_info().elem_type)
|
|
||||||
g.generate_array_equality_fn(ptr_typ, styp, sym)
|
|
||||||
}
|
|
||||||
if node.op == .eq {
|
if node.op == .eq {
|
||||||
g.write('${ptr_typ}_arr_eq(')
|
g.write('${ptr_typ}_arr_eq(')
|
||||||
} else if node.op == .ne {
|
} else if node.op == .ne {
|
||||||
|
@ -2618,7 +2613,20 @@ fn (mut g Gen) assoc(node ast.Assoc) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) generate_array_equality_fn(ptr_typ string, styp table.Type, sym &table.TypeSymbol) {
|
fn (mut g Gen) gen_array_equality_fn(left table.Type) string {
|
||||||
|
styp := g.table.value_type(left)
|
||||||
|
left_sym := g.table.get_type_symbol(left)
|
||||||
|
typ_name := g.typ(left)
|
||||||
|
ptr_typ := typ_name[typ_name.index_after('_', 0)+1..]
|
||||||
|
elem_sym := g.table.get_type_symbol(left_sym.array_info().elem_type)
|
||||||
|
mut elem_typ := ''
|
||||||
|
if elem_sym.kind == .array {
|
||||||
|
// Recursively generate array element comparison function code and return element type name
|
||||||
|
elem_typ = g.gen_array_equality_fn(left_sym.array_info().elem_type)
|
||||||
|
}
|
||||||
|
if ptr_typ in g.array_fn_definitions {
|
||||||
|
return ptr_typ
|
||||||
|
}
|
||||||
g.array_fn_definitions << ptr_typ
|
g.array_fn_definitions << ptr_typ
|
||||||
g.definitions.writeln('bool ${ptr_typ}_arr_eq(array_${ptr_typ} a, array_${ptr_typ} b) {')
|
g.definitions.writeln('bool ${ptr_typ}_arr_eq(array_${ptr_typ} a, array_${ptr_typ} b) {')
|
||||||
g.definitions.writeln('\tif (a.len != b.len) {')
|
g.definitions.writeln('\tif (a.len != b.len) {')
|
||||||
|
@ -2627,8 +2635,10 @@ fn (mut g Gen) generate_array_equality_fn(ptr_typ string, styp table.Type, sym &
|
||||||
g.definitions.writeln('\tfor (int i = 0; i < a.len; i++) {')
|
g.definitions.writeln('\tfor (int i = 0; i < a.len; i++) {')
|
||||||
if styp == table.string_type_idx {
|
if styp == table.string_type_idx {
|
||||||
g.definitions.writeln('\t\tif (string_ne(*((${ptr_typ}*)((byte*)a.data+(i*a.element_size))), *((${ptr_typ}*)((byte*)b.data+(i*b.element_size))))) {')
|
g.definitions.writeln('\t\tif (string_ne(*((${ptr_typ}*)((byte*)a.data+(i*a.element_size))), *((${ptr_typ}*)((byte*)b.data+(i*b.element_size))))) {')
|
||||||
} else if sym.kind == .struct_ {
|
} else if elem_sym.kind == .struct_ {
|
||||||
g.definitions.writeln('\t\tif (memcmp((byte*)a.data+(i*a.element_size), (byte*)b.data+(i*b.element_size), a.element_size)) {')
|
g.definitions.writeln('\t\tif (memcmp((byte*)a.data+(i*a.element_size), (byte*)b.data+(i*b.element_size), a.element_size)) {')
|
||||||
|
} else if elem_sym.kind == .array {
|
||||||
|
g.definitions.writeln('\t\tif (!${elem_typ}_arr_eq(a, b)) {')
|
||||||
} else {
|
} else {
|
||||||
g.definitions.writeln('\t\tif (*((${ptr_typ}*)((byte*)a.data+(i*a.element_size))) != *((${ptr_typ}*)((byte*)b.data+(i*b.element_size)))) {')
|
g.definitions.writeln('\t\tif (*((${ptr_typ}*)((byte*)a.data+(i*a.element_size))) != *((${ptr_typ}*)((byte*)b.data+(i*b.element_size)))) {')
|
||||||
}
|
}
|
||||||
|
@ -2637,6 +2647,7 @@ fn (mut g Gen) generate_array_equality_fn(ptr_typ string, styp table.Type, sym &
|
||||||
g.definitions.writeln('\t}')
|
g.definitions.writeln('\t}')
|
||||||
g.definitions.writeln('\treturn true;')
|
g.definitions.writeln('\treturn true;')
|
||||||
g.definitions.writeln('}')
|
g.definitions.writeln('}')
|
||||||
|
return ptr_typ
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verror(s string) {
|
fn verror(s string) {
|
||||||
|
@ -3249,12 +3260,7 @@ fn (mut g Gen) in_optimization(left ast.Expr, right ast.ArrayInit) {
|
||||||
if is_str {
|
if is_str {
|
||||||
g.write('string_eq(')
|
g.write('string_eq(')
|
||||||
} else if is_array {
|
} else if is_array {
|
||||||
styp := g.table.value_type(right.elem_type)
|
ptr_typ := g.gen_array_equality_fn(right.elem_type)
|
||||||
ptr_typ := g.typ(right.elem_type).split('_')[1]
|
|
||||||
if ptr_typ !in g.array_fn_definitions {
|
|
||||||
sym := g.table.get_type_symbol(elem_sym.array_info().elem_type)
|
|
||||||
g.generate_array_equality_fn(ptr_typ, styp, sym)
|
|
||||||
}
|
|
||||||
g.write('${ptr_typ}_arr_eq(')
|
g.write('${ptr_typ}_arr_eq(')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,3 +44,12 @@ fn test_array_equality() {
|
||||||
assert colors != [Color.blue, Color.green, Color.red]
|
assert colors != [Color.blue, Color.green, Color.red]
|
||||||
assert colors != [Color.blue, Color.red, Color.green]
|
assert colors != [Color.blue, Color.red, Color.green]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_nested_array_equality() {
|
||||||
|
a := [[1]]
|
||||||
|
assert a == [[1]]
|
||||||
|
b := [[[[1]]]]
|
||||||
|
assert b == [[[[1]]]]
|
||||||
|
c := [[[1,2,3]]]
|
||||||
|
assert c == [[[1,2,3]]]
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue