Commit 426099f4 authored by Ken Thompson's avatar Ken Thompson

6g complex type usable

8g and 5g have stubs to ignore complex

R=rsc
CC=golang-dev
https://golang.org/cl/257042
parent a9b9afa9
......@@ -55,6 +55,12 @@ cgen(Node *n, Node *res)
if(res == N || res->type == T)
fatal("cgen: res nil");
// TODO compile complex
if(n != N && n->type != T && iscomplex[n->type->etype])
return;
if(res != N && res->type != T && iscomplex[res->type->etype])
return;
while(n->op == OCONVNOP)
n = n->left;
......@@ -186,6 +192,12 @@ cgen(Node *n, Node *res)
fatal("cgen: unknown op %N", n);
break;
case OREAL:
case OIMAG:
case OCMPLX:
// TODO compile complex
return;
// these call bgen to get a bool value
case OOROR:
case OANDAND:
......@@ -787,6 +799,12 @@ bgen(Node *n, int true, Prog *to)
nl = n->left;
nr = n->right;
// TODO compile complex
if(nl != N && nl->type != T && iscomplex[nl->type->etype])
return;
if(nr != N && nr->type != T && iscomplex[nr->type->etype])
return;
if(n->type == T) {
convlit(&n, types[TBOOL]);
if(n->type == T)
......
......@@ -68,6 +68,11 @@ cgen(Node *n, Node *res)
if(res->ullman >= UINF)
goto gen;
if(complexop(n, res)) {
complexgen(n, res);
goto ret;
}
f = 1; // gen thru register
switch(n->op) {
case OLITERAL:
......@@ -79,20 +84,22 @@ cgen(Node *n, Node *res)
break;
}
a = optoas(OAS, res->type);
if(sudoaddable(a, res, &addr)) {
if(f) {
regalloc(&n2, res->type, N);
cgen(n, &n2);
p1 = gins(a, &n2, N);
regfree(&n2);
} else
p1 = gins(a, n, N);
p1->to = addr;
if(debug['g'])
print("%P [ignore previous line]\n", p1);
sudoclean();
goto ret;
if(!iscomplex[n->type->etype]) {
a = optoas(OAS, res->type);
if(sudoaddable(a, res, &addr)) {
if(f) {
regalloc(&n2, res->type, N);
cgen(n, &n2);
p1 = gins(a, &n2, N);
regfree(&n2);
} else
p1 = gins(a, n, N);
p1->to = addr;
if(debug['g'])
print("%P [ignore previous line]\n", p1);
sudoclean();
goto ret;
}
}
gen:
......@@ -139,20 +146,22 @@ cgen(Node *n, Node *res)
goto ret;
}
a = optoas(OAS, n->type);
if(sudoaddable(a, n, &addr)) {
if(res->op == OREGISTER) {
p1 = gins(a, N, res);
p1->from = addr;
} else {
regalloc(&n2, n->type, N);
p1 = gins(a, N, &n2);
p1->from = addr;
gins(a, &n2, res);
regfree(&n2);
if(!iscomplex[n->type->etype]) {
a = optoas(OAS, n->type);
if(sudoaddable(a, n, &addr)) {
if(res->op == OREGISTER) {
p1 = gins(a, N, res);
p1->from = addr;
} else {
regalloc(&n2, n->type, N);
p1 = gins(a, N, &n2);
p1->from = addr;
gins(a, &n2, res);
regfree(&n2);
}
sudoclean();
goto ret;
}
sudoclean();
goto ret;
}
switch(n->op) {
......
......@@ -27,12 +27,12 @@ complexmove(Node *f, Node *t, int perm)
Node n1, n2, n3, n4, nc;
if(debug['g']) {
dump("\ncomplex-f", f);
dump("complex-t", t);
dump("\ncomplexmove-f", f);
dump("complexmove-t", t);
}
if(!t->addable)
fatal("to no addable");
fatal("complexmove: to not addable");
ft = simsimtype(f->type);
tt = simsimtype(t->type);
......@@ -118,34 +118,90 @@ complexop(Node *n, Node *res)
{
if(n != N && n->type != T)
if(iscomplex[n->type->etype]) {
switch(n->op) {
case OCONV:
case OADD:
case OSUB:
case OMUL:
case ODIV:
case OMINUS:
goto yes;
}
//dump("complexop no", n);
goto yes;
}
if(res != N && res->type != T)
if(iscomplex[res->type->etype]) {
goto yes;
}
if(n->op == OREAL || n->op == OIMAG)
return 1;
return 0;
yes:
return 1;
switch(n->op) {
case OCONV: // implemented ops
case OADD:
case OSUB:
case OMUL:
case ODIV:
case OMINUS:
case OCMPLX:
case OREAL:
case OIMAG:
return 1;
case ODOT: // sudoaddr
case ODOTPTR:
case OINDEX:
case OIND:
case ONAME:
return 1;
}
return 0;
}
void
complexgen(Node *n, Node *res)
{
Node *nl, *nr;
Node tnl, tnr;
Node n1, n2, n3, n4, n5, n6;
Node ra, rb, rc, rd;
int tl, tr;
if(debug['g']) {
dump("\ncomplex-n", n);
dump("complex-res", res);
dump("\ncomplexgen-n", n);
dump("complexgen-res", res);
}
// pick off float/complex opcodes
switch(n->op) {
case OCMPLX:
tempname(&tnr, n->type);
tr = simsimtype(n->type);
tr = cplxsubtype(tr);
n1 = tnr;
n1.type = types[tr];
n2 = tnr;
n2.type = types[tr];
n2.xoffset += n2.type->width;
cgen(n->left, &n1);
cgen(n->right, &n2);
cgen(&tnr, res);
return;
case OREAL:
n = n->left;
tr = simsimtype(n->type);
tr = cplxsubtype(tr);
subnode(&n1, &n2, n);
cgen(&n1, res);
return;
case OIMAG:
n = n->left;
tr = simsimtype(n->type);
tr = cplxsubtype(tr);
subnode(&n1, &n2, n);
cgen(&n2, res);
return;
}
// perform conversion from n to res
......@@ -163,6 +219,44 @@ complexgen(Node *n, Node *res)
return;
}
if(!res->addable) {
igen(res, &n1, N);
cgen(n, &n1);
regfree(&n1);
return;
}
if(n->addable) {
complexmove(n, res, 0);
return;
}
switch(n->op) {
default:
dump("complexgen: unknown op", n);
fatal("complexgen: unknown op %O", n->op);
case ODOT:
case ODOTPTR:
case OINDEX:
case OIND:
case ONAME: // PHEAP or PPARAMREF var
igen(n, &n1, res);
complexmove(&n1, res, 0);
regfree(&n1);
return;
case OCONV:
case OADD:
case OSUB:
case OMUL:
case ODIV:
case OMINUS:
case OCMPLX:
case OREAL:
case OIMAG:
break;
}
nl = n->left;
if(nl == N)
return;
......@@ -171,25 +265,25 @@ complexgen(Node *n, Node *res)
// make both sides addable in ullman order
if(nr != N) {
if(nl->ullman > nr->ullman && !nl->addable) {
tempname(&n1, nl->type);
complexgen(nl, &n1);
nl = &n1;
tempname(&tnl, nl->type);
cgen(nl, &tnl);
nl = &tnl;
}
if(!nr->addable) {
tempname(&n2, nr->type);
complexgen(nr, &n2);
nr = &n2;
tempname(&tnr, nr->type);
cgen(nr, &tnr);
nr = &tnr;
}
}
if(!nl->addable) {
tempname(&n1, nl->type);
complexgen(nl, &n1);
nl = &n1;
tempname(&tnl, nl->type);
cgen(nl, &tnl);
nl = &tnl;
}
switch(n->op) {
default:
fatal("opcode %O", n->op);
fatal("complexgen: unknown op %O", n->op);
break;
case OCONV:
......@@ -325,26 +419,27 @@ complexgen(Node *n, Node *res)
void
complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
{
Node tnl, tnr;
Node n1, n2, n3, n4;
Node na, nb, nc;
// make both sides addable in ullman order
if(nr != N) {
if(nl->ullman > nr->ullman && !nl->addable) {
tempname(&n1, nl->type);
complexgen(nl, &n1);
nl = &n1;
tempname(&tnl, nl->type);
cgen(nl, &tnl);
nl = &tnl;
}
if(!nr->addable) {
tempname(&n2, nr->type);
complexgen(nr, &n2);
nr = &n2;
tempname(&tnr, nr->type);
cgen(nr, &tnr);
nr = &tnr;
}
}
if(!nl->addable) {
tempname(&n1, nl->type);
complexgen(nl, &n1);
nl = &n1;
tempname(&tnl, nl->type);
cgen(nl, &tnl);
nl = &tnl;
}
// build tree
......@@ -377,17 +472,6 @@ complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
bgen(&na, true, to);
}
int
cplxsubtype(int et)
{
if(et == TCOMPLEX64)
return TFLOAT32;
if(et == TCOMPLEX128)
return TFLOAT64;
fatal("cplxsubtype: %E\n", et);
return 0;
}
void
nodfconst(Node *n, Type *t, Mpflt* fval)
{
......
......@@ -128,7 +128,6 @@ void sudoclean(void);
int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*);
void datagostring(Strlit*, Addr*);
int cplxsubtype(int);
void nodfconst(Node*, Type*, Mpflt*);
/*
......
......@@ -57,6 +57,12 @@ cgen(Node *n, Node *res)
if(res == N || res->type == T)
fatal("cgen: res nil");
// TODO compile complex
if(n != N && n->type != T && iscomplex[n->type->etype])
return;
if(res != N && res->type != T && iscomplex[res->type->etype])
return;
// inline slices
if(cgen_inline(n, res))
return;
......@@ -162,6 +168,12 @@ cgen(Node *n, Node *res)
fatal("cgen %O", n->op);
break;
case OREAL:
case OIMAG:
case OCMPLX:
// TODO compile complex
return;
// these call bgen to get a bool value
case OOROR:
case OANDAND:
......@@ -729,6 +741,12 @@ bgen(Node *n, int true, Prog *to)
nl = n->left;
nr = n->right;
// TODO compile complex
if(nl != N && nl->type != T && iscomplex[nl->type->etype])
return;
if(nr != N && nr->type != T && iscomplex[nr->type->etype])
return;
if(n->type == T) {
convlit(&n, types[TBOOL]);
if(n->type == T)
......
......@@ -384,6 +384,7 @@ enum
ORUNESTR,
OSELRECV,
OIOTA,
OREAL, OIMAG, OCMPLX,
// stmts
OBLOCK,
......@@ -892,6 +893,7 @@ NodeList* listtreecopy(NodeList*);
int isselect(Node*);
Node* staticname(Type*);
int iscomposite(Type*);
int cplxsubtype(int);
Node* callnew(Type*);
Node* safeexpr(Node*, NodeList**);
int is64(Type*);
......
......@@ -1297,7 +1297,9 @@ static struct
"cap", LNAME, Txxx, OCAP,
"close", LNAME, Txxx, OCLOSE,
"closed", LNAME, Txxx, OCLOSED,
"cmplx", LNAME, Txxx, OCMPLX,
"copy", LNAME, Txxx, OCOPY,
"imag", LNAME, Txxx, OIMAG,
"len", LNAME, Txxx, OLEN,
"make", LNAME, Txxx, OMAKE,
"new", LNAME, Txxx, ONEW,
......@@ -1305,6 +1307,7 @@ static struct
"panicln", LNAME, Txxx, OPANICN,
"print", LNAME, Txxx, OPRINT,
"println", LNAME, Txxx, OPRINTN,
"real", LNAME, Txxx, OREAL,
"notwithstanding", LIGNORE, Txxx, OXXX,
"thetruthofthematter", LIGNORE, Txxx, OXXX,
......
......@@ -799,6 +799,7 @@ goopnames[] =
[OCASE] = "case",
[OCLOSED] = "closed",
[OCLOSE] = "close",
[OCMPLX] = "cmplx",
[OCOM] = "^",
[OCONTINUE] = "continue",
[OCOPY] = "copy",
......@@ -812,6 +813,7 @@ goopnames[] =
[OGOTO] = "goto",
[OGT] = ">",
[OIF] = "if",
[OIMAG] = "imag",
[OINC] = "++",
[OIND] = "*",
[OLEN] = "len",
......@@ -833,6 +835,7 @@ goopnames[] =
[OPRINTN] = "println",
[OPRINT] = "print",
[ORANGE] = "range",
[OREAL] = "real",
[ORECV] = "<-",
[ORETURN] = "return",
[ORSH] = ">>",
......@@ -1726,6 +1729,21 @@ methtype(Type *t)
return t;
}
int
cplxsubtype(int et)
{
switch(et) {
case TCOMPLEX:
return TFLOAT;
case TCOMPLEX64:
return TFLOAT32;
case TCOMPLEX128:
return TFLOAT64;
}
fatal("cplxsubtype: %E\n", et);
return 0;
}
int
iscomposite(Type *t)
{
......
......@@ -18,6 +18,7 @@
static void implicitstar(Node**);
static int onearg(Node*);
static int twoarg(Node*);
static int lookdot(Node*, Type*, int);
static void typecheckaste(int, Type*, NodeList*, char*);
static int exportassignok(Type*, char*);
......@@ -736,6 +737,8 @@ reswitch:
case OCAP:
case OLEN:
case OREAL:
case OIMAG:
ok |= Erv;
if(onearg(n) < 0)
goto error;
......@@ -743,7 +746,8 @@ reswitch:
defaultlit(&n->left, T);
implicitstar(&n->left);
l = n->left;
if((t = l->type) == T)
t = l->type;
if(t == T)
goto error;
switch(n->op) {
case OCAP:
......@@ -754,6 +758,12 @@ reswitch:
if(!okforlen[t->etype])
goto badcall1;
break;
case OREAL:
case OIMAG:
if(!iscomplex[t->etype])
goto badcall1;
n->type = types[cplxsubtype(t->etype)];
goto ret;
}
// might be constant
switch(t->etype) {
......@@ -769,6 +779,62 @@ reswitch:
n->type = types[TINT];
goto ret;
case OCMPLX:
ok |= Erv;
if(twoarg(n) < 0)
goto error;
l = typecheck(&n->left, Erv | (top & Eiota));
r = typecheck(&n->right, Erv | (top & Eiota));
if(l->type == T || r->type == T)
goto error;
defaultlit2(&l, &r, 0);
if(l->op == OLITERAL && r->op == OLITERAL) {
// make it a complex literal
switch(l->type->etype) {
default:
yyerror("real and imag parts must be the floating");
goto error;
case TIDEAL:
convlit(&l, types[TFLOAT]);
convlit(&r, types[TFLOAT]);
t = types[TIDEAL];
// fallthrough
case TFLOAT:
t = types[TCOMPLEX];
break;
case TFLOAT32:
t = types[TCOMPLEX64];
break;
case TFLOAT64:
t = types[TCOMPLEX128];
break;
}
n = nodcplxlit(l->val, r->val);
n->type = t;
goto ret;
}
n->left = l;
n->right = r;
if(l->type->etype != l->type->etype) {
yyerror("real and imag parts must be the same type");
goto error;
}
switch(l->type->etype) {
default:
yyerror("real and imag parts must be the floating");
goto error;
case TFLOAT:
n->type = types[TCOMPLEX];
break;
case TFLOAT32:
n->type = types[TCOMPLEX64];
break;
case TFLOAT64:
n->type = types[TCOMPLEX128];
break;
}
goto ret;
case OCLOSED:
case OCLOSE:
if(onearg(n) < 0)
......@@ -1206,6 +1272,31 @@ onearg(Node *n)
return 0;
}
static int
twoarg(Node *n)
{
if(n->left != N)
return 0;
if(n->list == nil) {
yyerror("missing argument to %#O - %#N", n->op, n);
return -1;
}
n->left = n->list->n;
if(n->list->next == nil) {
yyerror("missing argument to %#O - %#N", n->op, n);
n->list = nil;
return -1;
}
if(n->list->next->next != nil) {
yyerror("too many arguments to %#O", n->op);
n->list = nil;
return -1;
}
n->right = n->list->next->n;
n->list = nil;
return 0;
}
static Type*
lookdot1(Sym *s, Type *t, Type *f, int dostrcmp)
{
......
......@@ -579,6 +579,8 @@ walkexpr(Node **np, NodeList **init)
case OCOM:
case OLEN:
case OCAP:
case OREAL:
case OIMAG:
case ODOT:
case ODOTPTR:
case ODOTMETH:
......@@ -603,6 +605,7 @@ walkexpr(Node **np, NodeList **init)
case OGE:
case OGT:
case OADD:
case OCMPLX:
walkexpr(&n->left, init);
walkexpr(&n->right, init);
goto ret;
......
......@@ -98,6 +98,7 @@ var (
mapBytes = []byte("map[")
missingBytes = []byte("missing")
extraBytes = []byte("?(extra ")
irparenBytes = []byte("i)")
)
// State represents the printer state passed to custom formatters.
......@@ -447,6 +448,52 @@ func getFloat64(a interface{}) (val float64, ok bool) {
return
}
var complexBits = reflect.Typeof(complex(0i)).Size() * 8
func getComplex64(a interface{}) (val complex64, ok bool) {
// Is it a regular complex type?
switch c := a.(type) {
case complex64:
return c, true
case complex:
if complexBits == 64 {
return complex64(c), true
}
}
// Must be a renamed complex type.
switch c := reflect.NewValue(a).(type) {
case *reflect.Complex64Value:
return complex64(c.Get()), true
case *reflect.ComplexValue:
if complexBits == 64 {
return complex64(c.Get()), true
}
}
return
}
func getComplex128(a interface{}) (val complex128, ok bool) {
// Is it a regular complex type?
switch c := a.(type) {
case complex128:
return c, true
case complex:
if complexBits == 128 {
return complex128(c), true
}
}
// Must be a renamed complex type.
switch c := reflect.NewValue(a).(type) {
case *reflect.Complex128Value:
return complex128(c.Get()), true
case *reflect.ComplexValue:
if complexBits == 128 {
return complex128(c.Get()), true
}
}
return
}
// Convert ASCII to integer. n is 0 (and got is false) if no number present.
func parsenum(s string, start, end int) (n int, got bool, newi int) {
......@@ -511,6 +558,19 @@ func (p *pp) printField(field interface{}, plus, sharp bool, depth int) (was_str
p.fmt.fmt_g64(float64(f))
}
return false
// case complex64:
// p.fmt.fmt_c64(f)
// return false
// case complex128:
// p.fmt.fmt_c128(f)
// return false
// case complex:
// if complexBits == 128 {
// p.fmt.fmt_c128(complex128(f))
// } else {
// p.fmt.fmt_c64(complex64(f))
// }
// return false
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
v, signed, ok := getInt(field)
if !ok {
......@@ -863,6 +923,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_e32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_e64(v)
} else if v, ok := getComplex64(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_e32(real(v))
p.fmt.plus = true
p.fmt.fmt_e32(imag(v))
p.buf.Write(irparenBytes)
} else if v, ok := getComplex128(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_e64(real(v))
p.fmt.plus = true
p.fmt.fmt_e64(imag(v))
p.buf.Write(irparenBytes)
} else {
goto badtype
}
......@@ -871,6 +943,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_E32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_E64(v)
} else if v, ok := getComplex64(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_E32(real(v))
p.fmt.plus = true
p.fmt.fmt_E32(imag(v))
p.buf.Write(irparenBytes)
} else if v, ok := getComplex128(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_E64(real(v))
p.fmt.plus = true
p.fmt.fmt_E64(imag(v))
p.buf.Write(irparenBytes)
} else {
goto badtype
}
......@@ -879,6 +963,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_f32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_f64(v)
} else if v, ok := getComplex64(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_f32(real(v))
p.fmt.plus = true
p.fmt.fmt_f32(imag(v))
p.buf.Write(irparenBytes)
} else if v, ok := getComplex128(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_f64(real(v))
p.fmt.plus = true
p.fmt.fmt_f64(imag(v))
p.buf.Write(irparenBytes)
} else {
goto badtype
}
......@@ -887,6 +983,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_g32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_g64(v)
} else if v, ok := getComplex64(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_g32(real(v))
p.fmt.plus = true
p.fmt.fmt_g32(imag(v))
p.buf.Write(irparenBytes)
} else if v, ok := getComplex128(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_g64(real(v))
p.fmt.plus = true
p.fmt.fmt_g64(imag(v))
p.buf.Write(irparenBytes)
} else {
goto badtype
}
......@@ -895,6 +1003,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_G32(v)
} else if v, ok := getFloat64(field); ok {
p.fmt.fmt_G64(v)
} else if v, ok := getComplex64(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_G32(real(v))
p.fmt.plus = true
p.fmt.fmt_G32(imag(v))
p.buf.Write(irparenBytes)
} else if v, ok := getComplex128(field); ok {
p.buf.WriteByte('(')
p.fmt.fmt_G64(real(v))
p.fmt.plus = true
p.fmt.fmt_G64(imag(v))
p.buf.Write(irparenBytes)
} else {
goto badtype
}
......
......@@ -84,7 +84,7 @@ type Complex64Type struct {
commonType
}
// Complex128Type represents acomplex128 type.
// Complex128Type represents a complex128 type.
type Complex128Type struct {
commonType
}
......
......@@ -186,62 +186,62 @@ func (v *Float64Value) Set(x float64) {
// Set sets v to the value x.
func (v *Float64Value) SetValue(x Value) { v.Set(x.(*Float64Value).Get()) }
//// ComplexValue represents a complex value.
//type ComplexValue struct {
// value
//}
//
//// Get returns the underlying complex value.
//func (v *ComplexValue) Get() complex { return *(*complex)(v.addr) }
//
//// Set sets v to the value x.
//func (v *ComplexValue) Set(x complex) {
// if !v.canSet {
// panic(cannotSet)
// }
// *(*complex)(v.addr) = x
//}
//
//// Set sets v to the value x.
//func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) }
//
//// Complex64Value represents a complex64 value.
//type Complex64Value struct {
// value
//}
//
//// Get returns the underlying complex64 value.
//func (v *Complex64Value) Get() complex64 { return *(*complex64)(v.addr) }
//
//// Set sets v to the value x.
//func (v *Complex64Value) Set(x complex64) {
// if !v.canSet {
// panic(cannotSet)
// }
// *(*complex64)(v.addr) = x
//}
//
//// Set sets v to the value x.
//func (v *Complex64Value) SetValue(x Value) { v.Set(x.(*Complex64Value).Get()) }
//
//// Complex128Value represents a complex128 value.
//type Complex128Value struct {
// value
//}
//
//// Get returns the underlying complex128 value.
//func (v *Complex128Value) Get() complex128 { return *(*complex128)(v.addr) }
//
//// Set sets v to the value x.
//func (v *Complex128Value) Set(x complex128) {
// if !v.canSet {
// panic(cannotSet)
// }
// *(*complex128)(v.addr) = x
//}
//
//// Set sets v to the value x.
//func (v *Complex128Value) SetValue(x Value) { v.Set(x.(*Complex128Value).Get()) }
// ComplexValue represents a complex value.
type ComplexValue struct {
value
}
// Get returns the underlying complex value.
func (v *ComplexValue) Get() complex { return *(*complex)(v.addr) }
// Set sets v to the value x.
func (v *ComplexValue) Set(x complex) {
if !v.canSet {
panic(cannotSet)
}
*(*complex)(v.addr) = x
}
// Set sets v to the value x.
func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) }
// Complex64Value represents a complex64 value.
type Complex64Value struct {
value
}
// Get returns the underlying complex64 value.
func (v *Complex64Value) Get() complex64 { return *(*complex64)(v.addr) }
// Set sets v to the value x.
func (v *Complex64Value) Set(x complex64) {
if !v.canSet {
panic(cannotSet)
}
*(*complex64)(v.addr) = x
}
// Set sets v to the value x.
func (v *Complex64Value) SetValue(x Value) { v.Set(x.(*Complex64Value).Get()) }
// Complex128Value represents a complex128 value.
type Complex128Value struct {
value
}
// Get returns the underlying complex128 value.
func (v *Complex128Value) Get() complex128 { return *(*complex128)(v.addr) }
// Set sets v to the value x.
func (v *Complex128Value) Set(x complex128) {
if !v.canSet {
panic(cannotSet)
}
*(*complex128)(v.addr) = x
}
// Set sets v to the value x.
func (v *Complex128Value) SetValue(x Value) { v.Set(x.(*Complex128Value).Get()) }
// IntValue represents an int value.
type IntValue struct {
......@@ -1303,12 +1303,12 @@ func newValue(typ Type, addr addr, canSet bool) Value {
return (*Float32Value)(v)
case *Float64Type:
return (*Float64Value)(v)
// case *ComplexType:
// return (*ComplexValue)(v)
// case *Complex64Type:
// return (*Complex64Value)(v)
// case *Complex128Type:
// return (*Complex128Value)(v)
case *ComplexType:
return (*ComplexValue)(v)
case *Complex64Type:
return (*Complex64Value)(v)
case *Complex128Type:
return (*Complex128Value)(v)
case *IntType:
return (*IntValue)(v)
case *Int8Type:
......
......@@ -83,6 +83,10 @@ vprintf(int8 *s, byte *arg)
arg = vrnd(arg, sizeof(uintptr));
narg = arg + 8;
break;
case 'C':
arg = vrnd(arg, sizeof(uintptr));
narg = arg + 16;
break;
case 'p': // pointer-sized
case 's':
arg = vrnd(arg, sizeof(uintptr));
......@@ -267,7 +271,6 @@ void
{
write(fd, "(", 1);
·printfloat(v.real);
write(fd, ",", 1);
·printfloat(v.imag);
write(fd, "i)", 2);
}
......
// true # disabled until 8g has complex
// $G $D/$F.go && $L $F.$A && ./$A.out
// true
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
......
// true
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "unsafe"
import "reflect"
const (
R = 5
I = 6i
C1 = R + I // ADD(5,6)
)
var complexBits = reflect.Typeof(complex(0i)).Size() * 8
func main() {
c0 := C1
c0 = (c0+c0+c0) / (c0+c0)
println(c0)
c := *(*complex)(unsafe.Pointer(&c0))
println(c)
println(complexBits)
var a interface{}
switch c := reflect.NewValue(a).(type) {
case *reflect.Complex64Value:
v := c.Get()
_,_ = complex64(v), true
case *reflect.ComplexValue:
if complexBits == 64 {
v := c.Get()
_,_ = complex64(v), true
}
}
}
// true
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "fmt"
const (
R = 5
I = 6i
C1 = R + I // ADD(5,6)
)
func doprint(c complex) {
fmt.Printf("c = %f\n", c)
}
func main() {
// constants
fmt.Printf("c = %f\n", -C1)
doprint(C1)
// variables
c1 := C1
fmt.Printf("c = %f\n", c1)
doprint(c1)
// 128
c2 := complex128(C1)
fmt.Printf("c = %G\n", c2)
// real, imag, cmplx
c3 := cmplx(real(c2)+3, imag(c2)-5) + c2
fmt.Printf("c = %G\n", c3)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment