summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2010-03-05 20:16:04 -0800
committerKen Thompson <ken@golang.org>2010-03-05 20:16:04 -0800
commit5842cfc85c6f8fc4d21a8eed092e072c31e8d57f (patch)
tree762fd17775da62a5871b43cb2d8e2fc5061e01fa /src
parent6cb89cd7be227e578300ee8097f9dfbf362bee53 (diff)
downloadgolang-5842cfc85c6f8fc4d21a8eed092e072c31e8d57f.tar.gz
6g complex type usable
8g and 5g have stubs to ignore complex R=rsc CC=golang-dev http://codereview.appspot.com/257042
Diffstat (limited to 'src')
-rw-r--r--src/cmd/5g/cgen.c18
-rw-r--r--src/cmd/6g/cgen.c63
-rw-r--r--src/cmd/6g/cplx.c176
-rw-r--r--src/cmd/6g/gg.h1
-rw-r--r--src/cmd/8g/cgen.c18
-rw-r--r--src/cmd/gc/go.h2
-rw-r--r--src/cmd/gc/lex.c3
-rw-r--r--src/cmd/gc/subr.c18
-rw-r--r--src/cmd/gc/typecheck.c93
-rw-r--r--src/cmd/gc/walk.c3
-rw-r--r--src/pkg/fmt/print.go120
-rw-r--r--src/pkg/reflect/type.go2
-rw-r--r--src/pkg/reflect/value.go124
-rw-r--r--src/pkg/runtime/print.c5
14 files changed, 507 insertions, 139 deletions
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c
index 48d5e3c22..ce931600e 100644
--- a/src/cmd/5g/cgen.c
+++ b/src/cmd/5g/cgen.c
@@ -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)
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index 6038352e9..05e36d2a7 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -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) {
diff --git a/src/cmd/6g/cplx.c b/src/cmd/6g/cplx.c
index e7361af56..967b6bfb9 100644
--- a/src/cmd/6g/cplx.c
+++ b/src/cmd/6g/cplx.c
@@ -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)
{
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index 3fb2cbf62..bfa797435 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -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*);
/*
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index 5adf29a43..3f2a64caa 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -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)
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index cbcdc9c39..a301a756c 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -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*);
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 8afc737f3..ccde1c4da 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -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,
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index d3354c904..2cfca1985 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -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] = ">>",
@@ -1727,6 +1730,21 @@ methtype(Type *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)
{
if(t == T)
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index 4c4c92833..e7db038bf 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -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)
{
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 1f7312e5e..fded073a3 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -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;
diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go
index 37405424b..6918f63cd 100644
--- a/src/pkg/fmt/print.go
+++ b/src/pkg/fmt/print.go
@@ -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
}
diff --git a/src/pkg/reflect/type.go b/src/pkg/reflect/type.go
index 9451885af..2abb9331a 100644
--- a/src/pkg/reflect/type.go
+++ b/src/pkg/reflect/type.go
@@ -84,7 +84,7 @@ type Complex64Type struct {
commonType
}
-// Complex128Type represents acomplex128 type.
+// Complex128Type represents a complex128 type.
type Complex128Type struct {
commonType
}
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index 2543499f5..32accddf5 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -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:
diff --git a/src/pkg/runtime/print.c b/src/pkg/runtime/print.c
index 92f49fba9..26b3de785 100644
--- a/src/pkg/runtime/print.c
+++ b/src/pkg/runtime/print.c
@@ -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);
}