Browse Source

compiler: add support for comparing complex numbers

pull/167/head
Ayke van Laethem 6 years ago
parent
commit
e6720d7ddc
No known key found for this signature in database GPG Key ID: E97FF5335DFDFDED
  1. 32
      compiler/compiler.go
  2. 17
      testdata/binop.go
  3. 13
      testdata/binop.txt

32
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())

17
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 {

13
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

Loading…
Cancel
Save