diff --git a/compiler/compiler.go b/compiler/compiler.go index 98ae5a9a..74fb8e6a 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -2400,7 +2400,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p return c.builder.CreateICmp(llvm.IntUGE, x, y, ""), nil } default: - return llvm.Value{}, c.makeError(pos, "todo: binop on integer: "+op.String()) + panic("binop on integer: " + op.String()) } } else if typ.Info()&types.IsFloat != 0 { // Operations on floats @@ -2413,8 +2413,6 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p return c.builder.CreateFMul(x, y, ""), nil case token.QUO: // / return c.builder.CreateFDiv(x, y, ""), nil - case token.REM: // % - return c.builder.CreateFRem(x, y, ""), nil case token.EQL: // == return c.builder.CreateFCmp(llvm.FloatOEQ, x, y, ""), nil case token.NEQ: // != @@ -2428,7 +2426,27 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p case token.GEQ: // >= return c.builder.CreateFCmp(llvm.FloatOGE, x, y, ""), nil default: - return llvm.Value{}, c.makeError(pos, "todo: binop on float: "+op.String()) + panic("binop on float: " + op.String()) + } + } else if typ.Info()&types.IsComplex != 0 { + indexr := llvm.ConstInt(c.ctx.Int32Type(), 0, false) + indexi := llvm.ConstInt(c.ctx.Int32Type(), 1, false) + r1 := c.builder.CreateExtractElement(x, indexr, "r1") + r2 := c.builder.CreateExtractElement(y, indexr, "r2") + i1 := c.builder.CreateExtractElement(x, indexi, "i1") + i2 := c.builder.CreateExtractElement(y, indexi, "i2") + switch op { + case token.EQL: // == + req := c.builder.CreateFCmp(llvm.FloatOEQ, r1, r2, "") + ieq := c.builder.CreateFCmp(llvm.FloatOEQ, i1, i2, "") + return c.builder.CreateAnd(req, ieq, ""), nil + case token.NEQ: // != + req := c.builder.CreateFCmp(llvm.FloatOEQ, r1, r2, "") + ieq := c.builder.CreateFCmp(llvm.FloatOEQ, i1, i2, "") + neq := c.builder.CreateAnd(req, ieq, "") + return c.builder.CreateNot(neq, ""), nil + default: + return llvm.Value{}, c.makeError(pos, "todo: binop on complex number: "+op.String()) } } else if typ.Info()&types.IsBoolean != 0 { // Operations on booleans @@ -2438,7 +2456,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p case token.NEQ: // != return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil default: - return llvm.Value{}, c.makeError(pos, "todo: binop on boolean: "+op.String()) + panic("binop on bool: " + op.String()) } } else if typ.Kind() == types.UnsafePointer { // Operations on pointers @@ -2448,7 +2466,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p case token.NEQ: // != return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil default: - return llvm.Value{}, c.makeError(pos, "todo: binop on pointer: "+op.String()) + panic("binop on pointer: " + op.String()) } } else if typ.Info()&types.IsString != 0 { // Operations on strings @@ -2471,7 +2489,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p case token.GEQ: // >= return c.createRuntimeCall("stringLess", []llvm.Value{y, x}, ""), nil default: - return llvm.Value{}, c.makeError(pos, "todo: binop on string: "+op.String()) + panic("binop on string: " + op.String()) } } else { return llvm.Value{}, c.makeError(pos, "todo: unknown basic type in binop: "+typ.String()) diff --git a/testdata/binop.go b/testdata/binop.go index e98545f9..f58a94c1 100644 --- a/testdata/binop.go +++ b/testdata/binop.go @@ -47,6 +47,20 @@ func main() { println(s2 == Struct2{"foo", 0.0, 7}) println(s2 == Struct2{"foo", 1.0, 5}) println(s2 == Struct2{"foo", 1.0, 7}) + + println("complex numbers") + println(c64 == 3+2i) + println(c64 == 4+2i) + println(c64 == 3+3i) + println(c64 != 3+2i) + println(c64 != 4+2i) + println(c64 != 3+3i) + println(c128 == 3+2i) + println(c128 == 4+2i) + println(c128 == 3+3i) + println(c128 != 3+2i) + println(c128 != 4+2i) + println(c128 != 3+3i) } var x = true @@ -58,6 +72,9 @@ var s2 = Struct2{"foo", 0.0, 5} var a1 = [2]int{1, 2} +var c64 = 3 + 2i +var c128 = 4 + 3i + type Int int type Struct1 struct { diff --git a/testdata/binop.txt b/testdata/binop.txt index 72e67198..8d1f37be 100644 --- a/testdata/binop.txt +++ b/testdata/binop.txt @@ -41,3 +41,16 @@ true false true false +complex numbers +true +false +false +false +true +true +false +false +false +true +true +true