diff options
author | Ken Thompson <ken@golang.org> | 2010-03-05 20:16:04 -0800 |
---|---|---|
committer | Ken Thompson <ken@golang.org> | 2010-03-05 20:16:04 -0800 |
commit | 5842cfc85c6f8fc4d21a8eed092e072c31e8d57f (patch) | |
tree | 762fd17775da62a5871b43cb2d8e2fc5061e01fa /src | |
parent | 6cb89cd7be227e578300ee8097f9dfbf362bee53 (diff) | |
download | golang-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.c | 18 | ||||
-rw-r--r-- | src/cmd/6g/cgen.c | 63 | ||||
-rw-r--r-- | src/cmd/6g/cplx.c | 176 | ||||
-rw-r--r-- | src/cmd/6g/gg.h | 1 | ||||
-rw-r--r-- | src/cmd/8g/cgen.c | 18 | ||||
-rw-r--r-- | src/cmd/gc/go.h | 2 | ||||
-rw-r--r-- | src/cmd/gc/lex.c | 3 | ||||
-rw-r--r-- | src/cmd/gc/subr.c | 18 | ||||
-rw-r--r-- | src/cmd/gc/typecheck.c | 93 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 3 | ||||
-rw-r--r-- | src/pkg/fmt/print.go | 120 | ||||
-rw-r--r-- | src/pkg/reflect/type.go | 2 | ||||
-rw-r--r-- | src/pkg/reflect/value.go | 124 | ||||
-rw-r--r-- | src/pkg/runtime/print.c | 5 |
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); } |