builtin: real/imag/complex; c/math/cmplx; patch: math/cmplx
This commit is contained in:
@@ -66,6 +66,21 @@ func (b Builder) getField(x Expr, idx int) Expr {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
func (b Builder) Complex(r, i Expr) Expr {
|
||||
if debugInstr {
|
||||
log.Printf("Complex %v, %v\n", r.impl, i.impl)
|
||||
}
|
||||
prog := b.Prog
|
||||
var t Type
|
||||
switch kind := r.raw.Type.Underlying().(*types.Basic).Kind(); kind {
|
||||
case types.Float64:
|
||||
t = prog.Complex128()
|
||||
case types.Float32:
|
||||
t = prog.Complex64()
|
||||
}
|
||||
return b.aggregateValue(t, r.impl, i.impl)
|
||||
}
|
||||
|
||||
// MakeString creates a new string from a C string pointer and length.
|
||||
func (b Builder) MakeString(cstr Expr, n ...Expr) (ret Expr) {
|
||||
if debugInstr {
|
||||
|
||||
22
ssa/expr.go
22
ssa/expr.go
@@ -168,11 +168,20 @@ func (p Program) IntVal(v uint64, t Type) Expr {
|
||||
return Expr{ret, t}
|
||||
}
|
||||
|
||||
// FloatVal returns a float constant expression.
|
||||
func (p Program) FloatVal(v float64, t Type) Expr {
|
||||
ret := llvm.ConstFloat(t.ll, v)
|
||||
return Expr{ret, t}
|
||||
}
|
||||
|
||||
// ComplexVal returns a complex constant expression.
|
||||
func (p Program) ComplexVal(v complex128, t Type) Expr {
|
||||
flt := p.Field(t, 0)
|
||||
re := p.FloatVal(real(v), flt)
|
||||
im := p.FloatVal(imag(v), flt)
|
||||
return Expr{llvm.ConstStruct([]llvm.Value{re.impl, im.impl}, false), t}
|
||||
}
|
||||
|
||||
// Val returns a constant expression.
|
||||
func (p Program) Val(v interface{}) Expr {
|
||||
switch v := v.(type) {
|
||||
@@ -211,11 +220,16 @@ func (b Builder) Const(v constant.Value, typ Type) Expr {
|
||||
if v, exact := constant.Uint64Val(v); exact {
|
||||
return prog.IntVal(v, typ)
|
||||
}
|
||||
case kind == types.Float32 || kind == types.Float64:
|
||||
case kind == types.Float64 || kind == types.Float32:
|
||||
v, _ := constant.Float64Val(v)
|
||||
return prog.FloatVal(v, typ)
|
||||
case kind == types.String:
|
||||
return Expr{b.Str(constant.StringVal(v)).impl, typ}
|
||||
case kind == types.Complex128 || kind == types.Complex64:
|
||||
v = constant.ToComplex(v)
|
||||
re, _ := constant.Float64Val(constant.Real(v))
|
||||
im, _ := constant.Float64Val(constant.Imag(v))
|
||||
return prog.ComplexVal(complex(re, im), typ)
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("unsupported Const: %v, %v", v, raw))
|
||||
@@ -941,6 +955,12 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
return b.Recover()
|
||||
case "print", "println":
|
||||
return b.PrintEx(fn == "println", args...)
|
||||
case "complex":
|
||||
return b.Complex(args[0], args[1])
|
||||
case "real":
|
||||
return b.getField(args[0], 0)
|
||||
case "imag":
|
||||
return b.getField(args[0], 1)
|
||||
case "String": // unsafe.String
|
||||
return b.unsafeString(args[0].impl, args[1].impl)
|
||||
case "Slice": // unsafe.Slice
|
||||
|
||||
@@ -125,15 +125,16 @@ type aProgram struct {
|
||||
voidType llvm.Type
|
||||
voidPtrTy llvm.Type
|
||||
|
||||
c64Type llvm.Type
|
||||
c128Type llvm.Type
|
||||
|
||||
rtStringTy llvm.Type
|
||||
rtEfaceTy llvm.Type
|
||||
rtIfaceTy llvm.Type
|
||||
rtSliceTy llvm.Type
|
||||
rtMapTy llvm.Type
|
||||
|
||||
anyTy Type
|
||||
//anyPtr Type
|
||||
//anyPPtr Type
|
||||
anyTy Type
|
||||
voidTy Type
|
||||
voidPtr Type
|
||||
voidPPtr Type
|
||||
@@ -147,6 +148,8 @@ type aProgram struct {
|
||||
uintTy Type
|
||||
f64Ty Type
|
||||
f32Ty Type
|
||||
c128Ty Type
|
||||
c64Ty Type
|
||||
byteTy Type
|
||||
i32Ty Type
|
||||
u32Ty Type
|
||||
@@ -284,6 +287,24 @@ func (p Program) rtString() llvm.Type {
|
||||
return p.rtStringTy
|
||||
}
|
||||
|
||||
func (p Program) tyComplex64() llvm.Type {
|
||||
if p.c64Type.IsNil() {
|
||||
ctx := p.ctx
|
||||
f32 := ctx.FloatType()
|
||||
p.c64Type = ctx.StructType([]llvm.Type{f32, f32}, false)
|
||||
}
|
||||
return p.c64Type
|
||||
}
|
||||
|
||||
func (p Program) tyComplex128() llvm.Type {
|
||||
if p.c128Type.IsNil() {
|
||||
ctx := p.ctx
|
||||
f64 := ctx.DoubleType()
|
||||
p.c128Type = ctx.StructType([]llvm.Type{f64, f64}, false)
|
||||
}
|
||||
return p.c128Type
|
||||
}
|
||||
|
||||
// NewPackage creates a new package.
|
||||
func (p Program) NewPackage(name, pkgPath string) Package {
|
||||
mod := p.ctx.NewModule(pkgPath)
|
||||
@@ -394,24 +415,6 @@ func (p Program) String() Type {
|
||||
return p.stringTy
|
||||
}
|
||||
|
||||
/*
|
||||
// AnyPtrPtr returns **any type.
|
||||
func (p Program) AnyPtrPtr() Type {
|
||||
if p.anyPPtr == nil {
|
||||
p.anyPPtr = p.Pointer(p.AnyPtr())
|
||||
}
|
||||
return p.anyPPtr
|
||||
}
|
||||
|
||||
// AnyPtr returns *any type.
|
||||
func (p Program) AnyPtr() Type {
|
||||
if p.anyPtr == nil {
|
||||
p.anyPtr = p.Pointer(p.Any())
|
||||
}
|
||||
return p.anyPtr
|
||||
}
|
||||
*/
|
||||
|
||||
// Any returns the any (empty interface) type.
|
||||
func (p Program) Any() Type {
|
||||
if p.anyTy == nil {
|
||||
@@ -484,6 +487,22 @@ func (p Program) Float32() Type {
|
||||
return p.f32Ty
|
||||
}
|
||||
|
||||
// Complex128 returns complex128 type.
|
||||
func (p Program) Complex128() Type {
|
||||
if p.c128Ty == nil {
|
||||
p.c128Ty = p.rawType(types.Typ[types.Complex128])
|
||||
}
|
||||
return p.c128Ty
|
||||
}
|
||||
|
||||
// Complex64 returns complex64 type.
|
||||
func (p Program) Complex64() Type {
|
||||
if p.c64Ty == nil {
|
||||
p.c64Ty = p.rawType(types.Typ[types.Complex64])
|
||||
}
|
||||
return p.c64Ty
|
||||
}
|
||||
|
||||
// Byte returns byte type.
|
||||
func (p Program) Byte() Type {
|
||||
if p.byteTy == nil {
|
||||
|
||||
10
ssa/type.go
10
ssa/type.go
@@ -214,6 +214,14 @@ func (p Program) Field(typ Type, i int) Type {
|
||||
switch t := typ.raw.Type.(type) {
|
||||
case *types.Tuple:
|
||||
fld = t.At(i)
|
||||
case *types.Basic:
|
||||
switch t.Kind() {
|
||||
case types.Complex128:
|
||||
return p.Float64()
|
||||
case types.Complex64:
|
||||
return p.Float32()
|
||||
}
|
||||
panic("Field: basic type doesn't have fields")
|
||||
default:
|
||||
fld = t.Underlying().(*types.Struct).Field(i)
|
||||
}
|
||||
@@ -330,7 +338,9 @@ func (p Program) toType(raw types.Type) Type {
|
||||
case types.Float64:
|
||||
return &aType{p.ctx.DoubleType(), typ, vkFloat}
|
||||
case types.Complex64:
|
||||
return &aType{p.tyComplex64(), typ, vkComplex}
|
||||
case types.Complex128:
|
||||
return &aType{p.tyComplex128(), typ, vkComplex}
|
||||
case types.String:
|
||||
return &aType{p.rtString(), typ, vkString}
|
||||
case types.UnsafePointer:
|
||||
|
||||
Reference in New Issue
Block a user