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;
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:
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)
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:
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:
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) {
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);
{
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
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;
// 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:
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
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)
{
int sudoaddable(int, Node*, Addr*);
void afunclit(Addr*);
void datagostring(Strlit*, Addr*);
-int cplxsubtype(int);
void nodfconst(Node*, Type*, Mpflt*);
/*
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;
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:
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)
ORUNESTR,
OSELRECV,
OIOTA,
+ OREAL, OIMAG, OCMPLX,
// stmts
OBLOCK,
int isselect(Node*);
Node* staticname(Type*);
int iscomposite(Type*);
+int cplxsubtype(int);
Node* callnew(Type*);
Node* safeexpr(Node*, NodeList**);
int is64(Type*);
"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,
"panicln", LNAME, Txxx, OPANICN,
"print", LNAME, Txxx, OPRINT,
"println", LNAME, Txxx, OPRINTN,
+ "real", LNAME, Txxx, OREAL,
"notwithstanding", LIGNORE, Txxx, OXXX,
"thetruthofthematter", LIGNORE, Txxx, OXXX,
[OCASE] = "case",
[OCLOSED] = "closed",
[OCLOSE] = "close",
+ [OCMPLX] = "cmplx",
[OCOM] = "^",
[OCONTINUE] = "continue",
[OCOPY] = "copy",
[OGOTO] = "goto",
[OGT] = ">",
[OIF] = "if",
+ [OIMAG] = "imag",
[OINC] = "++",
[OIND] = "*",
[OLEN] = "len",
[OPRINTN] = "println",
[OPRINT] = "print",
[ORANGE] = "range",
+ [OREAL] = "real",
[ORECV] = "<-",
[ORETURN] = "return",
[ORSH] = ">>",
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)
{
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*);
case OCAP:
case OLEN:
+ case OREAL:
+ case OIMAG:
ok |= Erv;
if(onearg(n) < 0)
goto error;
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:
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) {
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)
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)
{
case OCOM:
case OLEN:
case OCAP:
+ case OREAL:
+ case OIMAG:
case ODOT:
case ODOTPTR:
case ODOTMETH:
case OGE:
case OGT:
case OADD:
+ case OCMPLX:
walkexpr(&n->left, init);
walkexpr(&n->right, init);
goto ret;
mapBytes = []byte("map[")
missingBytes = []byte("missing")
extraBytes = []byte("?(extra ")
+ irparenBytes = []byte("i)")
)
// State represents the printer state passed to custom formatters.
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) {
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 {
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
}
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
}
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
}
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
}
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
}
commonType
}
-// Complex128Type represents acomplex128 type.
+// Complex128Type represents a complex128 type.
type Complex128Type struct {
commonType
}
// 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 {
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:
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));
{
write(fd, "(", 1);
·printfloat(v.real);
- write(fd, ",", 1);
·printfloat(v.imag);
write(fd, "i)", 2);
}
-// 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
--- /dev/null
+// 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
+ }
+ }
+}
--- /dev/null
+// 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)
+}