]> Cypherpunks repositories - gostls13.git/commitdiff
6g complex type usable
authorKen Thompson <ken@golang.org>
Sat, 6 Mar 2010 04:16:04 +0000 (20:16 -0800)
committerKen Thompson <ken@golang.org>
Sat, 6 Mar 2010 04:16:04 +0000 (20:16 -0800)
8g and 5g have stubs to ignore complex

R=rsc
CC=golang-dev
https://golang.org/cl/257042

17 files changed:
src/cmd/5g/cgen.c
src/cmd/6g/cgen.c
src/cmd/6g/cplx.c
src/cmd/6g/gg.h
src/cmd/8g/cgen.c
src/cmd/gc/go.h
src/cmd/gc/lex.c
src/cmd/gc/subr.c
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c
src/pkg/fmt/print.go
src/pkg/reflect/type.go
src/pkg/reflect/value.go
src/pkg/runtime/print.c
test/ken/cplx0.go
test/ken/cplx3.go [new file with mode: 0644]
test/ken/cplx4.go [new file with mode: 0644]

index 48d5e3c221cd8cd7cdc8db2aeb1cd6111f9eb176..ce931600ec0719315c1a955e6f14379ede30cbec 100644 (file)
@@ -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)
index 6038352e969c8211f0d55302aab4bb934cfa563e..05e36d2a75a05d4a02d4d3fb3f10b6993b971f94 100644 (file)
@@ -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) {
index e7361af561ade1a2094b4668cabf8301c165952d..967b6bfb906365db992c28ccd6f6b6c445aca1cb 100644 (file)
@@ -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)
 {
index 3fb2cbf626aa00fc7c3c856ce96b605e96a08060..bfa7974352d83d14e37ebfc407f18fde19f8e214 100644 (file)
@@ -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*);
 
 /*
index 5adf29a438a484235f24c09001750f968aa619ee..3f2a64caa25ed5db3ff98c2189234577e0e1c518 100644 (file)
@@ -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)
index cbcdc9c39d27da5b657bffd45e6f40b491500830..a301a756c8311d3b8a66aeab2c53f868684dd0cf 100644 (file)
@@ -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*);
index 8afc737f38ddbc3ea1d449d7704ee7c6e5416af3..ccde1c4dac9bc1b1d30f5fdd3c57946ed7f0a80b 100644 (file)
@@ -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,
index d3354c904b5224ca919e2c5235dddaadc3c4ec50..2cfca1985c6526299608fb5830284a5ca993a414 100644 (file)
@@ -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)
 {
index 4c4c9283380e162e837d9836b70f6e66f82d0a97..e7db038bf6afb2074ee53437a824dccf42dc857d 100644 (file)
@@ -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)
 {
index 1f7312e5e05e528639d0aac33c8c1ee92f1cb671..fded073a378a7e044c1ed27d1179b57923b22f67 100644 (file)
@@ -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;
index 37405424bb1ac61adbfde5ec6bed7cc87e822149..6918f63cde07aedc5865c824c0ace0170cbac18e 100644 (file)
@@ -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
                        }
index 9451885afbbd75250e1565c328150b40fb7f42a9..2abb9331a2da7880f6f4b4a2eef9afb7cfb36ba1 100644 (file)
@@ -84,7 +84,7 @@ type Complex64Type struct {
        commonType
 }
 
-// Complex128Type represents acomplex128 type.
+// Complex128Type represents a complex128 type.
 type Complex128Type struct {
        commonType
 }
index 2543499f5c6f52ae226c14a72652b617c62d16b5..32accddf50f1467c74b84da93ac0b7392f5a0843 100644 (file)
@@ -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:
index 92f49fba96a40740971faf093dbf31216662ed72..26b3de785cdd3146ddbe0ae83ad463e1c261494e 100644 (file)
@@ -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);
 }
index b9de2292bb1eebd1fe11d723463cbabad8e88d09..b9e783029716908c86467a618a9a66d29b5da8a1 100644 (file)
@@ -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
diff --git a/test/ken/cplx3.go b/test/ken/cplx3.go
new file mode 100644 (file)
index 0000000..f08e9de
--- /dev/null
@@ -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
+               }
+       }
+}
diff --git a/test/ken/cplx4.go b/test/ken/cplx4.go
new file mode 100644 (file)
index 0000000..d29a1c8
--- /dev/null
@@ -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)
+}