mirror of
https://github.com/golang/go
synced 2024-11-21 19:14:44 -07: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)
|
||||
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);
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
// 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
|
||||
|
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