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:
parent
a9b9afa930
commit
426099f42e
@ -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)
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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)
|
||||||
|
@ -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*);
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
42
test/ken/cplx3.go
Normal 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
40
test/ken/cplx4.go
Normal 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)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user