diff --git a/internal/runtime/z_print.go b/internal/runtime/z_print.go index cbf9d83d3..7203a7001 100644 --- a/internal/runtime/z_print.go +++ b/internal/runtime/z_print.go @@ -47,12 +47,12 @@ func PrintFloat(v float64) { } return } - c.Fprintf(c.Stderr, c.Str("%e"), v) + c.Fprintf(c.Stderr, c.Str("%+e"), v) } -// func PrintComplex(c complex128) { -// print("(", real(c), imag(c), "i)") -// } +func PrintComplex(v complex128) { + c.Fprintf(c.Stderr, c.Str("(%+e%+ei)"), real(v), imag(v)) +} func PrintUint(v uint64) { c.Fprintf(c.Stderr, c.Str("%llu"), v) diff --git a/internal/runtime/z_rt.go b/internal/runtime/z_rt.go index 6653ff3d0..eb9bbac9b 100644 --- a/internal/runtime/z_rt.go +++ b/internal/runtime/z_rt.go @@ -122,6 +122,10 @@ func TracePanic(v any) { } else { println(*(*float64)(e.data)) } + case abi.Complex64: + println(*(*complex64)(e.data)) + case abi.Complex128: + println(*(*complex128)(e.data)) case abi.String: println(*(*string)(e.data)) default: diff --git a/ssa/abi/abi.go b/ssa/abi/abi.go index 127e36cbc..90186b578 100644 --- a/ssa/abi/abi.go +++ b/ssa/abi/abi.go @@ -89,7 +89,7 @@ func DataKindOf(raw types.Type, lvl int, is32Bits bool) (DataKind, types.Type, i return Integer, raw, lvl case kind == types.Float32: return BitCast, raw, lvl - case kind == types.Float64 || kind == types.Complex64: + case kind == types.Float64: if is32Bits { return Indirect, raw, lvl } diff --git a/ssa/expr.go b/ssa/expr.go index a9d9d1aa3..30e65522a 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -685,6 +685,18 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) { ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("StringFromRune"), x).impl return } + case types.Complex128: + switch xtyp := x.RawType().Underlying().(type) { + case *types.Basic: + if xtyp.Kind() == types.Complex64 { + r := b.impl.CreateExtractValue(x.impl, 0, "") + i := b.impl.CreateExtractValue(x.impl, 1, "") + r = castFloat(b, r, b.Prog.Float64()) + i = castFloat(b, i, b.Prog.Float64()) + ret.impl = b.aggregateValue(t, r, i).impl + return + } + } } switch xtyp := x.RawType().Underlying().(type) { case *types.Basic: @@ -716,6 +728,16 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) { } } } + if x.kind == vkComplex && t.kind == vkComplex { + ft := b.Prog.Complex128() + if t.raw.Type.Underlying().(*types.Basic).Kind() == types.Complex64 { + ft = b.Prog.Complex64() + } + r := b.impl.CreateExtractValue(x.impl, 0, "") + i := b.impl.CreateExtractValue(x.impl, 1, "") + ret.impl = b.Complex(Expr{castFloat(b, r, ft), ft}, Expr{castFloat(b, i, ft), ft}).impl + return + } case *types.Pointer: ret.impl = castPtr(b.impl, x.impl, t.ll) return @@ -1013,8 +1035,9 @@ func (b Builder) PrintEx(ln bool, args ...Expr) (ret Expr) { fn = "PrintEface" case vkIface: fn = "PrintIface" - // case vkComplex: - // fn = "PrintComplex" + case vkComplex: + fn = "PrintComplex" + typ = prog.Complex128() default: panic(fmt.Errorf("illegal types for operand: print %v", arg.RawType())) } diff --git a/ssa/type.go b/ssa/type.go index cc192ad5c..16a98dd65 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -211,7 +211,7 @@ func (p Program) Index(typ Type) Type { func (p Program) Field(typ Type, i int) Type { var fld *types.Var - switch t := typ.raw.Type.(type) { + switch t := typ.raw.Type.Underlying().(type) { case *types.Tuple: fld = t.At(i) case *types.Basic: @@ -223,7 +223,7 @@ func (p Program) Field(typ Type, i int) Type { } panic("Field: basic type doesn't have fields") default: - fld = t.Underlying().(*types.Struct).Field(i) + fld = t.(*types.Struct).Field(i) } return p.rawType(fld.Type()) }