diff --git a/compiler/compiler.go b/compiler/compiler.go index b482fa10..0409cc66 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -2867,6 +2867,30 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value) ( default: return llvm.Value{}, errors.New("todo: binop on slice: " + op.String()) } + case *types.Array: + // Compare each array element and combine the result. From the spec: + // Array values are comparable if values of the array element type + // are comparable. Two array values are equal if their corresponding + // elements are equal. + result := llvm.ConstInt(c.ctx.Int1Type(), 1, true) + for i := 0; i < int(typ.Len()); i++ { + xField := c.builder.CreateExtractValue(x, i, "") + yField := c.builder.CreateExtractValue(y, i, "") + fieldEqual, err := c.parseBinOp(token.EQL, typ.Elem(), xField, yField) + if err != nil { + return llvm.Value{}, err + } + result = c.builder.CreateAnd(result, fieldEqual, "") + } + switch op { + case token.EQL: // == + return result, nil + case token.NEQ: // != + return c.builder.CreateNot(result, ""), nil + default: + return llvm.Value{}, errors.New("unknown: binop on struct: " + op.String()) + } + return result, nil case *types.Struct: // Compare each struct field and combine the result. From the spec: // Struct values are comparable if all their fields are comparable. diff --git a/testdata/binop.go b/testdata/binop.go index 24774aad..64a33953 100644 --- a/testdata/binop.go +++ b/testdata/binop.go @@ -24,6 +24,14 @@ func main() { println("ab" < "aa") println("aa" < "ab") + println("array equality") + println(a1 == [2]int{1, 2}) + println(a1 != [2]int{1, 2}) + println(a1 == [2]int{1, 3}) + println(a1 == [2]int{2, 2}) + println(a1 == [2]int{2, 1}) + println(a1 != [2]int{2, 1}) + println("struct equality") println(s1 == Struct1{3, true}) println(s1 == Struct1{4, true}) @@ -48,6 +56,8 @@ var a = "a" var s1 = Struct1{3, true} var s2 = Struct2{"foo", 0.0, 5} +var a1 = [2]int{1, 2} + type Struct1 struct { i int b bool diff --git a/testdata/binop.txt b/testdata/binop.txt index 1e2f40e7..72e67198 100644 --- a/testdata/binop.txt +++ b/testdata/binop.txt @@ -20,6 +20,13 @@ true false false true +array equality +true +false +false +false +false +true struct equality true false