Skip to content

Commit e6720d7

Browse files
committed
compiler: add support for comparing complex numbers
1 parent dfef168 commit e6720d7

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

compiler/compiler.go

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,7 +2400,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p
24002400
return c.builder.CreateICmp(llvm.IntUGE, x, y, ""), nil
24012401
}
24022402
default:
2403-
return llvm.Value{}, c.makeError(pos, "todo: binop on integer: "+op.String())
2403+
panic("binop on integer: " + op.String())
24042404
}
24052405
} else if typ.Info()&types.IsFloat != 0 {
24062406
// Operations on floats
@@ -2413,8 +2413,6 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p
24132413
return c.builder.CreateFMul(x, y, ""), nil
24142414
case token.QUO: // /
24152415
return c.builder.CreateFDiv(x, y, ""), nil
2416-
case token.REM: // %
2417-
return c.builder.CreateFRem(x, y, ""), nil
24182416
case token.EQL: // ==
24192417
return c.builder.CreateFCmp(llvm.FloatOEQ, x, y, ""), nil
24202418
case token.NEQ: // !=
@@ -2428,7 +2426,27 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p
24282426
case token.GEQ: // >=
24292427
return c.builder.CreateFCmp(llvm.FloatOGE, x, y, ""), nil
24302428
default:
2431-
return llvm.Value{}, c.makeError(pos, "todo: binop on float: "+op.String())
2429+
panic("binop on float: " + op.String())
2430+
}
2431+
} else if typ.Info()&types.IsComplex != 0 {
2432+
indexr := llvm.ConstInt(c.ctx.Int32Type(), 0, false)
2433+
indexi := llvm.ConstInt(c.ctx.Int32Type(), 1, false)
2434+
r1 := c.builder.CreateExtractElement(x, indexr, "r1")
2435+
r2 := c.builder.CreateExtractElement(y, indexr, "r2")
2436+
i1 := c.builder.CreateExtractElement(x, indexi, "i1")
2437+
i2 := c.builder.CreateExtractElement(y, indexi, "i2")
2438+
switch op {
2439+
case token.EQL: // ==
2440+
req := c.builder.CreateFCmp(llvm.FloatOEQ, r1, r2, "")
2441+
ieq := c.builder.CreateFCmp(llvm.FloatOEQ, i1, i2, "")
2442+
return c.builder.CreateAnd(req, ieq, ""), nil
2443+
case token.NEQ: // !=
2444+
req := c.builder.CreateFCmp(llvm.FloatOEQ, r1, r2, "")
2445+
ieq := c.builder.CreateFCmp(llvm.FloatOEQ, i1, i2, "")
2446+
neq := c.builder.CreateAnd(req, ieq, "")
2447+
return c.builder.CreateNot(neq, ""), nil
2448+
default:
2449+
return llvm.Value{}, c.makeError(pos, "todo: binop on complex number: "+op.String())
24322450
}
24332451
} else if typ.Info()&types.IsBoolean != 0 {
24342452
// Operations on booleans
@@ -2438,7 +2456,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p
24382456
case token.NEQ: // !=
24392457
return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil
24402458
default:
2441-
return llvm.Value{}, c.makeError(pos, "todo: binop on boolean: "+op.String())
2459+
panic("binop on bool: " + op.String())
24422460
}
24432461
} else if typ.Kind() == types.UnsafePointer {
24442462
// Operations on pointers
@@ -2448,7 +2466,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p
24482466
case token.NEQ: // !=
24492467
return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil
24502468
default:
2451-
return llvm.Value{}, c.makeError(pos, "todo: binop on pointer: "+op.String())
2469+
panic("binop on pointer: " + op.String())
24522470
}
24532471
} else if typ.Info()&types.IsString != 0 {
24542472
// Operations on strings
@@ -2471,7 +2489,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p
24712489
case token.GEQ: // >=
24722490
return c.createRuntimeCall("stringLess", []llvm.Value{y, x}, ""), nil
24732491
default:
2474-
return llvm.Value{}, c.makeError(pos, "todo: binop on string: "+op.String())
2492+
panic("binop on string: " + op.String())
24752493
}
24762494
} else {
24772495
return llvm.Value{}, c.makeError(pos, "todo: unknown basic type in binop: "+typ.String())

testdata/binop.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,20 @@ func main() {
4747
println(s2 == Struct2{"foo", 0.0, 7})
4848
println(s2 == Struct2{"foo", 1.0, 5})
4949
println(s2 == Struct2{"foo", 1.0, 7})
50+
51+
println("complex numbers")
52+
println(c64 == 3+2i)
53+
println(c64 == 4+2i)
54+
println(c64 == 3+3i)
55+
println(c64 != 3+2i)
56+
println(c64 != 4+2i)
57+
println(c64 != 3+3i)
58+
println(c128 == 3+2i)
59+
println(c128 == 4+2i)
60+
println(c128 == 3+3i)
61+
println(c128 != 3+2i)
62+
println(c128 != 4+2i)
63+
println(c128 != 3+3i)
5064
}
5165

5266
var x = true
@@ -58,6 +72,9 @@ var s2 = Struct2{"foo", 0.0, 5}
5872

5973
var a1 = [2]int{1, 2}
6074

75+
var c64 = 3 + 2i
76+
var c128 = 4 + 3i
77+
6178
type Int int
6279

6380
type Struct1 struct {

testdata/binop.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,16 @@ true
4141
false
4242
true
4343
false
44+
complex numbers
45+
true
46+
false
47+
false
48+
false
49+
true
50+
true
51+
false
52+
false
53+
false
54+
true
55+
true
56+
true

0 commit comments

Comments
 (0)