1
0
mirror of https://github.com/golang/go synced 2024-09-23 21:20:13 -06:00

6g complex type usable

8g and 5g have stubs to ignore complex

R=rsc
CC=golang-dev
https://golang.org/cl/257042
This commit is contained in:
Ken Thompson 2010-03-05 20:16:04 -08:00
parent a9b9afa930
commit 426099f42e
17 changed files with 590 additions and 142 deletions

View File

@ -55,6 +55,12 @@ cgen(Node *n, Node *res)
if(res == N || res->type == T) if(res == N || res->type == T)
fatal("cgen: res nil"); 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) while(n->op == OCONVNOP)
n = n->left; n = n->left;
@ -186,6 +192,12 @@ cgen(Node *n, Node *res)
fatal("cgen: unknown op %N", n); fatal("cgen: unknown op %N", n);
break; break;
case OREAL:
case OIMAG:
case OCMPLX:
// TODO compile complex
return;
// these call bgen to get a bool value // these call bgen to get a bool value
case OOROR: case OOROR:
case OANDAND: case OANDAND:
@ -787,6 +799,12 @@ bgen(Node *n, int true, Prog *to)
nl = n->left; nl = n->left;
nr = n->right; 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) { if(n->type == T) {
convlit(&n, types[TBOOL]); convlit(&n, types[TBOOL]);
if(n->type == T) if(n->type == T)

View File

@ -68,6 +68,11 @@ cgen(Node *n, Node *res)
if(res->ullman >= UINF) if(res->ullman >= UINF)
goto gen; goto gen;
if(complexop(n, res)) {
complexgen(n, res);
goto ret;
}
f = 1; // gen thru register f = 1; // gen thru register
switch(n->op) { switch(n->op) {
case OLITERAL: case OLITERAL:
@ -79,6 +84,7 @@ cgen(Node *n, Node *res)
break; break;
} }
if(!iscomplex[n->type->etype]) {
a = optoas(OAS, res->type); a = optoas(OAS, res->type);
if(sudoaddable(a, res, &addr)) { if(sudoaddable(a, res, &addr)) {
if(f) { if(f) {
@ -94,6 +100,7 @@ cgen(Node *n, Node *res)
sudoclean(); sudoclean();
goto ret; goto ret;
} }
}
gen: gen:
igen(res, &n1, N); igen(res, &n1, N);
@ -139,6 +146,7 @@ cgen(Node *n, Node *res)
goto ret; goto ret;
} }
if(!iscomplex[n->type->etype]) {
a = optoas(OAS, n->type); a = optoas(OAS, n->type);
if(sudoaddable(a, n, &addr)) { if(sudoaddable(a, n, &addr)) {
if(res->op == OREGISTER) { if(res->op == OREGISTER) {
@ -154,6 +162,7 @@ cgen(Node *n, Node *res)
sudoclean(); sudoclean();
goto ret; goto ret;
} }
}
switch(n->op) { switch(n->op) {
default: default:

View File

@ -27,12 +27,12 @@ complexmove(Node *f, Node *t, int perm)
Node n1, n2, n3, n4, nc; Node n1, n2, n3, n4, nc;
if(debug['g']) { if(debug['g']) {
dump("\ncomplex-f", f); dump("\ncomplexmove-f", f);
dump("complex-t", t); dump("complexmove-t", t);
} }
if(!t->addable) if(!t->addable)
fatal("to no addable"); fatal("complexmove: to not addable");
ft = simsimtype(f->type); ft = simsimtype(f->type);
tt = simsimtype(t->type); tt = simsimtype(t->type);
@ -118,34 +118,90 @@ complexop(Node *n, Node *res)
{ {
if(n != N && n->type != T) if(n != N && n->type != T)
if(iscomplex[n->type->etype]) { if(iscomplex[n->type->etype]) {
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:
switch(n->op) { switch(n->op) {
case OCONV: case OCONV: // implemented ops
case OADD: case OADD:
case OSUB: case OSUB:
case OMUL: case OMUL:
case ODIV: case ODIV:
case OMINUS: case OMINUS:
goto yes; case OCMPLX:
} case OREAL:
//dump("complexop no", n); case OIMAG:
}
return 0;
yes:
return 1; return 1;
case ODOT: // sudoaddr
case ODOTPTR:
case OINDEX:
case OIND:
case ONAME:
return 1;
}
return 0;
} }
void void
complexgen(Node *n, Node *res) complexgen(Node *n, Node *res)
{ {
Node *nl, *nr; Node *nl, *nr;
Node tnl, tnr;
Node n1, n2, n3, n4, n5, n6; Node n1, n2, n3, n4, n5, n6;
Node ra, rb, rc, rd; Node ra, rb, rc, rd;
int tl, tr; int tl, tr;
if(debug['g']) { if(debug['g']) {
dump("\ncomplex-n", n); dump("\ncomplexgen-n", n);
dump("complex-res", res); 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 // perform conversion from n to res
@ -163,6 +219,44 @@ complexgen(Node *n, Node *res)
return; 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; nl = n->left;
if(nl == N) if(nl == N)
return; return;
@ -171,25 +265,25 @@ complexgen(Node *n, Node *res)
// make both sides addable in ullman order // make both sides addable in ullman order
if(nr != N) { if(nr != N) {
if(nl->ullman > nr->ullman && !nl->addable) { if(nl->ullman > nr->ullman && !nl->addable) {
tempname(&n1, nl->type); tempname(&tnl, nl->type);
complexgen(nl, &n1); cgen(nl, &tnl);
nl = &n1; nl = &tnl;
} }
if(!nr->addable) { if(!nr->addable) {
tempname(&n2, nr->type); tempname(&tnr, nr->type);
complexgen(nr, &n2); cgen(nr, &tnr);
nr = &n2; nr = &tnr;
} }
} }
if(!nl->addable) { if(!nl->addable) {
tempname(&n1, nl->type); tempname(&tnl, nl->type);
complexgen(nl, &n1); cgen(nl, &tnl);
nl = &n1; nl = &tnl;
} }
switch(n->op) { switch(n->op) {
default: default:
fatal("opcode %O", n->op); fatal("complexgen: unknown op %O", n->op);
break; break;
case OCONV: case OCONV:
@ -325,26 +419,27 @@ complexgen(Node *n, Node *res)
void void
complexbool(int op, Node *nl, Node *nr, int true, Prog *to) complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
{ {
Node tnl, tnr;
Node n1, n2, n3, n4; Node n1, n2, n3, n4;
Node na, nb, nc; Node na, nb, nc;
// make both sides addable in ullman order // make both sides addable in ullman order
if(nr != N) { if(nr != N) {
if(nl->ullman > nr->ullman && !nl->addable) { if(nl->ullman > nr->ullman && !nl->addable) {
tempname(&n1, nl->type); tempname(&tnl, nl->type);
complexgen(nl, &n1); cgen(nl, &tnl);
nl = &n1; nl = &tnl;
} }
if(!nr->addable) { if(!nr->addable) {
tempname(&n2, nr->type); tempname(&tnr, nr->type);
complexgen(nr, &n2); cgen(nr, &tnr);
nr = &n2; nr = &tnr;
} }
} }
if(!nl->addable) { if(!nl->addable) {
tempname(&n1, nl->type); tempname(&tnl, nl->type);
complexgen(nl, &n1); cgen(nl, &tnl);
nl = &n1; nl = &tnl;
} }
// build tree // build tree
@ -377,17 +472,6 @@ complexbool(int op, Node *nl, Node *nr, int true, Prog *to)
bgen(&na, true, 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 void
nodfconst(Node *n, Type *t, Mpflt* fval) nodfconst(Node *n, Type *t, Mpflt* fval)
{ {

View File

@ -128,7 +128,6 @@ void sudoclean(void);
int sudoaddable(int, Node*, Addr*); int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*); void afunclit(Addr*);
void datagostring(Strlit*, Addr*); void datagostring(Strlit*, Addr*);
int cplxsubtype(int);
void nodfconst(Node*, Type*, Mpflt*); void nodfconst(Node*, Type*, Mpflt*);
/* /*

View File

@ -57,6 +57,12 @@ cgen(Node *n, Node *res)
if(res == N || res->type == T) if(res == N || res->type == T)
fatal("cgen: res nil"); 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 // inline slices
if(cgen_inline(n, res)) if(cgen_inline(n, res))
return; return;
@ -162,6 +168,12 @@ cgen(Node *n, Node *res)
fatal("cgen %O", n->op); fatal("cgen %O", n->op);
break; break;
case OREAL:
case OIMAG:
case OCMPLX:
// TODO compile complex
return;
// these call bgen to get a bool value // these call bgen to get a bool value
case OOROR: case OOROR:
case OANDAND: case OANDAND:
@ -729,6 +741,12 @@ bgen(Node *n, int true, Prog *to)
nl = n->left; nl = n->left;
nr = n->right; 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) { if(n->type == T) {
convlit(&n, types[TBOOL]); convlit(&n, types[TBOOL]);
if(n->type == T) if(n->type == T)

View File

@ -384,6 +384,7 @@ enum
ORUNESTR, ORUNESTR,
OSELRECV, OSELRECV,
OIOTA, OIOTA,
OREAL, OIMAG, OCMPLX,
// stmts // stmts
OBLOCK, OBLOCK,
@ -892,6 +893,7 @@ NodeList* listtreecopy(NodeList*);
int isselect(Node*); int isselect(Node*);
Node* staticname(Type*); Node* staticname(Type*);
int iscomposite(Type*); int iscomposite(Type*);
int cplxsubtype(int);
Node* callnew(Type*); Node* callnew(Type*);
Node* safeexpr(Node*, NodeList**); Node* safeexpr(Node*, NodeList**);
int is64(Type*); int is64(Type*);

View File

@ -1297,7 +1297,9 @@ static struct
"cap", LNAME, Txxx, OCAP, "cap", LNAME, Txxx, OCAP,
"close", LNAME, Txxx, OCLOSE, "close", LNAME, Txxx, OCLOSE,
"closed", LNAME, Txxx, OCLOSED, "closed", LNAME, Txxx, OCLOSED,
"cmplx", LNAME, Txxx, OCMPLX,
"copy", LNAME, Txxx, OCOPY, "copy", LNAME, Txxx, OCOPY,
"imag", LNAME, Txxx, OIMAG,
"len", LNAME, Txxx, OLEN, "len", LNAME, Txxx, OLEN,
"make", LNAME, Txxx, OMAKE, "make", LNAME, Txxx, OMAKE,
"new", LNAME, Txxx, ONEW, "new", LNAME, Txxx, ONEW,
@ -1305,6 +1307,7 @@ static struct
"panicln", LNAME, Txxx, OPANICN, "panicln", LNAME, Txxx, OPANICN,
"print", LNAME, Txxx, OPRINT, "print", LNAME, Txxx, OPRINT,
"println", LNAME, Txxx, OPRINTN, "println", LNAME, Txxx, OPRINTN,
"real", LNAME, Txxx, OREAL,
"notwithstanding", LIGNORE, Txxx, OXXX, "notwithstanding", LIGNORE, Txxx, OXXX,
"thetruthofthematter", LIGNORE, Txxx, OXXX, "thetruthofthematter", LIGNORE, Txxx, OXXX,

View File

@ -799,6 +799,7 @@ goopnames[] =
[OCASE] = "case", [OCASE] = "case",
[OCLOSED] = "closed", [OCLOSED] = "closed",
[OCLOSE] = "close", [OCLOSE] = "close",
[OCMPLX] = "cmplx",
[OCOM] = "^", [OCOM] = "^",
[OCONTINUE] = "continue", [OCONTINUE] = "continue",
[OCOPY] = "copy", [OCOPY] = "copy",
@ -812,6 +813,7 @@ goopnames[] =
[OGOTO] = "goto", [OGOTO] = "goto",
[OGT] = ">", [OGT] = ">",
[OIF] = "if", [OIF] = "if",
[OIMAG] = "imag",
[OINC] = "++", [OINC] = "++",
[OIND] = "*", [OIND] = "*",
[OLEN] = "len", [OLEN] = "len",
@ -833,6 +835,7 @@ goopnames[] =
[OPRINTN] = "println", [OPRINTN] = "println",
[OPRINT] = "print", [OPRINT] = "print",
[ORANGE] = "range", [ORANGE] = "range",
[OREAL] = "real",
[ORECV] = "<-", [ORECV] = "<-",
[ORETURN] = "return", [ORETURN] = "return",
[ORSH] = ">>", [ORSH] = ">>",
@ -1726,6 +1729,21 @@ methtype(Type *t)
return 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 int
iscomposite(Type *t) iscomposite(Type *t)
{ {

View File

@ -18,6 +18,7 @@
static void implicitstar(Node**); static void implicitstar(Node**);
static int onearg(Node*); static int onearg(Node*);
static int twoarg(Node*);
static int lookdot(Node*, Type*, int); static int lookdot(Node*, Type*, int);
static void typecheckaste(int, Type*, NodeList*, char*); static void typecheckaste(int, Type*, NodeList*, char*);
static int exportassignok(Type*, char*); static int exportassignok(Type*, char*);
@ -736,6 +737,8 @@ reswitch:
case OCAP: case OCAP:
case OLEN: case OLEN:
case OREAL:
case OIMAG:
ok |= Erv; ok |= Erv;
if(onearg(n) < 0) if(onearg(n) < 0)
goto error; goto error;
@ -743,7 +746,8 @@ reswitch:
defaultlit(&n->left, T); defaultlit(&n->left, T);
implicitstar(&n->left); implicitstar(&n->left);
l = n->left; l = n->left;
if((t = l->type) == T) t = l->type;
if(t == T)
goto error; goto error;
switch(n->op) { switch(n->op) {
case OCAP: case OCAP:
@ -754,6 +758,12 @@ reswitch:
if(!okforlen[t->etype]) if(!okforlen[t->etype])
goto badcall1; goto badcall1;
break; break;
case OREAL:
case OIMAG:
if(!iscomplex[t->etype])
goto badcall1;
n->type = types[cplxsubtype(t->etype)];
goto ret;
} }
// might be constant // might be constant
switch(t->etype) { switch(t->etype) {
@ -769,6 +779,62 @@ reswitch:
n->type = types[TINT]; n->type = types[TINT];
goto ret; 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 OCLOSED:
case OCLOSE: case OCLOSE:
if(onearg(n) < 0) if(onearg(n) < 0)
@ -1206,6 +1272,31 @@ onearg(Node *n)
return 0; 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* static Type*
lookdot1(Sym *s, Type *t, Type *f, int dostrcmp) lookdot1(Sym *s, Type *t, Type *f, int dostrcmp)
{ {

View File

@ -579,6 +579,8 @@ walkexpr(Node **np, NodeList **init)
case OCOM: case OCOM:
case OLEN: case OLEN:
case OCAP: case OCAP:
case OREAL:
case OIMAG:
case ODOT: case ODOT:
case ODOTPTR: case ODOTPTR:
case ODOTMETH: case ODOTMETH:
@ -603,6 +605,7 @@ walkexpr(Node **np, NodeList **init)
case OGE: case OGE:
case OGT: case OGT:
case OADD: case OADD:
case OCMPLX:
walkexpr(&n->left, init); walkexpr(&n->left, init);
walkexpr(&n->right, init); walkexpr(&n->right, init);
goto ret; goto ret;

View File

@ -98,6 +98,7 @@ var (
mapBytes = []byte("map[") mapBytes = []byte("map[")
missingBytes = []byte("missing") missingBytes = []byte("missing")
extraBytes = []byte("?(extra ") extraBytes = []byte("?(extra ")
irparenBytes = []byte("i)")
) )
// State represents the printer state passed to custom formatters. // State represents the printer state passed to custom formatters.
@ -447,6 +448,52 @@ func getFloat64(a interface{}) (val float64, ok bool) {
return 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. // 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) { 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)) p.fmt.fmt_g64(float64(f))
} }
return false 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: case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
v, signed, ok := getInt(field) v, signed, ok := getInt(field)
if !ok { if !ok {
@ -863,6 +923,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_e32(v) p.fmt.fmt_e32(v)
} else if v, ok := getFloat64(field); ok { } else if v, ok := getFloat64(field); ok {
p.fmt.fmt_e64(v) 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 { } else {
goto badtype goto badtype
} }
@ -871,6 +943,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_E32(v) p.fmt.fmt_E32(v)
} else if v, ok := getFloat64(field); ok { } else if v, ok := getFloat64(field); ok {
p.fmt.fmt_E64(v) 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 { } else {
goto badtype goto badtype
} }
@ -879,6 +963,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_f32(v) p.fmt.fmt_f32(v)
} else if v, ok := getFloat64(field); ok { } else if v, ok := getFloat64(field); ok {
p.fmt.fmt_f64(v) 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 { } else {
goto badtype goto badtype
} }
@ -887,6 +983,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_g32(v) p.fmt.fmt_g32(v)
} else if v, ok := getFloat64(field); ok { } else if v, ok := getFloat64(field); ok {
p.fmt.fmt_g64(v) 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 { } else {
goto badtype goto badtype
} }
@ -895,6 +1003,18 @@ func (p *pp) doprintf(format string, a []interface{}) {
p.fmt.fmt_G32(v) p.fmt.fmt_G32(v)
} else if v, ok := getFloat64(field); ok { } else if v, ok := getFloat64(field); ok {
p.fmt.fmt_G64(v) 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 { } else {
goto badtype goto badtype
} }

View File

@ -84,7 +84,7 @@ type Complex64Type struct {
commonType commonType
} }
// Complex128Type represents acomplex128 type. // Complex128Type represents a complex128 type.
type Complex128Type struct { type Complex128Type struct {
commonType commonType
} }

View File

@ -186,62 +186,62 @@ func (v *Float64Value) Set(x float64) {
// Set sets v to the value x. // Set sets v to the value x.
func (v *Float64Value) SetValue(x Value) { v.Set(x.(*Float64Value).Get()) } func (v *Float64Value) SetValue(x Value) { v.Set(x.(*Float64Value).Get()) }
//// ComplexValue represents a complex value. // ComplexValue represents a complex value.
//type ComplexValue struct { type ComplexValue struct {
// value value
//} }
//
//// Get returns the underlying complex value. // Get returns the underlying complex value.
//func (v *ComplexValue) Get() complex { return *(*complex)(v.addr) } func (v *ComplexValue) Get() complex { return *(*complex)(v.addr) }
//
//// Set sets v to the value x. // Set sets v to the value x.
//func (v *ComplexValue) Set(x complex) { func (v *ComplexValue) Set(x complex) {
// if !v.canSet { if !v.canSet {
// panic(cannotSet) panic(cannotSet)
// } }
// *(*complex)(v.addr) = x *(*complex)(v.addr) = x
//} }
//
//// Set sets v to the value x. // Set sets v to the value x.
//func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) } func (v *ComplexValue) SetValue(x Value) { v.Set(x.(*ComplexValue).Get()) }
//
//// Complex64Value represents a complex64 value. // Complex64Value represents a complex64 value.
//type Complex64Value struct { type Complex64Value struct {
// value value
//} }
//
//// Get returns the underlying complex64 value. // Get returns the underlying complex64 value.
//func (v *Complex64Value) Get() complex64 { return *(*complex64)(v.addr) } func (v *Complex64Value) Get() complex64 { return *(*complex64)(v.addr) }
//
//// Set sets v to the value x. // Set sets v to the value x.
//func (v *Complex64Value) Set(x complex64) { func (v *Complex64Value) Set(x complex64) {
// if !v.canSet { if !v.canSet {
// panic(cannotSet) panic(cannotSet)
// } }
// *(*complex64)(v.addr) = x *(*complex64)(v.addr) = x
//} }
//
//// Set sets v to the value x. // Set sets v to the value x.
//func (v *Complex64Value) SetValue(x Value) { v.Set(x.(*Complex64Value).Get()) } func (v *Complex64Value) SetValue(x Value) { v.Set(x.(*Complex64Value).Get()) }
//
//// Complex128Value represents a complex128 value. // Complex128Value represents a complex128 value.
//type Complex128Value struct { type Complex128Value struct {
// value value
//} }
//
//// Get returns the underlying complex128 value. // Get returns the underlying complex128 value.
//func (v *Complex128Value) Get() complex128 { return *(*complex128)(v.addr) } func (v *Complex128Value) Get() complex128 { return *(*complex128)(v.addr) }
//
//// Set sets v to the value x. // Set sets v to the value x.
//func (v *Complex128Value) Set(x complex128) { func (v *Complex128Value) Set(x complex128) {
// if !v.canSet { if !v.canSet {
// panic(cannotSet) panic(cannotSet)
// } }
// *(*complex128)(v.addr) = x *(*complex128)(v.addr) = x
//} }
//
//// Set sets v to the value x. // Set sets v to the value x.
//func (v *Complex128Value) SetValue(x Value) { v.Set(x.(*Complex128Value).Get()) } func (v *Complex128Value) SetValue(x Value) { v.Set(x.(*Complex128Value).Get()) }
// IntValue represents an int value. // IntValue represents an int value.
type IntValue struct { type IntValue struct {
@ -1303,12 +1303,12 @@ func newValue(typ Type, addr addr, canSet bool) Value {
return (*Float32Value)(v) return (*Float32Value)(v)
case *Float64Type: case *Float64Type:
return (*Float64Value)(v) return (*Float64Value)(v)
// case *ComplexType: case *ComplexType:
// return (*ComplexValue)(v) return (*ComplexValue)(v)
// case *Complex64Type: case *Complex64Type:
// return (*Complex64Value)(v) return (*Complex64Value)(v)
// case *Complex128Type: case *Complex128Type:
// return (*Complex128Value)(v) return (*Complex128Value)(v)
case *IntType: case *IntType:
return (*IntValue)(v) return (*IntValue)(v)
case *Int8Type: case *Int8Type:

View File

@ -83,6 +83,10 @@ vprintf(int8 *s, byte *arg)
arg = vrnd(arg, sizeof(uintptr)); arg = vrnd(arg, sizeof(uintptr));
narg = arg + 8; narg = arg + 8;
break; break;
case 'C':
arg = vrnd(arg, sizeof(uintptr));
narg = arg + 16;
break;
case 'p': // pointer-sized case 'p': // pointer-sized
case 's': case 's':
arg = vrnd(arg, sizeof(uintptr)); arg = vrnd(arg, sizeof(uintptr));
@ -267,7 +271,6 @@ void
{ {
write(fd, "(", 1); write(fd, "(", 1);
·printfloat(v.real); ·printfloat(v.real);
write(fd, ",", 1);
·printfloat(v.imag); ·printfloat(v.imag);
write(fd, "i)", 2); write(fd, "i)", 2);
} }

View File

@ -1,6 +1,4 @@
// true # disabled until 8g has complex // true
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style

42
test/ken/cplx3.go Normal file
View File

@ -0,0 +1,42 @@
// 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
}
}
}

40
test/ken/cplx4.go Normal file
View File

@ -0,0 +1,40 @@
// 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)
}