diff --git a/compiler.go b/compiler.go index 40c68928..41d48193 100644 --- a/compiler.go +++ b/compiler.go @@ -2219,6 +2219,17 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error } else { return llvm.Value{}, errors.New("todo: unknown basic type in binop: " + typ.String()) } + case *types.Interface: + switch binop.Op { + case token.EQL, token.NEQ: // ==, != + result := c.builder.CreateCall(c.mod.NamedFunction("runtime.interfaceEqual"), []llvm.Value{x, y}, "") + if binop.Op == token.NEQ { + result = c.builder.CreateNot(result, "") + } + return result, nil + default: + return llvm.Value{}, errors.New("binop on interface: " + binop.Op.String()) + } case *types.Pointer: switch binop.Op { case token.EQL: // == diff --git a/src/runtime/interface.go b/src/runtime/interface.go index 98d8f954..aaaa575d 100644 --- a/src/runtime/interface.go +++ b/src/runtime/interface.go @@ -58,3 +58,17 @@ func interfaceMethod(itf _interface, method uint16) *uint8 { i++ } } + +// Return true iff both interfaces are equal. +func interfaceEqual(x, y _interface) bool { + if x.typecode != y.typecode { + // Different dynamic type so always unequal. + return false + } + if x.typecode == 0 { + // Both interfaces are nil, so they are equal. + return true + } + // TODO: depends on reflection. + panic("unimplemented: interface equality") +}